Problème d'événement jQuery Datepicker onchange


239

J'ai un code JS dans lequel lorsque vous modifiez un champ, il appelle une routine de recherche. Le problème est que je ne trouve aucun événement jQuery qui se déclenche lorsque le Datepicker met à jour le champ de saisie.

Pour une raison quelconque, un événement de modification n'est pas appelé lorsque Datepicker met à jour le champ. Lorsque le calendrier apparaît, il change le focus, donc je ne peux pas l'utiliser non plus. Des idées?


J'ai fini par utiliser stackoverflow.com/a/30132949/293792 car cela semblait répondre directement à la question
twobob

Réponses:


370

Vous pouvez utiliser le datepicker onSelectévénement .

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

Exemple en direct :

Malheureusement, il se onSelectdéclenche chaque fois qu'une date est sélectionnée, même si elle n'a pas changé. Il s'agit d'un défaut de conception dans le sélecteur de date: il se déclenche toujours onSelect(même si rien n'a changé) et ne déclenche aucun événement sur l'entrée sous-jacente au changement. (Si vous regardez dans le code de cet exemple, nous écoutons les changements, mais ils ne sont pas déclenchés.) Il devrait probablement déclencher un événement sur l'entrée lorsque les choses changent (éventuellement l' changeévénement habituel , ou éventuellement un sélecteur de date) spécifique).


Si vous le souhaitez, bien sûr, vous pouvez faire l' changeévénement sur le inputfeu:

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

Cela se déclenchera changesur le sous-jacent inputpour tout gestionnaire connecté via jQuery. Mais encore une fois, il le déclenche toujours . Si vous ne souhaitez tirer que sur un changement réel, vous devrez enregistrer la valeur précédente (éventuellement via data) et comparer.

Exemple en direct :


1
@ user760092: J'ai posté cette réponse, puis je suis sorti, et littéralement, comme je partais, j'ai pensé "Vous savez, vous pourriez déclencher le change(s) gestionnaire (s)" et j'ai donc mis à jour la réponse avec cela. :-)
TJ Crowder

1
J'ai tourné en rond en essayant d'aller faire fonctionner cela dans tous les scénarios et cela l'a fait! Très appréciée!
Chris Nevill

7
Pourquoi diable n'ont-ils pas fait ces événements réels?
Jay K

1
C'est pour "sélectionner" et PAS pour "changer". Si vous sélectionnez une date, puis la resélectionnez, cet événement est déclenché. Certains développeurs voudront savoir quand une date est passée d'un état initial pour savoir si les données sont "sales" et doivent être enregistrées. Pour cette raison, je vous vote à ce sujet.
AndroidDev

4
@AndroidDev: J'ai clarifié cela. ( Vous pourriez avoir, bien sûr; le but du site est d'avoir de bonnes réponses ; une édition respectueuse pour y parvenir est encouragée.) C'est un défaut de conception dans le sélecteur de date, pas dans la réponse. (Ce qu'il doit faire, c'est déclencher un événement de modification d'une certaine sorte sur l'entrée, si et seulement si vous changez la date, mais ce n'est pas le cas.)
TJ Crowder

67

La réponse de TJ Crowder ( https://stackoverflow.com/a/6471992/481154 ) est très bonne et reste toujours exacte. Déclencher l'événement change dans la fonction onSelect est aussi proche que possible.

Cependant, il existe une belle propriété sur l'objet datepicker ( lastVal) qui vous permettra de déclencher conditionnellement l'événement de modification uniquement sur les modifications réelles sans avoir à stocker vous-même la ou les valeurs:

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

Ensuite, gérez simplement les événements de changement comme d'habitude:

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

Quelqu'un l'a-t-il testé récemment? Ça ne marche pas pour moi. i.lastVal renvoie undefined et il ne semble pas être l'une des propriétés disponibles.
BK

Je viens de l'implémenter sans aucun problème. Fonctionne comme un charme.
DevSlick

cela ne fonctionne plus, lastval n'est plus défini
luke_mclachlan

4
@luke_mclachlan lastValest cependant ;-)
Alexander Derck

lastValn'existe pas sur l'objet datepicker, du moins dans mes tests. Cette solution déclenchera donc toujours le changement.
Nicholas

13

Votre recherche de l' événement onSelect dans l'objet datepicker:

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

11

J'ai écrit cela parce que j'avais besoin d'une solution pour déclencher un événement uniquement si la date changeait.

C'est une solution simple. Chaque fois que la boîte de dialogue se ferme, nous testons pour voir si les données ont changé. Si c'est le cas, nous déclenchons un événement personnalisé et réinitialisons la valeur stockée.

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

Nous pouvons maintenant connecter des gestionnaires pour cet événement personnalisé ...

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

J'utilise ceci avec knockout, je n'ai pas pu l'obtenir pour déclencher un événement lorsque l'utilisateur a supprimé ou modifié manuellement la date sans sélectionner de date dans le sélecteur. Très utile.
Tony

Mon problème avec les champs jQuery datepicker n'est pas exactement le même que celui publié ici. Il s'agit de l'événement de changement qui se déclenche plusieurs fois. J'ai essayé plusieurs solutions et c'est la seule qui fonctionne réellement dans ma situation.
Patee Gutee

J'ai fait plus ou moins la même chose que cette solution et je pense qu'elle fonctionne certainement le mieux. Je publierai ce que j'ai fait dans une réponse séparée ...

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

14
Je pensais que cela devrait fonctionner, mais malheureusement pas. Il n'est déclenché que lorsque le champ est modifié à l'aide du clavier , pas lors de la sélection dans le sélecteur de date. Énervant.
Simon East

1
À partir des documents de l'interface utilisateur jQuery: "Ce widget manipule la valeur de son élément par programme, par conséquent, un événement de modification natif ne peut pas être déclenché lorsque la valeur de l'élément change."
Sam Kauffman

Le plus drôle, c'est que j'obtiens le contraire - lorsque je modifie l'entrée à la main via le clavier, aucun événement n'est déclenché. Mais lorsque je modifie la valeur du champ via le widget, l'événement change est déclenché. Impair.
Renan

Cela fonctionne bien lorsque je change avec le clavier et lorsque je change avec le widget de sélection de date.
The Sammie

en quelque sorte, cela appelle plusieurs fois.
NMathur


4

Sur jQueryUi 1.9, j'ai réussi à le faire fonctionner grâce à une valeur de données supplémentaire et une combinaison de fonctions beforeShow et 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 );
        }
    }
});

Travaille pour moi :)


4

Je sais que c'est une vieille question. Mais je n'ai pas pu obtenir l'événement jquery $ (this) .change () pour qu'il se déclenche correctement surSelect. J'ai donc opté pour l'approche suivante pour déclencher l'événement de changement via 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'erreur "'$' n'est pas définie" pour cet extrait de code. Euh oh.
Michael12345

Vous distribuez un événement change dans l'événement onSelect qui n'est pas tout à fait l'effet souhaité, car select se déclenche chaque fois qu'une date est cliquée, mais cela ne signifie pas nécessairement que la date a réellement été modifiée, c'est-à-dire que l'utilisateur a peut-être cliqué sur la même date deux fois.
Jacques

@Jacques vous avez raison. je crois que vous pouvez comparer String dateText à this.value et ne déclencher cela que s'ils sont différents.
tstrand66

@ Michael12345 je vois ce que tu veux dire. je l'ai modifié pour que ce ne soit plus un extrait. mes excuses.
tstrand66

3

Essaye ça

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

J'espère que cela t'aides:)


3

Essayez:

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

1

Le manuel dit:

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

Alors:

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

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

Travaille pour moi.


1

Mon 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
});


0

Code d'événement de changement de valeur sélectionné par DatePicker ci-dessous

/* 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

si vous utilisez wdcalendar, cela va vous aider

 $("#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'événement onReturn fonctionne pour moi

j'espère que cette aide


0

Je pense que votre problème peut résider dans la configuration de votre datepicker. Pourquoi ne déconnectez-vous pas l'entrée ... n'utilisez pas altField. Au lieu de cela, définissez explicitement les valeurs lorsque onSelect se déclenche. Cela vous donnera le contrôle de chaque interaction; le champ de texte utilisateur et le sélecteur de date.

Remarque: Parfois, vous devez appeler la routine sur .change () et non sur .onSelect () car onSelect peut être appelé sur différentes interactions auxquelles vous ne vous attendez pas.

Pseudo code:

$('#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
    });
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.