ставлячи datepicker () на динамічно створені елементи - JQuery / JQueryUI


115

Я динамічно створював текстові поля, і я хочу, щоб кожна з них могла відображати календар при натисканні. Я використовую код:

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

Який працюватиме лише в першому текстовому полі, хоча всі мої текстові поля мають клас, який називається datepicker_recurring_start.

Ваша допомога дуже цінується!


Коли ви говорите "динамічно створений", ви маєте на увазі затримку коду перед завантаженням сторінки або javascript після завантаження сторінки? Тому що якщо елементи додаються після завантаження сторінки, вам потрібно буде перев’язувати календар щоразу, коли додається нове текстове поле.
DangerMonkey

Я завантажую його в код ззаду з PHP.
крутий

Я думаю, що ви можете заплутатися, але тоді важко сказати інформацію, яку ви надали. Тож для підтвердження, чи можете ви підтвердити, що ви маєте на увазі під "динамічно створеними текстовими полями", будь ласка.
Tr1stan

Якщо я завантажую "сторінку першу", php дивиться на db, щоб побачити, скільки текстових полів дати на "сторінці одна", і відображає її. Отже, коли завантажується сторінка «перша», буде 4 текстових поля, які потрібно завантажити датчик (). "сторінка друга" має 7 текстових полів, у які потрібно завантажити функцію Datepicker ().
крутий

Якщо у вас є проблема з тим, що інструмент вибору даних не працює після першого дзвінка, ознайомтеся з цією відповіддю: stackoverflow.com/a/16283547/1329910 Можливо, ваша проблема пов'язана з вибором дати, додавши власний клас: hasDatepicker
Влад

Відповіді:


270

ось хитрість:

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

DEMO

У $('...selector..').on('..event..', '...another-selector...', ...callback...);синтаксичних засобів:
Додати слухача ...selector..( bodyв нашому прикладі) для події ..event..( «фокус» в нашому прикладі). Для всіх нащадків узгоджуючих вузлів, що відповідають селектору ...another-selector...( .datepicker_recurring_startу нашому прикладі), застосуйте обробник подій ...callback...(функція вбудованого в нашому прикладі)

Дивіться http://api.jquery.com/on/ і особливо розділ про "делеговані події"


4
Це рішення, яке б працювало в будь-якому типі динамічного додавання. +1 вам.
DangerMonkey

5
Хоча мені здається дивним, що ви хочете зателефонувати .datapicker()кожного разу, коли текстове поле отримує фокус - тому ви хочете бути обережними з таким підходом (припускаючи, що я читаю це правильно). Однак я думаю, що ви будете в порядку з тим, .datapicker()що він, ймовірно, перевірить, чи створено підбирач дат, перш ніж спробувати відтворити. З іншим кодом ви можете не мати цієї благодаті. Також .on (вводиться лише в JQuery 1.7 - тому переконайтеся, що ви використовуєте правильну версію.
Tr1stan

3
datepicker досить розумний, щоб перевірити, чи він уже створений чи ні (всі компоненти jQueryUI до речі), якщо версія jQuery нижче 1,7, ви можете просто використовувати live
ilyes kooli

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

Завдяки скафандрі

Примітка. Переконайтеся, що ваш ідентифікатор відрізняється для кожного поля


Правильно - для мене я повинен використовувати $ (document), а не $ ('body') - Сортування проблеми з невеликими фрагментами коду. Я можу отримати приклад для роботи без проблем, але, як тільки я додаю кучу свого javascript у скрипку, цей код більше не працює для мене. Завдяки обом, хоча.
Том Стікель

16

Відмінна відповідь скафандрі +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
Це не завжди працює на практиці з мого досвіду. Найкращий випадок - додати унікальні ідентифікатори до своїх елементів та використовувати ці ідентифікатори для посилання на них та застосувати позначку дат. Здається, що плагін використовує ці селектори.
Уес Джонсон

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


0

Жодне з інших рішень для мене не працювало. У своєму додатку я додаю елементи діапазону дат до документа за допомогою jquery, а потім застосовую до них датчик. Тож жодне рішення подій чомусь не спрацювало.

Ось що, нарешті, спрацювало:

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

Сподіваюся, що це комусь допоможе, тому що це мене трохи повернуло.


0

ви можете додати клас .datepicker у функцію javascript, щоб мати можливість динамічно змінювати тип введення

 $("#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 або новіших версій, для нових версій потрібно адаптувати це до "увімкнено"

Більше про різницю дивіться тут http://api.jquery.com/live/


0
$( ".datepicker_recurring_start" ).each(function(){
    $(this).datepicker({
        dateFormat:"dd/mm/yy",
        yearRange: '2000:2012',
        changeYear: true,
        changeMonth: true
    });
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.