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.