为什么使用动态DOM时jQuery UI的日期选择器会出错?

33

我正在处理一个动态的DOM,已经调用了jQuery UI日期选择器来处理特定类名为.date的所有输入。

对于第一个静态结构它可以很好地工作,但是当我克隆它时,事件处理程序似乎不想移动过来。我得到了Firebug错误:

inst未定义

我尝试研究jQuery的新live()函数,但无法使两者结合起来。有任何想法吗?

13个回答

41

明白了,在将HTML添加到DOM后,我会在所有需要弹出日期选择器的输入框上运行以下代码。日期选择器会向已附加到的元素添加一个类,因此我们可以过滤掉现有的输入框,并仅将其应用于新的输入框。

$('.date').not('.hasDatePicker').datepicker();

希望这能够帮助到大家,因为我也曾经搜索了好几天都没有找到合适的解决方案。

您还应该注意,通过将其设置为上下文而不是整个页面,在新生成的HTML中检查input.date的速度会更快,因为这是一种更有效的操作。


2
Will,非常感谢!你节省了我几个小时的时间 :) - BinaryButterfly
14
使用动态DOM时,这个解决方案在我使用(jquery)克隆带有事件的表格行时并没有帮助到我。我的解决方案是执行$('.date').removeClass('hasDatepicker').datepicker()。 - David
David,你使用的jQuery核心和UI版本是什么?这是分别为1.3.2和1.7的,而且该解决方案已经在其他实现中得到了验证。不过,随你喜欢! - Will Morgan
这帮助我解决了我的问题。我的问题是我在输入框中添加了一个名为hasDatepicker的类,与Jquery UI无关。显然,Jquery UI代码在应用日期选择器之前检查此类,这会导致它无法工作!不要在要添加日期选择器的输入框中添加名为hasDatepicker的类!否则会出现错误消息“inst未定义”。 - Liam

5

我有一个类似的问题,我的页面上有多个表格,每个表格都有多个日期选择器,在单击“添加行”按钮时,它会添加一个具有动态HTML和日期选择器的表格行。

经过长时间的搜索,我意识到我的输入日期字段没有定义“id”,它们看起来像这样

<input type="text" class="datepicker" name="mDate1" value="" size=8 >

jQuery将所有日期字段的值指向页面上定义的第一个日期字段,日历会在所有日期字段上弹出,但第一个日期字段的值会改变。我对html进行了如下更改:

<input type="text" class="datepicker" id="Date1" name="mDate1" value="" size=8 >

通过添加“id”,它开始工作了,对于动态日期字段,我会像这样更改Id。
var allColumns = $("#"+$tableId+" tr:last td"); 
        $(allColumns).each(function (i,val) {
            if($(val).find(":input").hasClass("datepicker")){
                $(val).find(":input").attr("id",newId+$(val).find(":input").attr("id"));
            }
        });

4
这可能有点晚了,但是以上所有建议对我都没有用,我想出了一个简单的解决方案。
首先,问题的原因是什么: JQuery将datepicker分配给元素ID。如果您克隆元素,则可能会克隆相同的ID。这是jQuery不喜欢的。您可能会收到null引用错误或无论点击哪个输入字段,日期都被分配给第一个输入字段。
解决方案:
1)销毁datepicker 2)为所有输入字段分配新的唯一ID 3)为每个输入字段分配datepicker 确保您的输入类似于此
<input type="text" name="ndate[]" id="date1" class="n1datepicker">

在克隆之前,请销毁日期选择器。
$('.n1datepicker').datepicker('destroy');

在克隆后,请添加以下行:
var i = 0;
$('.n1datepicker').each(function () {
    $(this).attr("id",'date' + i).datepicker();
    i++;
});

接下来就是神奇的时刻了


你正在做比必要更多的工作——摧毁一切并重新创建一切。 - Will Morgan

4
您需要使用“live”事件,以使其与动态DOM配合使用。因此,如果您的日期选择器输入类为“date-input”,则以下代码将使其正常工作:
$(document).ready(function() {
    $('.date-input').live('click', function() {
    $(this).datepicker('destroy').datepicker({showOn:'focus'}).focus();
        });
});

1
不行。每次单击输入框时,您都在重新创建一个日期选择器,这样做会影响性能。 - Will Morgan
+1 对于简单易用且在其他解决方案出现问题时仍能正常工作的解决方案表示赞同。 - Matt
5
我想你可能是那种不为自己的工作感到骄傲的程序员。 - Will Morgan
我已经改进了这个答案,避免重新创建日期选择器,并在第一次点击/聚焦时显示。 - Mauricio Gracia Gutierrez

3
使用
$j(id or class).removeClass('hasDatepicker').datepicker();

它正在工作。


你并没有销毁日期选择器,这意味着每次触发代码时,你实际上是重新绑定了某些东西。因此,你将会有两个日期选择器(或者它会发生两次 - 没有经过测试)。所以,看起来它可能有效,但它不会以最佳方式运行。 - Will Morgan
1
很遗憾,除了在新元素上设置日期选择器之外,您正在重新绑定所有先前创建的元素,这将占用内存。在短时间内可能不会注意到这一点,但如果页面从未重新加载并且您这样做了许多次,您将会注意到差异。通常被认为是良好的编程实践来关注内存 :) - Will Morgan

2

使用jQuery选择器:

$(".mydatepicker:not(.hasDatepicker)").datepicker()

1

页面上有多个jquery-ui库的实例也会导致此错误。删除多余的实例对我的情况有效。


0
今天我遇到了相同的问题... 我在应用程序中使用 datetimepicker 插件。
同时也使用jquery的默认日期选择器。每当我在文档准备就绪时调用它们时,都会出现错误inst未定义
    $(document).ready(function(){
        $(".datepickerCustom").datetimepicker();
        $(".datepicker").datepicker();
        $("#MainForm").validationEngine('attach');
        ....
    });

所以我将代码更改为在文档准备就绪之前调用,如下所示:

    $(".datepickerCustom").datetimepicker();
    $(".datepicker").datepicker();
    $(document).ready(function(){
        $("#MainForm").validationEngine('attach');
        ....
    });

现在一切都正常工作,没有问题。


0

在尝试了这里的许多答案后,我发现以下方法适用于我,并且在第一次点击/聚焦时显示

function vincularDatePickers() {
    $('.mostrar_calendario').live('click', function () {
        $(this).datepicker({ showButtonPanel: true, changeMonth: true, changeYear: true, showOn: 'focus' }).focus();
    });
}

这需要您的输入具有“mostrar_calendario”类

live适用于JQuery 1.3+的版本,对于更新的版本,您需要将其适应为"on"

在此处查看更多关于差异的信息http://api.jquery.com/live/


0

我遇到了相同的症状,这是由于一个包含与输入元素相同id属性的td元素所致。

 <td id="fld_xyz"><input id="fld_xyz" class="date" /></td>

我知道这并不理想,但值得注意的是,日期选择器组件似乎依赖于ID的唯一性。


1
是的。ID 应该是唯一的。如果您想要识别同一类别中的多个元素,则应使用 class 属性。 - Will Morgan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接