Problema de evento de cambio de jQuery Datepicker

239

Tengo un código JS en el que cuando cambias un campo llama a una rutina de búsqueda. El problema es que no puedo encontrar ningún evento jQuery que se active cuando Datepicker actualiza el campo de entrada.

Por alguna razón, no se llama a un evento de cambio cuando Datepicker actualiza el campo. Cuando aparece el calendario, cambia el enfoque, así que tampoco puedo usarlo. ¿Algunas ideas?

zbestzeus
fuente
Terminé usando stackoverflow.com/a/30132949/293792 ya que esto parecía responder directamente a la pregunta
twobob

Respuestas:

370

Puedes usar el onSelectevento datepicker .

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

Ejemplo en vivo :

Desafortunadamente, se onSelectdispara cada vez que se selecciona una fecha, incluso si no ha cambiado. Esta es una falla de diseño en el selector de fechas: siempre se dispara onSelect(incluso si nada ha cambiado), y no dispara ningún evento en la entrada subyacente en el cambio. (Si observa el código de ese ejemplo, estamos escuchando los cambios, pero no se están generando). Probablemente debería disparar un evento en la entrada cuando las cosas cambian (posiblemente el changeevento habitual , o posiblemente un selector de fecha- uno específico).


Si lo desea, por supuesto, puede hacer que el changeevento en el inputfuego:

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

Eso se disparará changeen el subyacente inputpara cualquier controlador conectado a través de jQuery. Pero de nuevo, siempre lo dispara. Si solo desea activar un cambio real, deberá guardar el valor anterior (posiblemente a través de data) y comparar.

Ejemplo en vivo :

TJ Crowder
fuente
1
@ user760092: publiqué esta respuesta y luego salí, y literalmente cuando me iba pensé "Sabes, podrías activar los changemanejadores" y actualicé la respuesta con eso. :-)
TJ Crowder
1
¡He dado vueltas y vueltas en círculos tratando de hacer que esto funcione en todos los escenarios y esto lo ha logrado! ¡Muy apreciado!
Chris Nevill
77
¿Por qué en el mundo no hicieron esos eventos reales?
Jay K
1
Esto es para "seleccionar" y NO para "cambiar". Si selecciona una fecha y luego la vuelve a seleccionar, se activará este evento. Algunos desarrolladores querrán saber cuándo una fecha ha cambiado desde un estado inicial para saber si los datos están "sucios" y si deben guardarse. Por esta razón, te estoy rechazando por esto.
AndroidDev
44
@AndroidDev: lo he aclarado. ( Usted podría tener, por supuesto, el objetivo del sitio es tener buenas respuestas ; edición respetuosa para lograr que se anima.) Es un defecto de diseño en el selector de fechas, no en la respuesta. (Lo que debería hacer es activar un evento de cambio de algún tipo en la entrada, si y solo si cambia la fecha, pero no lo hace).
TJ Crowder
67

La respuesta de TJ Crowder ( https://stackoverflow.com/a/6471992/481154 ) es muy buena y sigue siendo precisa. Activar el evento de cambio dentro de la función onSelect es lo más cercano que va a llegar.

Sin embargo, hay una buena propiedad en el objeto datepicker ( lastVal) que le permitirá activar condicionalmente el evento de cambio solo en cambios reales sin tener que almacenar los valores usted mismo:

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

Luego solo maneje los eventos de cambio como lo normal:

$('#dateInput').change(function(){
     //Change code!
});
theChrisKent
fuente
¿Alguien ha probado esto recientemente? A mi no me funciona. i.lastVal devuelve indefinido y no parece ser una de las propiedades disponibles.
BK
Acabo de implementar esto sin ningún problema. Funciona de maravilla.
DevSlick
esto ya no funciona, lastval ya no está definido
luke_mclachlan
44
@luke_mclachlan lastValsin embargo es ;-)
Alexander Derck
lastValno existe en el objeto datepicker, al menos en mis pruebas. Entonces esta solución siempre activará el cambio.
Nicholas
13

Está buscando el evento onSelect en el objeto datepicker:

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

Escribí esto porque necesitaba una solución para activar un evento solo si la fecha cambiaba.

Es una solución simple. Cada vez que se cierra el cuadro de diálogo, probamos para ver si los datos han cambiado. Si es así, activamos un evento personalizado y restablecemos el valor almacenado.

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

Ahora podemos conectar controladores para ese evento personalizado ...

$('body').on('dateupdated','.datetime', function(e) {
    // do something
});
CodeDreamer68
fuente
Estoy usando esto con knockout, no pude lograr que desencadene un evento cuando el usuario eliminó o cambió manualmente la fecha sin seleccionar una fecha en el selector. Muy útil.
Tony
Mi problema con los campos jQuery datepicker no es exactamente el mismo que el publicado aquí. Se trata del evento de cambio que se dispara varias veces. Intenté varias soluciones y esta es la única que realmente funciona en mi situación.
Patee Gutee
Hice más o menos lo mismo que esta solución y creo que definitivamente funciona mejor. Voy a publicar lo que hice en una respuesta por separado ...
10
$('#inputfield').change(function() { 
    dosomething();
});
usuario583576
fuente
14
Pensé que esto debería funcionar, pero desafortunadamente no. Solo se activa cuando el campo se cambia usando el teclado , no cuando se selecciona desde el selector de fechas. Molesto.
Simon East
1
De los documentos de jQuery UI: "Este widget manipula el valor de su elemento mediante programación, por lo tanto, un evento de cambio nativo no puede activarse cuando el valor del elemento cambia".
Sam Kauffman
Lo curioso es que obtengo lo contrario de eso: cuando cambio la entrada a mano con el teclado, no se activa ningún evento. Pero cuando cambio el valor del campo a través del widget, se activa el evento de cambio. Impar.
Renan
Esto funciona bien cuando cambio con el teclado y cuando cambio con el widget selector de fecha.
The Sammie
de alguna manera esto llama varias veces.
NMathur
4

En jQueryUi 1.9 he logrado que funcione a través de un valor de datos adicional y una combinación de las funciones beforeShow y 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 );
        }
    }
});

Funciona para mi :)

buscando
fuente
4

Sé que esta es una vieja pregunta. Pero no pude hacer que el evento jquery $ (this) .change () se active correctamente en Select. Así que seguí el siguiente enfoque para activar el evento de cambio a través de 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);
         }
     }
});
tstrand66
fuente
Error "'$' no está definido" para este fragmento. UH oh.
Michael12345
Está enviando un evento de cambio en el evento onSelect que no es el efecto deseado, ya que select se activará cada vez que se hace clic en una fecha, pero no necesariamente significa que la fecha realmente se cambió, es decir, el usuario podría haber hecho clic en la misma fecha dos veces.
Jacques
@Jacques tienes razón. creo que podría comparar String dateText con this.value y solo activar esto si son diferentes.
tstrand66
@ Michael12345 veo a qué te refieres. Lo he modificado para que ya no sea un fragmento. mis disculpas.
tstrand66
3

Prueba esto

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

Espero que esto ayude:)

mike tracker
fuente
3

Tratar :

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

El manual dice:

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

Entonces:

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

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

Funciona para mi.

Sam
fuente
1

Mi soluthion:

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
});
Andriy Petrusha
fuente
1

Mi solución es:

events: {
    'apply.daterangepicker #selector': 'function'
}
Daniel Ortegón
fuente
0

Código de evento de cambio de valor seleccionado de DatePicker a continuación

/* 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);        
            });
Hemang Rami
fuente
0

si estás usando wdcalendar esto te ayudará

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

el evento onReturn me funciona

espero que esto ayude

mavirroco
fuente
0

Creo que su problema puede estar en cómo se configura su selector de fechas. ¿Por qué no desconecta la entrada? No use altField. En su lugar, establezca explícitamente los valores cuando se active onSelect. Esto te dará el control de cada interacción; el campo de texto del usuario y el selector de fecha.

Nota: a veces debe llamar a la rutina en .change () y no en .onSelect () porque onSelect se puede invocar en diferentes interacciones que no espera.

Pseudocódigo:

$('#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
    });
});
Jeremy
fuente