克隆 jQuery UI 日期选择器时出现的问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2441061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
problem when cloning jQuery UI datepicker
提问by h3.
I have a div in which there is a datepicker. I use something like this to clone it:
我有一个 div,其中有一个日期选择器。我使用这样的东西来克隆它:
mydiv = $('#someDiv');
// works fine so far
mydiv.find('input.datefield').datepicker();
// clone without the events and insert
newDiv = myDiv.clone(false).insertAfter(myDiv);
// datepicker won't re-init if this class is present
newDiv.find('.hadDatepicker').removeClass('hadDatepicker');
// reinitialize datepicker
newDiv.find('input.datefield').datepicker();
This is a stripped down version of my code. It works and the calendar shows up as expected where it is expected .. but when a date is clicked, the previousdatepicker's value gets updated.. (the one from which it was cloned).
这是我的代码的精简版。它可以工作并且日历按预期显示在预期的位置..但是当单击日期时,前一个日期选择器的值会更新..(从中克隆它的那个)。
I've tried to destroy the (inexisting) instance before like this:
我之前曾尝试像这样销毁(不存在的)实例:
newDiv.find('input.datefield').datepicker('destroy').datepicker();
No luck ..
没运气 ..
I've checked how it keeps track of instances and manually cleared the data like this:
我检查了它如何跟踪实例并手动清除数据,如下所示:
newDiv.find('input.datefield').data('datepicker', false).datepicker('destroy').datepicker();
Still no luck.
仍然没有运气。
What I don't understand is that only the date selection behavior is buggy, everything else works as expected.
我不明白的是只有日期选择行为有问题,其他一切都按预期工作。
I really don't know what else to check now ..
我真的不知道现在还要检查什么..
回答by jitter
This works for me with jQuery UI 1.7.2
这适用于 jQuery UI 1.7.2
var mydiv = $('#someDiv');
mydiv.find('input.datefield').datepicker();
var newDiv = mydiv.clone(false).attr("id", "someDiv2").insertAfter(mydiv);
newDiv.find('input.datefield')
.attr("id", "")
.removeClass('hasDatepicker')
.removeData('datepicker')
.unbind()
.datepicker();
Check http://jsbin.com/ahoqa3/2for a quick demo
检查http://jsbin.com/ahoqa3/2以获得快速演示
btw. you seem to have different errors in the code of your question. The css class is hasDatepicker
not hadDatepicker
and at one time you wrote mydiv
and the next time the variable is myDiv
which isn't the same.
顺便提一句。您的问题代码中似乎有不同的错误。css 类hasDatepicker
不是hadDatepicker
,一次是你写的mydiv
,而下一次myDiv
是不一样的变量。
回答by Andrew Roazen
Here's the problem. datepicker creates UUID-based ID attributes for the input fields it binds when you initialize it. You cloning those elements results in more elements with either the same ID (which jQuery does not like) or a different ID if your clone routine manages that (which means datepicker does not know about the clones). In other words, datepicker only initializes all the elements matching your selector at the time you call it.it actually makes less sense to try to destroy/disable/enable over and over, when you can just wrap the init call inside whatever function you use to create the clones.
这就是问题所在。datepicker 在初始化时为其绑定的输入字段创建基于 UUID 的 ID 属性。如果克隆例程管理这些元素,则克隆这些元素会产生更多具有相同 ID(jQuery 不喜欢)或不同 ID 的元素(这意味着 datepicker 不知道克隆)。换句话说,datepicker 仅在您调用它时初始化与您的选择器匹配的所有元素。当您可以将 init 调用包装在用于创建克隆的任何函数中时,尝试一遍又一遍地销毁/禁用/启用实际上没有意义。
Because my clone functions typically copy from hidden DOM elements rather than visible ones, I have the luxury deciding whether I need to bind before or after cloning. So, make #templateDiv a hidden element on your page with the INPUT element already in there.
因为我的克隆函数通常是从隐藏的 DOM 元素而不是可见元素中复制的,所以我可以随意决定是否需要在克隆之前或之后进行绑定。因此,让 #templateDiv 成为页面上的隐藏元素,其中已经包含 INPUT 元素。
mydiv = $('#templateDiv');
mydest = $('#someDiv');
function make_the_donuts() {
newDiv = myDiv.clone(true).insertAfter(mydest);
// attach datepickers by instance rather than by class
newDiv.find('input.datefield').datepicker();
}
and that pretty much does it. Clone(true) whenever you can, it'll save you headaches in the long run.
这几乎可以做到。尽可能克隆(真),从长远来看,它会为您省去麻烦。
回答by dfmiller
If you call .datepicker('destroy').removeAttr('id')
before cloning and then re-init the date picker it will work.
如果您.datepicker('destroy').removeAttr('id')
在克隆之前调用然后重新初始化日期选择器,它将起作用。
This seems to be a bug with destroy since it is supposed to return the element back to it's original state.
这似乎是 destroy 的一个错误,因为它应该将元素返回到它的原始状态。
回答by edfuh
just do
做就是了
$('input.datefield').datepicker("destroy");
before cloning the div. Then afterinserting the clone bind the datepicker again
在克隆 div 之前。然后在插入克隆后再次绑定日期选择器
$('input.datefield').datepicker();
kind of a 'hacky' solution but it works perfectly.
一种“hacky”解决方案,但效果很好。
回答by kuhn
$('input.datefield').datepicker("destroy");
$('input.datefield').datepicker();
it works good. But just doing this, datepicker will open on cloned input and set the date to the original input (because they have the same ID)
它运作良好。但只要这样做,datepicker 将打开克隆输入并将日期设置为原始输入(因为它们具有相同的 ID)
to solve this you must change id attribute of the cloned input.
要解决此问题,您必须更改克隆输入的 id 属性。
dp = < cloned input >
var d = $('input.vDateField');
dp.removeClass('hasDatepicker');
dp.attr('id', dp.attr('id')+d.length);
d.datepicker("destroy");
d.datepicker();
and it will work great!
它会很好用!
回答by Hardik Patil
Here how it worked for me:
这里是如何为我工作的:
First you need to remove the class hasDatepickerfromthe cloned elements,because this is what is preventing the datepicker from getting attached to the specific element.
首先,您需要从克隆的元素中删除类hasDatepicker,因为这是阻止日期选择器附加到特定元素的原因。
Then you gotta remove the idattribute from each of the cloned elements else .datepicker() will assume that datepicker is added to this element.
然后你必须从每个克隆的元素中删除id属性,否则 .datepicker() 会假设 datepicker 被添加到这个元素中。
After that call .datepicker() on cloned element.
在那之后打电话。克隆元素上的datepicker()。
newDiv.find('.classAttributeGivenForDatepicker').each(function() {
$(this).removeAttr('id').removeClass('hasDatepicker');
$(this).datepicker({dateFormat: 'dd-mm-yy', minDate: 0, autoclose: true,});
});
回答by pestaa
What about changing the order?
换个顺序怎么办?
mydiv = $('#someDiv');
// clone without the events and insert
newDiv = myDiv.clone(false).insertAfter(myDiv);
// datepicker won't re-init if this class is present
// not necessary anymore
// newDiv.find('.hadDatepicker').removeClass('hadDatepicker');
newDiv.find('input.datefield').datepicker();
// datepicker attached as a last step
mydiv.find('input.datefield').datepicker();
Honestly I don't know how datepicker works internally. My hunch is that it stores something in jQuery DOM storage. Let's avoid copying it at all costs.
老实说,我不知道 datepicker 内部是如何工作的。我的预感是它在 jQuery DOM 存储中存储了一些东西。让我们不惜一切代价避免复制它。
(You might have long business logic between these lines of code. The point is to have a backup of #someDiv before putting a datepicker on it.)
(您可能在这些代码行之间有很长的业务逻辑。关键是在将日期选择器放在#someDiv 之前备份它。)
回答by David Morton
Make sure your newly cloned datepicker has a different name and ID than the original. If they both have the same name, then the behavior you're describing would be normal.
确保您新克隆的日期选择器与原始日期选择器具有不同的名称和 ID。如果它们都具有相同的名称,那么您所描述的行为将是正常的。
Try changing that last line to something like:
尝试将最后一行更改为:
newDiv.find('input.datefield').attr('id', 'newDatePicker').attr('name', 'newDatePicker').datepicker();
回答by mariofertc
The complete solution that works for me.
适合我的完整解决方案。
//before
$('input.fecha').datepicker("destroy");
newcell.innerHTML = table.rows[0].cells[i].innerHTML;
//change de input id
$("input.fecha").attr("id", function (arr) {return "fecha" + arr;});
//after
$('input.fecha').datepicker({defaultDate: "+1w",changeMonth: true,numberOfMonths: 1, showOn: "button", buttonImage: "<?php echo base_url() ?>images/calendar.gif", buttonImageOnly: true, showLabel:false, dateFormat:"yy-mm-dd"});
And the html td table.
和 html td 表。
<td><?php echo form_input(array('name' => 'fecha','id' => 'fecha','class' => 'fecha')); ?></td>
Hope this helps you.
希望这对你有帮助。
Good day
再会
回答by Isaac
var dt = new Date();
var month = dt.getMonth();
var day = dt.getDate();
var year = dt.getFullYear()-5;
$newClone.children().children("#fna"+clickID)
.attr({
'id': 'fna1'+newID,
'name': 'fna'+newID,
'value': day + '-' + month + '-' + year
})
.datepicker("destroy")
.datepicker({
firstDay: 1,
changeMonth: true,
changeYear: true,
yearRange: 'c-100:c',
defaultDate: '-1y',
dateFormat: 'dd-mm-yy' ,
nextText: "Mes siguiente",
prevText: "Mes anterior",
monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'],
dayNamesMin: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa']
});