克隆jQuery UI datepicker时的问题

时间:2010-03-14 03:14:16

标签: jquery jquery-ui uidatepicker

我有一个div,其中有一个datepicker。我使用这样的东西来克隆它:

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

这是我的代码的精简版本。它工作正常,日历按预期显示在预期的位置。但是当点击日期时,上一个 datepicker的值会更新..(克隆它的那个)。

我试图在此之前销毁(不存在的)实例:

newDiv.find('input.datefield').datepicker('destroy').datepicker();

没有运气..

我已经检查了它如何跟踪实例并手动清除了这样的数据:

newDiv.find('input.datefield').data('datepicker', false).datepicker('destroy').datepicker();

仍然没有运气。

我不明白的是,只有日期选择行为是错误的,其他一切都按预期工作。

我真的不知道现在还要检查什么..

12 个答案:

答案 0 :(得分:39)

这适用于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();

检查http://jsbin.com/ahoqa3/2以获得快速演示

顺便说一句。您似乎在问题的代码中有不同的错误。 css类是hasDatepicker而不是hadDatepicker,并且您曾一次编写mydiv,而下次变量myDiv则不同。

答案 1 :(得分:26)

这是问题所在。 datepicker为初始化时绑定的输入字段创建基于UUID的ID属性。克隆这些元素会导致更多元素具有相同的ID(jQuery不喜欢)或者不同的ID(如果克隆例程管理它)(这意味着datepicker不知道克隆)。 换句话说,datepicker只会在你调用它时初始化与你的选择器匹配的所有元素。它实际上没有意义去尝试一遍又一遍地销毁/禁用/启用,当你可以包装在用于创建克隆的任何函数内部调用init。

因为我的克隆函数通常从隐藏的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();
}

这几乎就是这样。克隆(真实),只要你能做到,从长远来看,它会让你头疼。

答案 2 :(得分:7)

如果您在克隆之前致电.datepicker('destroy').removeAttr('id'),然后重新启动日期选择器,它将会有效。

这似乎是一个破坏的错误,因为它应该将元素返回到它的原始状态。

答案 3 :(得分:3)

只是做

$('input.datefield').datepicker("destroy");

克隆div之前。 然后之后插入克隆再次绑定datepicker

$('input.datefield').datepicker();

有点像'hacky'的解决方案,但效果很好。

答案 4 :(得分:1)

$('input.datefield').datepicker("destroy");
$('input.datefield').datepicker();

效果很好。 但只是这样做,datepicker将在克隆输入上打开并将日期设置为原始输入(因为它们具有相同的ID)

要解决此问题,您必须更改克隆输入的id属性。

dp = < cloned input >
var d = $('input.vDateField');
dp.removeClass('hasDatepicker');
dp.attr('id', dp.attr('id')+d.length);
d.datepicker("destroy");
d.datepicker();

它会很棒!

答案 5 :(得分:1)

这对我有用:

首先,您需要删除克隆元素的类 hasDatepickerfrom ,因为这是阻止datepicker附加到特定元素的原因。

然后你必须从每个克隆元素中删除 id 属性.datepicker()将假定将datepicker添加到此元素。

在克隆元素上调用 datepicker ()之后。

newDiv.find('.classAttributeGivenForDatepicker').each(function() {
   $(this).removeAttr('id').removeClass('hasDatepicker');
   $(this).datepicker({dateFormat: 'dd-mm-yy', minDate: 0, autoclose: true,});
});

答案 6 :(得分:0)

如何更改订单?

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

老实说,我不知道datepicker如何在内部工作。我的预感是它存储在jQuery DOM存储中的东西。我们不惜一切代价避免复制它。

(在这些代码行之间可能有很长的业务逻辑。重点是在将datepicker放在其上之前备份#someDiv。)

答案 7 :(得分:0)

确保新克隆的日期选择器具有与原始名称和ID不同的名称和ID。如果它们都具有相同的名称,那么您描述的行为将是正常的。

尝试将最后一行更改为:

newDiv.find('input.datefield').attr('id', 'newDatePicker').attr('name', 'newDatePicker').datepicker();

答案 8 :(得分:0)

适合我的完整解决方案。

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

和html td表。

<td><?php echo form_input(array('name' => 'fecha','id' => 'fecha','class' => 'fecha')); ?></td>

希望这会对你有所帮助。

美好的一天

答案 9 :(得分:0)

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

答案 10 :(得分:0)

这可能有点晚了,但上面的所有建议对我都不起作用,我想出了一个简单的解决方案。

首先,导致问题的原因是: JQuery将datepicker分配给元素id。如果你是克隆元素,那么也可以克隆相同的id。哪个jQuery不喜欢。您最终可能会收到空引用错误或分配给第一个输入字段的日期,无论您单击哪个输入字段。

解决方案:

1)销毁datepicker 2)为所有输入字段分配新的唯一ID 3)为每个输入分配datepicker

确保您的输入是这样的

<input type="text" name="ndate[]" id="date1" class="n1datepicker">

在克隆之前,销毁datepicker

$('.n1datepicker').datepicker('destroy');

克隆后,也可以添加这些行

var i = 0;
$('.n1datepicker').each(function () {
    $(this).attr("id",'date' + i).datepicker();
    i++;
});

并且魔术发生了

答案 11 :(得分:0)

如果元素的ID已更改,则

Datepicker不会。因此,如果必须要求,最好不要更改元素的id。 但是,如果您确实需要更改ID,并且更改后的ID需要使用datepicker,请遵循

$(selector).removeClass('hasDatepicker');
$(selector).datepicker({
  changeMonth: true,
  changeYear: true
});