【问题标题】:putting datepicker() on dynamically created elements - JQuery/JQueryUI将 datepicker() 放在动态创建的元素上 - JQuery/JQueryUI
【发布时间】:2024-05-23 02:45:01
【问题描述】:

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

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

这仅适用于第一个文本框,即使我所有的文本框都有一个名为 datepicker_recurring_start 的类。

非常感谢您的帮助!

【问题讨论】:

  • 当您说“动态创建”时,您是指在页面加载之前使用代码隐藏还是在页面加载之后使用 javascript?因为如果在页面加载后添加元素,则每次添加新文本框时都需要重新绑定日历。
  • 我正在使用 PHP 将其加载到代码隐藏中。
  • 我认为您可能会感到困惑,但是您提供的信息很难判断。所以只是为了确认,你能确认一下“动态创建的文本框”是什么意思吗?
  • 如果我正在加载“第一页”,php 会查看数据库以查看“第一页”中有多少日期文本框并显示它。因此,当“第一页”加载时,将有 4 个文本框需要加载 datepicker()。 “第二页”有 7 个文本框,需要加载 datepicker() 函数。
  • 如果您在第一次调用后遇到数据选择器无法正常工作的问题,请查看以下答案:*.com/a/16283547/1329910您的问题可能与 datepicker 添加自己的类有关:hasDatepicker

标签: javascript jquery jquery-ui datepicker


【解决方案1】:

这是诀窍:

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

DEMO

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

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

【讨论】:

  • 这是一个适用于任何动态附加的解决方案。 +1 给你。
  • 虽然我觉得每次文本框获得焦点时都想调用.datapicker() 似乎很奇怪 - 所以你要小心这种方法(假设我没看错)。但是,我认为您可以使用.datapicker(),因为它可能会在尝试重新创建之前检查是否创建了日期选择器。使用其他代码,您可能没有这种优雅。此外, .on( 仅在 JQuery 1.7 中引入 - 所以请确保您使用的是正确的版本。
  • datepicker 足够聪明,可以检查它是否已经创建(顺便说一下,所有 jQueryUI 组件)如果 jQuery 版本低于 1.7,你可以简单地使用 live
  • 您可能需要添加过滤器:not(.hasDatepicker)
  • 小心在包含日期选择器的区域内使用 jQuery.clone()。如果你这样做,添加这个以删除 hasDatepicker 类和 id datepicker 添加到你的输入: .... find('input.hasDatepicker').removeClass('hasDatepicker').removeAttr('id');
【解决方案2】:

对我来说,下面的 jquery 工作:

将“正文”更改为文档

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

感谢skafandri

注意:确保每个字段的 id 都不同

【讨论】:

  • 正确 - 对我来说,我必须使用 $(document) 而不是 $('body') - 小sn-ps代码的问题。我可以让示例正常工作,但是一旦我将一堆 javascript 添加到小提琴中,这段代码就不再适用于我了。不过,感谢两者。
【解决方案3】:

skafandri +1 的出色回答

这只是为了检查 hasDatepicker 类而更新。

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

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

});

【讨论】:

  • 可以缩短为$('body').on('focus',".datepicker:not(.hasDatepicker)", function(){$(this).datepicker();});吗?
【解决方案4】:

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

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

【讨论】:

  • 完全正确!动态加载的元素最终对我来说不是问题,所以这个解决方案奏效了。
【解决方案5】:

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

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

假设您使用 JQuery Load 方法从源中提取元素并将它们加载到 DOM 中,您可以执行以下操作:

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

【讨论】:

  • 根据我的经验,这在实践中并不总是有效。最好的情况是为您的元素添加唯一 ID,并使用这些 ID 来引用它们并应用日期选择器。似乎插件在内部使用了这些选择器。
【解决方案6】:

动态元素的新方法是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
});

【讨论】:

    【解决方案7】:

    这对我有用(使用 jquery datepicker):

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

    【讨论】:

      【解决方案8】:

      其他解决方案都不适合我。在我的应用程序中,我使用 jquery 将日期范围元素添加到文档中,然后将 datepicker 应用于它们。因此,由于某种原因,所有事件解决方案都不起作用。

      这终于奏效了:

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

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

      【讨论】:

        【解决方案9】:

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

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

        【讨论】:

          【解决方案10】:

          我已经修改了@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);
          });
          

          这是working demo

          【讨论】:

            【解决方案11】:

            这在 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/

            【讨论】:

              【解决方案12】:
              $( ".datepicker_recurring_start" ).each(function(){
                  $(this).datepicker({
                      dateFormat:"dd/mm/yy",
                      yearRange: '2000:2012',
                      changeYear: true,
                      changeMonth: true
                  });
              });
              

              【讨论】:

                【解决方案13】:
                 $('body').on('focus',".my_date_picker", function(){
                            $(this).datepicker({
                                minDate: new Date(),
                            });
                        });
                

                【讨论】:

                  最近更新 更多