umieszczenie datepicker () na dynamicznie tworzonych elementach - JQuery / JQueryUI


116

Mam dynamicznie utworzone pola tekstowe i chcę, aby każde z nich mogło wyświetlać kalendarz po kliknięciu. Kod, którego używam to:

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

Co będzie działać tylko na pierwszym polu tekstowym, mimo że wszystkie moje pola tekstowe mają klasę o nazwie datepicker_recurring_start.

Twoja pomoc jest bardzo ceniona!


Kiedy mówisz „utworzone dynamicznie”, masz na myśli kod związany z kodem przed załadowaniem strony czy JavaScript po załadowaniu strony? Ponieważ jeśli elementy zostaną dodane po załadowaniu strony, za każdym razem, gdy dodawane jest nowe pole tekstowe, musisz ponownie wiązać kalendarz.
— DangerMonkey

Ładuję go w kodzie za pomocą PHP.
— przesiąknięty

Myślę, że możesz być zdezorientowany, ale wtedy trudno to stwierdzić na podstawie dostarczonych informacji. Tak więc, aby potwierdzić, czy możesz potwierdzić, co masz na myśli mówiąc o „dynamicznie tworzonych polach tekstowych”.
— Tr1stan

Jeśli ładuję „pierwszą stronę”, php patrzy na bazę danych, aby zobaczyć, ile pól tekstowych daty znajduje się na „pierwszej stronie” i wyświetla ją. Kiedy więc ładuje się pierwsza strona, będą 4 pola tekstowe, które będą musiały załadować datepicker (). 'strona druga' ma 7 pól tekstowych, które muszą załadować funkcję datepicker ().
— przesiąknięty

Jeśli masz problem z niedziałającym selektorem danych po pierwszym połączeniu, sprawdź tę odpowiedź: stackoverflow.com/a/16283547/1329910 Twój problem może być związany z dodaniem własnej klasy Datepicker: hasDatepicker
— Vlad

Odpowiedzi:


270

oto sztuczka:

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

PRÓBNY

Te $('...selector..').on('..event..', '...another-selector...', ...callback...);środki składniowe:
Dodawanie słuchacza ...selector..(the bodyw naszym przykładzie) za zdarzenie ..event..( „FOCUS” w naszym przykładzie). Dla wszystkich potomków pasujących węzłów, które pasują do selektora ...another-selector...( .datepicker_recurring_startw naszym przykładzie), zastosuj procedurę obsługi zdarzeń ...callback...(funkcję wbudowaną w naszym przykładzie)

Zobacz http://api.jquery.com/on/, a zwłaszcza sekcję o „wydarzeniach delegowanych”


4
Jest to rozwiązanie, które sprawdzi się w każdym rodzaju dołączania dynamicznego. +1 dla Ciebie.
— DangerMonkey

5
Chociaż wydaje mi się dziwne, że chciałbyś dzwonić za .datapicker()każdym razem, gdy pole tekstowe nabiera ostrości - więc chciałbyś zachować ostrożność przy tym podejściu (zakładając, że dobrze to czytam). Jednak myślę, że nie .datapicker()przeszkadzałoby ci to, ponieważ prawdopodobnie sprawdzi, czy datapicker jest utworzony przed próbą ponownego utworzenia. Z innym kodem możesz nie mieć tej łaski. Ponadto .on (jest wprowadzony tylko w JQuery 1.7 - więc upewnij się, że używasz poprawnej wersji.
— Tr1stan

3
datepicker jest wystarczająco sprytny, aby sprawdzić, czy jest już utworzony, czy nie (przy okazji wszystkie komponenty jQueryUI) jeśli wersja jQuery jest poniżej 1.7, możesz po prostu użyć live
— ilyes kooli

7
Możesz dodać filtr:not(.hasDatepicker)
— Salman A,

1
Uważaj na używanie jQuery.clone () w obszarze zawierającym datepicker. Jeśli to zrobisz, dodaj to, aby usunąć klasę hasDatepicker ORAZ id datepicker dodaje do twoich danych wejściowych: .... find ('input.hasDatepicker'). RemoveClass ('hasDatepicker'). RemoveAttr ('id');
— yahermann

44

U mnie poniżej działało jquery:

zmiana „treści” na dokument

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

Dzięki skafandri

Uwaga: upewnij się, że Twój identyfikator jest inny dla każdego pola


Prawidłowo - dla mnie muszę używać $ (dokument), a nie $ ('body') - Rodzaj problemu z małymi fragmentami kodu. Mogę sprawić, by przykład zadziałał bez problemu, ale i wkrótce, gdy dodam kilka moich javascript do skrzypiec, ten kod już nie działa. Ale dzięki obu.
— Tom Stickel,

16

Doskonała odpowiedź od skafandri +1

Zostało to właśnie zaktualizowane, aby sprawdzić klasę hasDatepicker.

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

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

});

1
Czy można to wtedy skrócić do $('body').on('focus',".datepicker:not(.hasDatepicker)", function(){$(this).datepicker();});?
— Luke Stevenson

11

Upewnij się, że Twój element z .date-pickerklasą NIE ma już hasDatepickerklasy. Jeśli tak się stanie, nawet próba ponownej inicjalizacji za pomocą programu $myDatepicker.datepicker();zakończy się niepowodzeniem! Zamiast tego musisz zrobić ...

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

Dokładnie tak! Elementy ładowane dynamicznie nie były dla mnie problemem, więc to rozwiązanie zadziałało.
— Sterling Beason

6

Musisz uruchomić .datepicker();ponownie po dynamicznym utworzeniu innych elementów pola tekstowego.

Poleciłbym to zrobić w metodzie wywołania zwrotnego wywołania, czyli dodaniu elementów do DOM.

Powiedzmy, że używasz metody JQuery Load do ściągnięcia elementów ze źródła i załadowania ich do DOM, zrobiłbyś coś takiego:

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

1
Z mojego doświadczenia wynika, że ​​nie zawsze działa to w praktyce. Najlepszym przypadkiem jest dodanie unikalnych identyfikatorów do swoich elementów i użycie tych identyfikatorów do odniesienia się do nich i zastosowania selektora dat. Wygląda na to, że wewnętrznie wtyczka używa tych selektorów.
— Wes Johnson,

1

Nowa metoda dla elementów dynamicznych to MutationsObserver .. W poniższym przykładzie użyto znaku podkreślenia.js do użycia funkcji (_.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

Oto, co zadziałało dla mnie (używając jquery datepicker):

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

0

Żadne z innych rozwiązań nie działało dla mnie. W mojej aplikacji dodaję elementy zakresu dat do dokumentu za pomocą jQuery, a następnie stosuję do nich DatePicker. Więc żadne z rozwiązań eventowych nie działało z jakiegoś powodu.

Oto, co w końcu zadziałało:

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

Mam nadzieję, że to komuś pomoże, ponieważ trochę mnie cofnęło.


0

możesz dodać klasę .datepicker do funkcji javascript, aby móc dynamicznie zmieniać typ danych wejściowych

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

0

Zmodyfikowałem odpowiedź @skafandri, aby uniknąć ponownego zastosowania datepickerkonstruktora do wszystkich danych wejściowych z .datepicker_recurring_startklasą.

Oto kod HTML:

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

Oto JS:

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

oto działające demo


0

To właśnie zadziałało dla mnie w JQuery 1.3 i jest widoczne przy pierwszym kliknięciu / fokusie

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

wymaga to, aby twoje dane wejściowe miały klasę „mostrar_calendario”

Live jest dla JQuery 1.3+ dla nowszych wersji, musisz dostosować to do „on”

Zobacz więcej o różnicy tutaj http://api.jquery.com/live/


0
$( ".datepicker_recurring_start" ).each(function(){
    $(this).datepicker({
        dateFormat:"dd/mm/yy",
        yearRange: '2000:2012',
        changeYear: true,
        changeMonth: true
    });
});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.