onchangeDate不会在克隆的datepicker对象上触发

时间:2017-02-24 12:42:08

标签: jquery jquery-ui datepicker event-listener

我目前正在处理项目的项目(请参阅我之前的问题:validate-dynamic-table-rows-on-event-listeners/42408354#42408354),在成功处理后克隆我的表行。我必须清除所有输入,更改嵌套的html对象'除了onchangeDate事件监听器之外,类和ID以及一切正常。

我正在使用 jQuery.dataTables 来填充我的表格,complete:函数是我将我的日期选择器绑定到我的tr tds中的原始输入html元素的地方。而不是由datepickers分配的dp126353729 ID,我使用我的ID的行号,这根本不是问题。

我的问题是,当我关闭我的日期选择器时,我使用onchangeDate事件来触发onfocusout事件,因此我的表行将使用新日期进行处理。我必须使用setTimeout来玩游戏才能让事件监听器首先获取新日期!

克隆的datepicker元素未触发onchangeDate。我试图将它们绑定到这个事件没有任何运气。使用默认ID也没有帮助。

这是一个JSFIDDLE来显示克隆的日期选择器如何触发onfocusout

这是我的代码:

    var DatePicker = function(that){
    if (jQuery().datepicker) {
    alert(that.attr('id'));

      that.datepicker({
      showOn: "button",
      buttonImage: "/images/calendar.png",
      buttonImageOnly: true,
      buttonText: 'Select a start buying date',
      changeMonth: true,
      changeYear: true, 
      beforeShow: function() {
          setTimeout(function(){
              $('.ui-datepicker').css('z-index', 100100);
          }, 0);
      },
      onSelect: function () {
        $('.item-failure').addClass("hidden").hide();
         $(this).removeClass("error").tooltip("disable").tooltip("hide");
         $('.ui-datepicker').css('z-index', -1);
         setTimeout(function(){  
          //allows date to catchup  
         },0);
     },
     onClose: function(){
        $(this).trigger("changeDate");
     },
      minDate: '+1', // The min date that can be selected, i.e. 30 days from the 'now'
      maxDate: '+1y'  // The max date that can be selected, i.e. + 1 month, 1 week, and 1 days from 'now'
      //                       HR   MIN  SEC  MILLI 
      //new Date().getTime() + 24 * 60 * 60 * 1000)
    }).datepicker();
        if($(this).hasClass("newDp")){
            $(this).bind("changeDate");
        }
  }
}

在这里你可以看到我触发了focusout事件,它反过来会对所有行进行验证和处理:

$(".dp").on("changeDate",function(e){
e.stopImmediatePropagation();
  $(this).trigger("focusout");
  alert("onchange date" + $(this).val());
});

从那里处理行的事件:

  //Iterates thru the entire row when date changed 
 $(".dp").on("keyup focusout",function (e) {
        e.stopImmediatePropagation();
        //reset validators
        $(".qty").rules('remove','min');
        $(".qty").rules('remove','max');    
        $(".qty").rules('remove','required');
        hasQtys = false;
        hadOtherQtys = false;
        var row = $(this).closest('tr');
        $(this).rules('add',{required:true,messages:{required:"Must supply a start buy date."}});
        $(this).rules('add',{UsaDate:true,messages:{UsaDate:"Enter date in mm/dd/yyyy format"}});
        var buydate = $(this);
        var num = 0;
        var dow = '';
        var delday = '';
        var quans = 0;
            flag = true;
        var qty = $();
        var Error = false;
        //console.log("dp triggered" + e.type);
        //only check date when manually entered. 
        if(e.type === "keyup" && ($(this).valid() === false || $(this).val() ===""))
        {   console.log(e.type + $(this).valid());
            $(this).addClass("error").tooltip("enable").show(); 
            $('item-failure').removeClass("hidden").html("You have some errors. See below.").show();
            Error = true;
        } 
        //check for qtys in row before processing    
        row.children("td").each(function(index){
            qty = $(this).find(".qty");
               //processes the inputs within the row
ProcessRequest(row, qty,dow);
            }//eof qty.val undefined
          });//eof td children
         }//eof error
     });//eof event datepicker listener

以下是在complete:函数上创建的日期选择器的屏幕截图,其中包含可成功触发此函数的dataTables

onClose: function(){
    $(this).trigger("changeDate");
 },

enter image description here

以下是克隆的datepicker屏幕截图,它不会触发此函数:

onClose: function(){
    $(this).trigger("changeDate");
 },

enter image description here

以下是我在处理时克隆datepicker的代码:

var ProcessRequest = function(tr, count,delday){
    var dp = tr.find("[name='BUYDATE']");
        //clear all errors
        tr.children("td").each(function(){       $(this).find(".qty").removeClass("error").tooltip("disable").tooltip("hide");  
        });
        //insert new row because we create new row off emptyRow
        if(tr.find(".itno").hasClass("EmptyRow") && flag == true){
             console.log("this was an .EmptyRow");
            var $clone = tr.clone();
            $clone.insertBefore(tr);
            //clear inputs 
            $clone.children("td").each(function(){
                var $input = $(this).find("input");
                $input.val("");  
            });  
            //destroy datepicker    
            var dp = $clone.find(".dp");
                dp.remove();
            //create new DatePicker(dp);
            var dpId = $('#table_001 tr').length + 1;
            $clone.find("td:eq(13) span").html("<input name='BUYDATE' class='dp newDp form-control-inline' style='width:95px'; />");   
            dp = $clone.find(".dp");
            dp.attr('id',dpId);
            DatePicker(dp);  
}

解决方案:感谢armesian我提出了这个解决方案:

var DatePicker = function(that){
if (jQuery().datepicker) {
//alert(that.attr('id'));
  that.datepicker({
  showOn: "button",
  buttonImage: "/images/calendar.png",
  buttonImageOnly: true,
  buttonText: 'Select a start buying date',
  changeMonth: true,
  changeYear: true, 
  beforeShow: function() {
      setTimeout(function(){
          $('.ui-datepicker').css('z-index', 100100);
      }, 0);
  },
  onSelect: function () {
    $('.item-failure').addClass("hidden").hide();
     $(this).removeClass("error").tooltip("disable").tooltip("hide");
     $('.ui-datepicker').css('z-index', -1);
     setTimeout(function(){  
      //allows date to catchup  
     },0);
 },
 onClose: function(){
    $(this).trigger("changeDate");
 },
  minDate: '+1', // The min date that can be selected, i.e. 30 days from the 'now'
  maxDate: '+1y'  // The max date that can be selected, i.e. + 1 month, 1 week, and 1 days from 'now'
  //                       HR   MIN  SEC  MILLI 
  //new Date().getTime() + 24 * 60 * 60 * 1000)
}).datepicker();

if($(this).hasClass("newDp")){
    $(this).bind("changeDate", function(e) { // this is the missing part in my opinion
        e.stopImmediatePropagation();
        $(this).trigger("focusout");
        alert("onchange date" + $(this).val());
    }); 
//Dynamic binding on cloned datepickers only
$(this).on("focusout",function(){
 RowValidation($(this));
});
} 

} }

1 个答案:

答案 0 :(得分:1)

对于我能看到的内容,我要指出一条我觉得修复需要去的路线。

我假设在这一行中你的意图是将changeDate事件绑定到新创建的元素,但绑定缺少在触发事件时将执行的实际函数:

// corrected version would be
if($(this).hasClass("newDp")){
  $(this).bind("changeDate", function(e) { // this is the missing part in my opinion
      e.stopImmediatePropagation();
      $(this).trigger("focusout");
      alert("onchange date" + $(this).val());
  });
}

@yardpenalty你差不多了!您忘记将onfocusout事件绑定到克隆的dp。您可以在应该修复它的dp.addClass("newDp");之后添加以下行:

dp.on("focusout",function(){
  $("<div class='red'></div>").insertBefore("#table_001");
});

这是有效的JSFIDDLE