onchangeDate不会在克隆的datepicker对象上触发
The project I am currently working on a project (see my previous question: validate-dynamic-table-rows-on-event-listeners/42408354#42408354) where my table rows are cloned upon successful processing. I have to clear all the inputs, change the nested html objects' classes and ids and everything works fine except the onchangeDate
event listener.
我正在使用 jQuery.dataTables 填充表,并且complete:
函数是将日期选择器绑定到tr tds中原始输入html元素的地方.我没有使用日期选择器分配的dp126353729 ID,而是使用ID作为我的ID的行号.
I am using jQuery.dataTables to populate my table and the complete:
function is where I bind my datepickers to my original input html elements inside my tr tds. Instead of the dp126353729 ids assigned by the datepickers I use the row number for my Ids which is not a problem at all.
我的问题是,当我关闭日期选择器时,我使用onchangeDate
事件触发onfocusout
事件,以便用新日期处理表行.我必须使用setTimeout
进行游戏,以使事件监听器首先获得新的日期!
My issue is that I use the onchangeDate
event to trigger the onfocusout
event when I close my datepicker so my table row is processed with the new date. I had to play games by using setTimeout
to get the event listeners to pick up the new date in the first place!
克隆的日期选择器元素未触发onchangeDate
.我试图将他们绑定到此事件,没有任何运气.使用默认ID也无济于事.
The cloned datepicker elements are not triggering onchangeDate
. I have tried to bind them to this event without any luck. Using the default ids hasn't helped either.
这是一个 JSFIDDLE ,以显示克隆的日期选择器如何触发onfocusout
Here is a JSFIDDLE to show how the cloned datepickers arent triggering 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事件,该事件依次执行所有行的验证和处理:
Here you can see the that I trigger the focusout event which in turns does all the row validating and processing:
$(".dp").on("changeDate",function(e){
e.stopImmediatePropagation();
$(this).trigger("focusout");
alert("onchange date" + $(this).val());
});
从那里开始处理该行的事件:
From there the event that processes the row:
//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创建的日期选择器的屏幕快照,该表成功从该函数触发
Here is a screenshot of a datepicker that is created on the complete:
function with dataTables which fires from this function succesfully
onClose: function(){
$(this).trigger("changeDate");
},
以下是克隆的datepicker屏幕截图,该屏幕未启用此功能:
Here is the cloned datepicker screenshot that does NOT fire on this function:
onClose: function(){
$(this).trigger("changeDate");
},
这是我在处理后克隆日期选择器的代码:
Here is the code where I clone the datepicker upon processing:
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,我想出了以下解决方案:
Solution: Thanks to armesian I came up with this solution:
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));
});
}
} }
对于我所看到的,我要指出一条我认为是需要修复的地方.
For what I could see i'm going to point out a line that I think is where the fix needs to go.
我假设在这一行中,您的意图是将changeDate事件绑定到新创建的元素,但是该绑定缺少触发事件时将要执行的实际功能:
I'm assuming that in this line your intention is to bind the changeDate event to the new created element but the binding is missing the actual function that will get executed when the event is triggered:
// 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");
之后添加以下行以对其进行修复:
@yardpenalty you were almost there!. You forget to bind the onfocusout event to the cloned dp. You can add the below line after dp.addClass("newDp");
that should fix it:
dp.on("focusout",function(){
$("<div class='red'></div>").insertBefore("#table_001");
});
这里正在工作 JSFIDDLE