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?

zbestzeus
źródło
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 :

TJ Crowder
źródło
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!
});
theChrisKent
źródło
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) { ... }
});
locrizak
źródło
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
});
CodeDreamer68
źródło
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();
});
użytkownik583576
źródło
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 :)

poszukiwanie
źródło
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);
         }
     }
});
tstrand66
źródło
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:)

Mike Tracker
źródło
3

Próbować :

$('#idPicker').on('changeDate', function() {
    var date = $('#idPicker').datepicker('getFormattedDate');
});
GiorgosBarkos
źródło
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.

Sam
źródło
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
});
Andrij Petrusha
źródło
1

Moje rozwiązanie to:

events: {
    'apply.daterangepicker #selector': 'function'
}
Daniel Ortegón
źródło
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);        
            });
Hemang Rami
źródło
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

mavirroco
źródło
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
    });
});
Jeremy
źródło