【问题标题】:onchangeDate not triggering on cloned datepicker objectsonchangeDate 不会在克隆的 datepicker 对象上触发
【发布时间】:2017-02-24 12:42:08
【问题描述】:

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

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

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

克隆的日期选择器元素未触发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");
 },

这里是克隆的日期选择器屏幕截图,不会触发此功能:

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

这是我在处理时克隆日期选择器的代码:

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));
});
} 

} }

【问题讨论】:

  • 如果您附上一些工作示例 Html+javascript,您将获得更快的响应
  • 问题是我在 as400 上的服务器端!如果不重写整个服务器端程序,就无法真正重现该问题。我将附上屏幕截图以显示发生了什么。好吧,我想我可以创建一个克隆表格行的按钮。 :-)
  • 请检查我的答案

标签: jquery jquery-ui datepicker event-listener


【解决方案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

【讨论】:

  • 哦。我没有意识到我可以在绑定上使用回调函数!谢谢!一旦我能够测试这个,我会检查答案!很酷!
  • 看我上面的jsfiddle问题依然存在
  • 感谢您整理小提琴!你快到了!检查我答案的最后一部分。干杯
  • 谢谢你是个好人!那么当涉及到动态事件绑定时,你真的必须单独绑定它们吗?
  • 您也可以像 $('.common-class').bind(...) 那样批量绑定它们,这就是您在开始时所做的 $(".dp").on("focusout"....... 在 newDp 的情况下您只有为您刚刚创建的单个元素执行此操作,所有其他 dp 元素都已绑定。很高兴你让它工作:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-07
  • 2011-07-30
相关资源
最近更新 更多