Problema dell'evento onchange di jQuery Datepicker


239

Ho un codice JS in cui quando cambi un campo chiama una routine di ricerca. Il problema è che non riesco a trovare alcun evento jQuery che si attivi quando Datepicker aggiorna il campo di input.

Per qualche motivo, un evento di modifica non viene chiamato quando Datepicker aggiorna il campo. Quando viene visualizzato il calendario, cambia lo stato attivo, quindi non posso nemmeno usarlo. Qualche idea?


Ho finito per usare stackoverflow.com/a/30132949/293792 poiché questo sembrava rispondere direttamente alla domanda
twobob

Risposte:


370

Puoi usare l' onSelectevento del datepicker .

$(".date").datepicker({
    onSelect: function(dateText) {
        console.log("Selected date: " + dateText + "; input's current value: " + this.value);
    }
});

Esempio live :

Sfortunatamente, viene onSelectgenerato ogni volta che viene selezionata una data, anche se non è cambiata. Questo è un difetto di progettazione nel datepicker: si attiva sempre onSelect(anche se non è cambiato nulla) e non attiva alcun evento sull'input sottostante al cambiamento. (Se guardi nel codice di quell'esempio, stiamo ascoltando le modifiche, ma non vengono sollevate.) Probabilmente dovrebbe changegenerare un evento sull'input quando cambiano le cose (forse il solito evento, o forse un datepicker- uno specifico).


Se ti piace, ovviamente, puoi rendere l' changeevento sul inputfuoco:

$(".date").datepicker({
    onSelect: function() {
        $(this).change();
    }
});

Ciò si attiverà changesul sottostante inputper qualsiasi gestore collegato tramite jQuery. Ma di nuovo, lo spara sempre . Se vuoi sparare solo su un vero cambiamento, dovrai salvare il valore precedente (possibilmente via data) e confrontare.

Esempio live :


1
@ user760092: ho pubblicato questa risposta e poi sono uscito, e letteralmente mentre me ne andavo ho pensato "Sai, potresti innescare i changegestori" e così ho aggiornato la risposta con quello. :-)
TJ Crowder,

1
Ho girato in tondo cercando di farlo funzionare in tutti gli scenari e questo l'ha fatto! Molto apprezzato!
Chris Nevill,

7
Perché nel mondo non hanno fatto quegli eventi reali?
Jay K,

1
Questo è per "selezione" e NON per "modifica". Se selezioni una data e poi la ri-selezioni, questo evento viene generato. Alcuni sviluppatori vorranno sapere quando una data è cambiata da uno stato iniziale per sapere se i dati sono "sporchi" e devono essere salvati. Per questo motivo, ti sto sottovalutando su questo.
AndroidDev

4
@AndroidDev: l'ho chiarito. ( Potresti avere, ovviamente; l'obiettivo del sito è avere buone risposte ; il montaggio rispettoso per ottenere ciò è incoraggiato.) È un difetto di progettazione nell'agenda, non nella risposta. (Quello che dovrebbe fare è lanciare un evento di cambiamento di qualche tipo sull'input, se e solo se cambia la data, ma non lo fa.)
TJ Crowder

67

La risposta di TJ Crowder ( https://stackoverflow.com/a/6471992/481154 ) è molto buona e rimane ancora accurata. L'attivazione dell'evento di modifica all'interno della funzione onSelect è il più vicino possibile.

Tuttavia, esiste una bella proprietà sull'oggetto datepicker ( lastVal) che ti consentirà di attivare condizionalmente l'evento change solo sulle modifiche effettive senza dover memorizzare tu stesso i valori:

$('#dateInput').datepicker({
     onSelect: function(d,i){
          if(d !== i.lastVal){
              $(this).change();
          }
     }
});

Quindi gestisci gli eventi di modifica come al solito:

$('#dateInput').change(function(){
     //Change code!
});

Qualcuno l'ha provato di recente? Non funziona per me. i.lastVal restituisce undefined e non sembra essere una delle proprietà disponibili.
BK,

L'ho appena implementato senza alcun problema. Funziona come un fascino.
DevSlick

questo non funziona più, lastval non è più definito
luke_mclachlan il

4
@luke_mclachlan lastValinvece è ;-)
Alexander Derck il

lastValnon esiste sull'oggetto datepicker, almeno nei miei test. Quindi questa soluzione attiverà sempre il cambiamento.
Nicholas

13

La vostra ricerca del onSelect evento nell'oggetto datepicker:

$('.selector').datepicker({
   onSelect: function(dateText, inst) { ... }
});

11

Ho scritto questo perché avevo bisogno di una soluzione per attivare un evento solo se la data è cambiata.

È una soluzione semplice Ogni volta che la finestra di dialogo viene chiusa, verifichiamo se i dati sono stati modificati. In tal caso, attiviamo un evento personalizzato e ripristiniamo il valore memorizzato.

$('.datetime').datepicker({
    onClose: function(dateText,datePickerInstance) {
        var oldValue = $(this).data('oldValue') || "";
        if (dateText !== oldValue) {
            $(this).data('oldValue',dateText);
            $(this).trigger('dateupdated');
        }
    }
});

Ora possiamo collegare i gestori per quell'evento personalizzato ...

$('body').on('dateupdated','.datetime', function(e) {
    // do something
});

Lo sto usando con knockout, non sono riuscito a far scattare un evento quando l'utente ha eliminato o modificato manualmente la data senza selezionare una data nel selettore. Molto utile.
Tony,

Il mio problema con i campi datepicker jQuery non è esattamente lo stesso di quello pubblicato qui. Si tratta dell'evento di modifica che si attiva più volte. Ho provato diverse soluzioni e questa è l'unica che funziona davvero nella mia situazione.
Patee Gutee,

Ho fatto più o meno lo stesso di questa soluzione e penso che funzioni decisamente meglio.

10
$('#inputfield').change(function() { 
    dosomething();
});

14
Ho pensato che dovrebbe funzionare, ma sfortunatamente no. Viene attivato solo quando il campo viene modificato utilizzando la tastiera , non quando si seleziona dal selettore della data. Fastidioso.
Simon East,

1
Dai documenti dell'interfaccia utente jQuery: "Questo widget manipola il valore del suo elemento a livello di codice, pertanto un evento di modifica nativo potrebbe non essere generato quando il valore dell'elemento cambia."
Sam Kauffman,

La cosa divertente è che sto ottenendo il contrario - quando cambio manualmente l'input tramite tastiera, non viene attivato alcun evento. Ma quando cambio il valore del campo tramite il widget, l'evento change viene generato. Dispari.
Renan,

Funziona bene quando cambio con la tastiera e quando cambio con il widget di selezione della data.
The Sammie,

in qualche modo questo chiama più volte.
NMathur,


4

Su jQueryUi 1.9 sono riuscito a farlo funzionare attraverso un valore di dati aggiuntivo e una combinazione di funzioni beforeShow e onSelect:

$( ".datepicker" ).datepicker({
    beforeShow: function( el ){
        // set the current value before showing the widget
        $(this).data('previous', $(el).val() );
    },

    onSelect: function( newText ){
        // compare the new value to the previous one
        if( $(this).data('previous') != newText ){
            // do whatever has to be done, e.g. log it to console
            console.log( 'changed to: ' + newText );
        }
    }
});

Per me va bene :)


4

So che questa è una vecchia domanda. Ma non sono riuscito a far sì che l'evento jquery $ (this) .change () si attivasse correttamente su Seleziona. Quindi sono andato con il seguente approccio per lanciare l'evento change tramite vanilla js.

$('.date').datepicker({
     showOn: 'focus',
     dateFormat: 'mm-dd-yy',
     changeMonth: true,
     changeYear: true,
     onSelect: function() {
         var event;
         if(typeof window.Event == "function"){
             event = new Event('change');
             this.dispatchEvent(event);
         }   else {
             event = document.createEvent('HTMLEvents');
             event.initEvent('change', false, false);
             this.dispatchEvent(event);
         }
     }
});

L'errore "'$' non è definito" per questo frammento. Uh Oh.
Michael12345,

Stai inviando un evento di modifica nell'evento onSelect che non è l'effetto desiderato dal momento che select verrà attivato ogni volta che viene cliccata una data, ma non significa necessariamente che la data sia stata effettivamente cambiata, ovvero l'utente potrebbe aver fatto clic sulla stessa data due volte.
Jacques,

@Jacques hai ragione. credo che potresti confrontare String dateText con this.value e lanciarlo solo se sono diversi.
tstrand66,

@ Michael12345 capisco cosa intendi. l'ho modificato in modo che non sia più uno snippet. Mie scuse.
tstrand66,

3

Prova questo

$('#dateInput').datepicker({
 onSelect: function(){
       $(this).trigger('change');
      }
 }});

Spero che questo ti aiuti:)


3

Provare :

$('#idPicker').on('changeDate', function() {
    var date = $('#idPicker').datepicker('getFormattedDate');
});

1

Il manuale dice:

apply.daterangepicker: Triggered when the apply button is clicked, or when a predefined range is clicked

Così:

$('#daterange').daterangepicker({
  locale: { cancelLabel: 'Clear' }  
});

$('#daterange').on('apply.daterangepicker', function() {
  alert('worked!');
});

Per me va bene.


1

La mia solitudine:

var $dateInput = $('#dateInput');

$dateInput.datepicker({
    onSelect: function(f,d,i){
        if(d !== i.lastVal){
            $dateInput.trigger("change");
        }
    }
}).data('datepicker');

$dateInput.on("change", function () {
   //your code
});


0

DatePicker ha selezionato il codice evento di modifica del valore di seguito

/* HTML Part */
<p>Date: <input type="text" id="datepicker"></p>

/* jQuery Part */
$("#datepicker").change(function() {
                selectedDate= $('#datepicker').datepicker({ dateFormat: 'yy-mm-dd' }).val();
                alert(selectedDate);        
            });

0

se stai usando wdcalendar questo ti aiuterà

 $("#PatientBirthday").datepicker({ 
        picker: "<button class='calpick'></button>",
        onReturn:function(d){
          var today = new Date();
          var birthDate = d;
          var age = today.getFullYear() - birthDate.getFullYear();
          var m = today.getMonth() - birthDate.getMonth();
          if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
            age--;
          }

          $('#ageshow')[0].innerHTML="Age: "+age;
          $("#PatientBirthday").val((d.getMonth() + 1) + '/' + d.getDate() + '/' +  d.getFullYear());
        }
      }); 

l'evento onReturn funziona per me

spero che questo aiuto


0

Penso che il tuo problema potrebbe risiedere nel modo in cui è impostato il tuo datepicker. Perché non scollegare l'ingresso ... non usare altField. Invece imposta esplicitamente i valori quando viene attivato onSelect. Questo ti darà il controllo di ogni interazione; il campo di testo dell'utente e il datepicker.

Nota: a volte devi chiamare la routine su .change () e non .onSelect () perché onSelect può essere chiamato su interazioni diverse che non ti aspetti.

Codice pseudo:

$('#date').datepicker({
    //altField: , //do not use
    onSelect: function(date){
        $('#date').val(date); //Set my textbox value
        //Do your search routine
    },
}).change(function(){
    //Or do it here...
});

$('#date').change(function(){
    var thisDate = $(this).val();
    if(isValidDate(thisDate)){
        $('#date').datepicker('setDate', thisDate); //Set my datepicker value
        //Do your search routine
    });
});
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.