mettere datepicker () su elementi creati dinamicamente - JQuery / JQueryUI


116

Ho creato caselle di testo dinamicamente e desidero che ciascuna di esse sia in grado di visualizzare un calendario al clic. Il codice che sto usando è:

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

Che funzionerà solo sulla prima casella di testo, anche se tutte le mie caselle di testo hanno una classe chiamata datepicker_recurring_start.

Il tuo aiuto è molto apprezzato!


Quando dici "creato dinamicamente", intendi con code-behind prima del caricamento della pagina o con javascript dopo il caricamento della pagina? Perché se gli elementi vengono aggiunti dopo il caricamento della pagina, dovrai ricollegare il calendario ogni volta che viene aggiunta una nuova casella di testo.
DangerMonkey

Lo sto caricando nel code-behind con PHP.
immerso

Penso che potresti essere confuso, ma poi è difficile da dire con le informazioni che hai fornito. Quindi, solo per confermare, puoi confermare cosa intendi per "caselle di testo create dinamicamente" per favore.
Tr1stan

Se sto caricando la "pagina uno", php guarda il db per vedere quante caselle di testo della data ci sono nella "pagina uno" e lo visualizza. Quindi, quando viene caricata la "pagina uno", ci saranno 4 caselle di testo che devono caricare il datepicker (). 'pagina due' ha 7 caselle di testo che devono caricare la funzione datepicker ().
immerso

Se hai un problema con il selettore di dati che non funziona dopo una prima chiamata, controlla questa risposta: stackoverflow.com/a/16283547/1329910 Il tuo problema potrebbe avere a che fare con il datepicker che aggiunge la propria classe: hasDatepicker
Vlad

Risposte:


270

ecco il trucco:

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

DEMO

La $('...selector..').on('..event..', '...another-selector...', ...callback...);sintassi significa:
Aggiungi un ascoltatore a ...selector..( bodynel nostro esempio) per l'evento ..event..('focus' nel nostro esempio). Per tutti i discendenti dei nodi corrispondenti che corrispondono al selettore ...another-selector...( .datepicker_recurring_startnel nostro esempio), applica il gestore di eventi ...callback...(la funzione inline nel nostro esempio)

Vedi http://api.jquery.com/on/ e in particolare la sezione sugli "eventi delegati"


4
Questa è una soluzione che funzionerebbe con qualsiasi tipo di aggiunta dinamica. +1 a te.
DangerMonkey

5
Anche se mi sembra strano che tu voglia chiamare .datapicker()ogni volta che la casella di testo ottiene il focus, quindi dovresti stare attento con questo approccio (supponendo che io stia leggendo bene). Tuttavia, penso che staresti bene con il .datapicker()perché probabilmente controllerà se un datepicker è stato creato prima di provare a ricreare. Con altro codice potresti non avere questa grazia. Inoltre, .on (è stato introdotto solo in JQuery 1.7, quindi assicurati di utilizzare la versione corretta.
Tr1stan

3
datepicker è abbastanza intelligente da verificare se è già stato creato o meno (tutti i componenti jQueryUI a proposito) se la versione di jQuery è inferiore alla 1.7 puoi semplicemente usare live
ilyes kooli

7
Potresti voler aggiungere un filtro:not(.hasDatepicker)
Salman A

1
Attenzione a usare jQuery.clone () all'interno di un'area che include un datepicker. Se lo fai, aggiungilo per rimuovere la classe hasDatepicker E l'id datepicker aggiunge al tuo input: .... find ('input.hasDatepicker'). RemoveClass ('hasDatepicker'). RemoveAttr ('id');
yahermann

44

Per me di seguito jquery ha funzionato:

cambiando "corpo" in documento

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

Grazie a skafandri

Nota: assicurati che il tuo ID sia diverso per ogni campo


Corretto - per me devo usare $ (documento) e non $ ('corpo') - Una sorta di problema con piccoli frammenti di codice. Posso fare in modo che l'esempio funzioni senza problemi, ma non appena aggiungo un po 'del mio javascript in un violino, questo codice non funziona più per me. Grazie ad entrambi però.
Tom Stickel

16

Ottima risposta di skafandri +1

Questo è appena aggiornato per controllare la classe hasDatepicker.

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

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

});

1
Potrebbe quindi essere abbreviato a $('body').on('focus',".datepicker:not(.hasDatepicker)", function(){$(this).datepicker();});?
Luke Stevenson

11

Assicurati che il tuo elemento con la .date-pickerclasse NON abbia già una hasDatepickerclasse. Se lo fa, anche un tentativo di reinizializzare con $myDatepicker.datepicker();fallirà! Invece devi fare ...

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

Completamente giusto! Gli elementi caricati dinamicamente hanno finito per non essere il problema per me, quindi questa soluzione ha funzionato.
Sterling Beason

6

È necessario eseguire di .datepicker();nuovo dopo aver creato dinamicamente gli altri elementi della casella di testo.

Consiglierei di farlo nel metodo di callback della chiamata che aggiunge gli elementi al DOM.

Quindi diciamo che stai usando il metodo JQuery Load per estrarre gli elementi da una sorgente e caricarli nel DOM, faresti qualcosa del genere:

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

1
Questo non funziona sempre nella pratica in base alla mia esperienza. Il caso migliore è aggiungere ID univoci ai tuoi elementi e utilizzare tali ID per fare riferimento ad essi e applicare il datepicker. Sembra che internamente il plugin utilizzi quei selettori.
Wes Johnson

1

Il nuovo metodo per gli elementi dinamici è MutationsObserver . L'esempio seguente utilizza underscore.js per utilizzare la funzione (_.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

Questo era ciò che ha funzionato per me (usando jquery datepicker):

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

0

Nessuna delle altre soluzioni ha funzionato per me. Nella mia app, sto aggiungendo gli elementi dell'intervallo di date al documento usando jquery e quindi applicando loro il datepicker. Quindi nessuna delle soluzioni per eventi ha funzionato per qualche motivo.

Questo è ciò che alla fine ha funzionato:

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

Spero che questo aiuti qualcuno perché questo mi ha un po 'indietro.


0

puoi aggiungere la classe .datepicker in una funzione javascript, per poter cambiare dinamicamente il tipo di input

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

0

Ho modificato la risposta di @skafandri per evitare di riapplicare il datepickercostruttore a tutti gli input con .datepicker_recurring_startclasse.

Ecco l'HTML:

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

Ecco il JS:

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

ecco una demo funzionante


0

Questo è ciò che ha funzionato per me su JQuery 1.3 e viene mostrato al primo clic / focus

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

questo richiede che il tuo input abbia la classe 'mostrar_calendario'

Live è per JQuery 1.3+ per le versioni più recenti devi adattarlo a "on"

Scopri di più sulla differenza qui http://api.jquery.com/live/


0
$( ".datepicker_recurring_start" ).each(function(){
    $(this).datepicker({
        dateFormat:"dd/mm/yy",
        yearRange: '2000:2012',
        changeYear: true,
        changeMonth: true
    });
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.