jQuery Datepicker problem zdarzenia wymiany


239

Mam kod JS, w którym po zmianie pola wywoływana jest procedura wyszukiwania. Problem polega na tym, że nie mogę znaleźć żadnych zdarzeń jQuery, które uruchomią się, gdy Datepicker zaktualizuje pole wejściowe.

Z jakiegoś powodu zdarzenie zmiany nie jest wywoływane, gdy Datepicker aktualizuje pole. Po wyświetleniu kalendarza zmienia się fokus, więc nie mogę z niego korzystać. Jakieś pomysły?


Skończyło się na użyciu stackoverflow.com/a/30132949/293792, ponieważ wydawało się, że bezpośrednio odpowiada na pytanie
twobob

Odpowiedzi:


370

Możesz użyć onSelectzdarzenia datepicker .

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

Przykład na żywo :

Niestety, onSelectodpala po każdym wybraniu daty, nawet jeśli się nie zmieniła. Jest to wada projektowa w datepicker: zawsze uruchamia się onSelect(nawet jeśli nic się nie zmieniło) i nie wywołuje żadnego zdarzenia na podstawie danych wejściowych przy zmianie. (Jeśli spojrzysz na kod z tego przykładu, szukamy zmian, ale nie są one podnoszone.) Prawdopodobnie powinno to wywołać zdarzenie na wejściu, gdy coś się zmieni (być może zwykłe changezdarzenie lub być może datepicker- konkretny).


Jeśli chcesz, możesz oczywiście zrobić changezdarzenie w inputogniu:

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

To uruchomi changebazę inputdla każdego modułu obsługi podłączonego przez jQuery. Ale znowu to zawsze odpala. Jeśli chcesz strzelać tylko na prawdziwą zmianę, musisz zapisać poprzednią wartość (być może poprzez data) i porównać.

Przykład na żywo :


1
@ user760092: Wysłałem tę odpowiedź, a potem wyszedłem i dosłownie wychodząc pomyślałem: „Wiesz, możesz uruchomić program changeobsługi” i dlatego zaktualizowałem odpowiedź. :-)
TJ Crowder

1
Krążyłem w kółko, próbując sprawić, by zadziałało we wszystkich scenariuszach i już to zrobiłem! Bardzo mile widziane!
Chris Nevill

7
Dlaczego na świecie nie zrobili tych faktycznych wydarzeń?
Jay K,

1
Służy do „wybierania”, a NIE do „zmiany”. Jeśli wybierzesz datę, a następnie wybierzesz ją ponownie, wydarzenie zostanie uruchomione. Niektórzy programiści chcą wiedzieć, kiedy data zmieniła się z pewnego stanu początkowego, aby wiedzieć, czy dane są „brudne” i należy je zapisać. Z tego powodu głosuję cię w tej sprawie.
AndroidDev

4
@AndroidDev: Wyjaśniłem to. ( Oczywiście możesz mieć; celem witryny jest uzyskanie dobrych odpowiedzi ; zachęcamy do szacunkowej edycji, aby to osiągnąć.) Jest to błąd projektowy w narzędziu do wyboru dat, a nie w odpowiedzi. (To, co powinien zrobić, to uruchomić jakieś zdarzenie zmiany na wejściu, jeśli i tylko przy zmianie daty, ale tak nie jest.)
TJ Crowder

67

Odpowiedź TJ Crowdera ( https://stackoverflow.com/a/6471992/481154 ) jest bardzo dobra i nadal pozostaje dokładna. Wywołanie zdarzenia zmiany w funkcji onSelect jest tak blisko, jak to tylko możliwe.

Istnieje jednak ładna właściwość obiektu datepicker ( lastVal), która pozwoli warunkowo wywołać zdarzenie zmiany tylko w przypadku rzeczywistych zmian bez konieczności samodzielnego przechowywania wartości (wartości):

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

Następnie po prostu obsługuj zdarzenia zmiany jak normalnie:

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

Czy ktoś to ostatnio testował? To nie działa dla mnie. i.lastVal zwraca wartość niezdefiniowaną i nie wydaje się być jedną z dostępnych właściwości.
BK

Właśnie zaimplementowałem to bez żadnego problemu. Działa jak marzenie.
DevSlick

to już nie działa, lastval nie jest już zdefiniowany
luke_mclachlan

4
@luke_mclachlan lastValjest jednak ;-)
Alexander Derck

lastValnie istnieje na obiekcie datepicker, przynajmniej w moich testach. To rozwiązanie zawsze wywoła zmianę.
Nicholas

13

Twój szuka onSelect imprezy w obiekcie datepicker:

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

11

Napisałem to, ponieważ potrzebowałem rozwiązania, aby wywołać zdarzenie tylko w przypadku zmiany daty.

To proste rozwiązanie. Za każdym razem, gdy okno dialogowe się zamyka, testujemy, czy dane się zmieniły. Jeśli tak, uruchamiamy niestandardowe zdarzenie i resetujemy zapisaną wartość.

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

Teraz możemy podłączyć moduły obsługi tego niestandardowego zdarzenia ...

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

Używam tego z nokautem, nie mogłem zmusić go do wywołania zdarzenia, gdy użytkownik usunął lub ręcznie zmienił datę bez wybrania daty w selektorze. Bardzo pomocne.
Tony,

Mój problem z polami datepicker jQuery nie jest dokładnie taki sam jak ten opublikowany tutaj. Chodzi o wielokrotne uruchomienie zdarzenia zmiany. Wypróbowałem kilka rozwiązań i to jedyne, które faktycznie działa w mojej sytuacji.
Patee Gutee,

Zrobiłem mniej więcej to samo co to rozwiązanie i myślę, że zdecydowanie działa najlepiej.

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

14
Myślałem, że to powinno działać, ale niestety nie. Jest on uruchamiany tylko wtedy, gdy pole jest zmieniane za pomocą klawiatury , a nie podczas wybierania z selektora dat. Denerwujący.
Simon East

1
Z dokumentów interfejsu użytkownika jQuery: „Ten widget programowo manipuluje wartością swojego elementu, dlatego natywne zdarzenie zmiany może nie zostać wywołane, gdy zmienia się wartość elementu”.
Sam Kauffman

Zabawne jest to, że dostaję coś przeciwnego - kiedy zmieniam dane ręcznie za pomocą klawiatury, żadne zdarzenie nie jest wywoływane. Ale kiedy zmieniam wartość pola za pomocą widgetu, zdarzenie zmiany zostaje uruchomione. Dziwny.
Renan

Działa to dobrze, gdy zmieniam za pomocą klawiatury i kiedy zmieniam za pomocą widgetu wyboru daty.
The Sammie,

jakoś to wywołuje wiele razy.
NMathur


4

W jQueryUi 1.9 udało mi się sprawić, aby działał poprzez dodatkową wartość danych oraz kombinację funkcji beforeShow i 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 );
        }
    }
});

Pracuje dla mnie :)


4

Wiem, że to stare pytanie. Ale nie mogłem pobrać zdarzenia jquery $ (this) .change (), aby poprawnie uruchomić onSelect. Więc zastosowałem następujące podejście do uruchomienia zdarzenia zmiany za pośrednictwem waniliowej wersji 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);
         }
     }
});

Błąd „„ $ ”jest niezdefiniowany” dla tego fragmentu. O o.
Michael12345

Wywołujesz zdarzenie zmiany w zdarzeniu onSelect, co nie jest do końca pożądanym efektem, ponieważ select będzie uruchamiany przy każdym kliknięciu daty, ale nie musi to oznaczać, że data została faktycznie zmieniona, tj. Użytkownik mógł kliknąć tę samą datę dwa razy.
Jacques

@Jacques masz rację. Wierzę, że możesz porównać String dateText do this.value i odpalić to tylko, jeśli są różne.
tstrand66

@ Michael12345 Rozumiem, co masz na myśli. zmodyfikowałem go tak, aby nie był już fragmentem kodu. przepraszam.
tstrand66

3

Spróbuj tego

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

Mam nadzieję że to pomoże:)


3

Próbować :

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

1

Podręcznik mówi:

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

Więc:

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

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

Pracuje dla mnie.


1

Moje rozwiązanie:

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 zaznaczony kod zdarzenia zmiany wartości poniżej

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

jeśli używasz wdcalendar, to ci pomoże

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

Wydarzenie onReturn działa dla mnie

Mam nadzieję, że to pomoże


0

Myślę, że twój problem może polegać na konfiguracji selektora dat. Dlaczego nie odłączysz wejścia ... nie używaj altField. Zamiast tego jawnie ustaw wartości podczas uruchamiania onSelect. To da ci kontrolę nad każdą interakcją; pole tekstowe użytkownika i datepicker.

Uwaga: Czasami musisz wywołać procedurę na .change (), a nie na .onSelect (), ponieważ onSelect można wywoływać przy różnych interakcjach, których się nie spodziewasz.

Pseudo kod:

$('#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
    });
});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.