Problema no evento do jQuery Datepicker onchange


239

Eu tenho um código JS no qual, quando você altera um campo, ele chama uma rotina de pesquisa. O problema é que não consigo encontrar nenhum evento jQuery que será acionado quando o Datepicker atualizar o campo de entrada.

Por algum motivo, um evento de alteração não é chamado quando o Datepicker atualiza o campo. Quando o calendário aparece, ele muda o foco, então também não posso usá-lo. Alguma ideia?


Acabei usando stackoverflow.com/a/30132949/293792 desde que este apareceu para responder diretamente a pergunta
twobob

Respostas:


370

Você pode usar o onSelectevento do datepicker .

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

Exemplo ao vivo :

Infelizmente, é onSelectacionado sempre que uma data é selecionada, mesmo que não tenha sido alterada. Essa é uma falha de design no datepicker: sempre é acionada onSelect(mesmo que nada tenha sido alterado) e não dispara nenhum evento na entrada subjacente na alteração. (Se você procurar no código desse exemplo, estamos ouvindo as alterações, mas elas não estão sendo levantadas.) Provavelmente, deve disparar um evento na entrada quando as coisas mudarem (possivelmente o changeevento usual ou possivelmente um datepicker- específico).


Se você quiser, é claro, pode fazer o changeevento pegar inputfogo:

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

Isso será acionado changeno subjacente inputpara qualquer manipulador conectado via jQuery. Mas, novamente, sempre dispara. Se você deseja acionar apenas uma alteração real, precisará salvar o valor anterior (possivelmente via data) e comparar.

Exemplo ao vivo :


1
@ user760092: Eu postei esta resposta e saí, e literalmente quando eu estava saindo, pensei "Sabe, você poderia acionar o change(s) manipulador (es)" e, portanto, atualizei a resposta com isso. :-)
TJ Crowder

1
Eu andei repetidamente em círculos tentando fazer com que isso funcionasse em todos os cenários e isso foi feito! Muito apreciado!
precisa

7
Por que eles não fizeram esses eventos reais?
Jay K

1
Isto é para "selecionar" e NÃO para "alterar". Se você selecionar uma data e depois selecioná-la novamente, esse evento será disparado. Alguns desenvolvedores desejam saber quando uma data mudou de algum estado inicial para saber se os dados estão "sujos" e precisam ser salvos. Por esse motivo, estou votando contra você nisso.
precisa saber é o seguinte

4
@AndroidDev: Eu esclareci isso. ( É claro que você poderia ter; o objetivo do site é ter boas respostas ; editar respeitosamente para conseguir isso é incentivado.) É uma falha de design no selecionador de datas, não na resposta. (O que ele deve fazer é disparar um evento de alteração de algum tipo na entrada, se e somente se alterar a data, mas não funciona.)
TJ Crowder

67

A resposta de TJ Crowder ( https://stackoverflow.com/a/6471992/481154 ) é muito boa e ainda permanece precisa. O acionamento do evento de alteração na função onSelect é o mais próximo possível.

No entanto, existe uma boa propriedade no objeto datepicker ( lastVal) que permitirá que você acione condicionalmente o evento de alteração apenas em alterações reais sem precisar armazenar os valores:

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

Em seguida, basta manipular eventos de alteração como normal:

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

Alguém testou isso recentemente? Isso não funciona para mim. i.lastVal retorna indefinido e não parece ser uma das propriedades disponíveis.
BK

Acabei de implementar isso sem nenhum problema. Funciona como um encanto.
DevSlick

isso não funciona mais, lastval não está mais definido #
luke_mclachlan

4
@luke_mclachlan lastVal, porém, é ;-)
Alexander Derck

lastValnão existe no objeto datepicker, pelo menos nos meus testes. Portanto, essa solução sempre acionará a alteração.
19318 Nicholas

13

Você está procurando o evento onSelect no objeto datepicker:

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

11

Escrevi isso porque precisava de uma solução para acionar um evento apenas se a data fosse alterada.

É uma solução simples. Cada vez que a caixa de diálogo é fechada, testamos para ver se os dados foram alterados. Se houver, acionamos um evento personalizado e redefinimos o valor armazenado.

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

Agora podemos conectar manipuladores para esse evento personalizado ...

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

Estou usando isso com nocaute, não consegui acionar um evento quando o usuário excluiu ou alterou manualmente a data sem selecionar uma data no seletor. Muito útil.
Tony

Meu problema com os campos datepicker do jQuery não é exatamente o mesmo que foi postado aqui. É sobre o evento de alteração disparado várias vezes. Tentei várias soluções e esta é a única que realmente funciona na minha situação.
Patee Gutee

Fiz mais ou menos o mesmo que esta solução e acho que definitivamente funciona melhor. Vou postar o que eu fiz em uma resposta em separado ...

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

14
Eu pensei que isso deveria funcionar, mas infelizmente não. É acionado apenas quando o campo é alterado usando o teclado , não ao selecionar no selecionador de data. Irritante.
Simon East

1
Nos documentos da interface do usuário do jQuery: "Este widget manipula o valor de seu elemento programaticamente, portanto, um evento de alteração nativo pode não ser acionado quando o valor do elemento é alterado."
Sam Kauffman

O engraçado é que estou tendo o oposto disso - quando altero a entrada manualmente via teclado, nenhum evento é acionado. Mas quando altero o valor do campo por meio do widget, o evento de alteração é acionado. Ímpar.
Renan

Isso funciona bem quando troco com o teclado e quando troco com o widget do seletor de datas.
The Sammie

de alguma forma, isso chama várias vezes.
28417 NMathur


4

No jQueryUi 1.9, consegui fazê-lo funcionar com um valor de dados adicional e uma combinação das funções 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 );
        }
    }
});

Funciona para mim :)


4

Eu sei que esta é uma pergunta antiga. Mas não foi possível obter o evento jquery $ (this) .change () para disparar corretamente em Select. Então, eu fui com a seguinte abordagem para disparar o evento de mudança 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);
         }
     }
});

O erro "'$' está indefinido" para este snippet. Ah, oh.
precisa

Você está despachando um evento de alteração no evento onSelect, que não é o efeito desejado, pois a seleção é acionada toda vez que uma data é clicada, mas isso não significa necessariamente que a data foi realmente alterada, ou seja, o usuário pode ter clicado na mesma data duas vezes.
27419 Jacques

@ Jacques você está correto. Eu acredito que você poderia comparar String dateText para this.value e apenas disparar isso se eles forem diferentes.
Tstrand66 18/05/19

@ Michael12345 vejo o que você quer dizer. Eu o modifiquei para que não seja mais um trecho. me desculpe.
Tstrand66 18/05/19

3

Tente isto

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

Espero que isto ajude:)


3

Experimentar :

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

1

O manual diz:

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

Assim:

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

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

Funciona para mim.


1

Minha solução:

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

Código de evento de alteração de valor selecionado pelo DatePicker abaixo

/* 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 você estiver usando wdcalendar, isso ajudará você

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

o evento onReturn funciona para mim

espero que isso ajude


0

Acho que seu problema pode estar na forma como o datepicker está configurado. Por que você não desconecta a entrada ... não use altField. Em vez disso, defina explicitamente os valores quando o onSelect for acionado. Isso lhe dará controle de cada interação; o campo de texto do usuário e o selecionador de data.

Nota: Às vezes, é necessário chamar a rotina em .change () e não em .onSelect () porque onSelect pode ser chamado em diferentes interações que você não espera.

Pseudo-có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
    });
});
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.