将datepicker()放在动态创建的元素上-JQuery / JQueryUI


115

我已经动态创建了文本框,希望它们每个都能够在单击时显示日历。我使用的代码是:

$(".datepicker_recurring_start" ).datepicker();

即使我所有的文本框都有一个名为datepicker_recurring_start的类,该方法仅在第一个文本框上有效。

非常感谢您的帮助!


当您说“动态创建”时,是指在页面加载之前是代码隐藏的,还是在页面加载之后是javascript的?因为如果在页面加载后添加了元素,则每次添加新的文本框时都需要重新绑定日历。
DangerMonkey,2012年

我在PHP的后台代码中加载它。
2012年

我认为您可能会感到困惑,但是很难用您提供的信息来分辨。因此,请确认一下,您能确认“动态创建的文本框”是什么意思。
Tr1stan 2012年

如果我正在加载“第一页”,php将查看数据库以查看“第一页”中有多少个日期文本框并显示它。因此,当加载“第一页”时,将有4个文本框需要加载datepicker()。“第二页”有7个文本框,需要加载datepicker()函数。
2012年

如果在第一次调用后数据选择器无法正常工作,请查看以下答案:stackoverflow.com/a/16283547/1329910您的问题可能与datepicker添加了自己的类有关:hasDatepicker
Vlad

Answers:


268

这是窍门:

$('body').on('focus',".datepicker_recurring_start", function(){
    $(this).datepicker();
});​

演示

$('...selector..').on('..event..', '...another-selector...', ...callback...);语法手段:
添加一个监听器...selector..(在body我们的例子)的事件..event..(“焦点”在我们的例子)。对于与选择器匹配的所有匹配节点的后代...another-selector....datepicker_recurring_start在我们的示例中),应用事件处理程序...callback...(在我们的示例中为内联函数)

请参阅http://api.jquery.com/on/,尤其是有关“委托事件”的部分


4
这是一种适用于任何类型的动态附加的解决方案。+1给你。
DangerMonkey,2012年

5
尽管对于我来说,.datapicker()每次文本框获得焦点时都想调用它似乎很奇怪-所以您还是要谨慎使用此方法(假设我没看错)。但是,我认为您会同意的,.datapicker()因为它可能会在尝试重新创建之前检查是否创建了日期选择器。对于其他代码,您可能没有这种宽限期。此外,。对(在JQuery的1.7只推出了-所以一定要确保你使用正确的版本。
Tr1stan

3
datepicker足够聪明,可以检查它是否已经创建(顺便说一下,所有jQueryUI组件),如果jQuery版本低于1.7,则可以直接使用live
ilyes kooli,2012年

7
您可能要添加过滤器:not(.hasDatepicker)
Salman A

1
当心在包含日期选择器的区域中使用jQuery.clone()。如果这样做,则添加此代码以删除hasDatepicker类,并将id datepicker添加到您的输入中:.... find('input.hasDatepicker')。removeClass('hasDatepicker')。removeAttr('id');
yahermann

44

对我来说下面的jQuery工作:

将“正文”更改为文档

$(document).on('focus',".datepicker_recurring_start", function(){
    $(this).datepicker();
});

感谢skafandri

注意:请确保每个字段的ID都不相同


正确-对我而言,我必须使用$(document)而不是$('body')-带有少量代码段的问题。我可以使该示例正常工作,但是一旦我将一堆JavaScript添加到小提琴中,此代码就不再对我有用。多亏了两个。
汤姆·斯蒂克2015年

16

skafandri的出色回答+1

这只是更新以检查hasDatepicker类。

$('body').on('focus',".datepicker", function(){

    if( $(this).hasClass('hasDatepicker') === false )  {
        $(this).datepicker();
    }

});

1
可以将其缩短为$('body').on('focus',".datepicker:not(.hasDatepicker)", function(){$(this).datepicker();});吗?
路加·史蒂文森

11

确保具有.date-picker该类的元素还没有一个hasDatepicker类。如果是这样,即使使用进行重新初始化$myDatepicker.datepicker();也将失败!相反,您需要做...

$myDatepicker.removeClass('hasDatepicker').datepicker();

非常正确!动态加载的元素最终对我来说不是问题,因此此解决方案有效。
斯特林·比森

6

您需要运行 .datepicker();动态创建其他文本框元素后,再次。

我建议在将元素添加到DOM的调用的回调方法中这样做。

因此,可以说您正在使用JQuery Load方法从源中提取元素并将其加载到DOM中,您将执行以下操作:

$('#id_of_div_youre_dynamically_adding_to').load('ajax/get_textbox', function() {
  $(".datepicker_recurring_start" ).datepicker();
});

1
根据我的经验,这在实践中并不总是有效。最好的情况是向您的元素添加唯一的ID,并使用这些ID引用它们并应用日期选择器。内部似乎插件使用这些选择器。
Wes Johnson

1

动态元素的新方法是MutationsObserver .。下面的示例使用underscore.js来使用(_.each)函数。

MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;    

var observerjQueryPlugins = new MutationObserver(function (repeaterWrapper) {

    _.each(repeaterWrapper, function (repeaterItem, index) {

        var jq_nodes = $(repeaterItem.addedNodes);

        jq_nodes.each(function () {

            // Date Picker
            $(this).parents('.current-repeateritem-container').find('.element-datepicker').datepicker({
                dateFormat: "dd MM, yy",
                showAnim: "slideDown",
                changeMonth: true,
                numberOfMonths: 1
            });

        });

    });

});

observerjQueryPlugins.observe(document, {
    childList: true,
    subtree: true,
    attributes: false,
    characterData: false
});

1

这是对我有用的(使用jQuery datepicker):

$('body').on('focus', '.datepicker', function() {
 $(this).removeClass('hasDatepicker').datepicker();
});

0

没有其他解决方案对我有用。在我的应用程序中,我要使用jquery将日期范围元素添加到文档中,然后将datepicker应用于它们。因此,由于某种原因,所有事件解决方案均无法正常工作。

这是最终有效的方法:

$(document).on('changeDate',"#elementid", function(){
    alert('event fired');
});

希望这对某人有帮助,因为这让我有点退缩。


0

您可以在javascript函数中添加.datepicker类,以便能够动态更改输入类型

 $("#ddlDefault").addClass("datepicker");
 $(".datepicker").datetimepicker({ timepicker: false, format: 'd/m/Y', });

0

我修改了@skafandri答案,以避免将datepicker构造函数重新应用于.datepicker_recurring_start类的所有输入。

这是HTML:

<div id="content"></div>
<button id="cmd">add a datepicker</button>

这是JS:

$('#cmd').click(function() {
  var new_datepicker = $('<input type="text">').datepicker();
  $('#content').append('<br>a datepicker ').append(new_datepicker);
});

这是一个工作演示


0

这就是我在JQuery 1.3上工作的结果,并且在第一次单击/显示焦点时就显示了

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/


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.