Проблема события обмена JQuery Datepicker


239

У меня есть код JS, в котором при изменении поля он вызывает процедуру поиска. Проблема в том, что я не могу найти какие-либо события jQuery, которые сработают, когда Datepicker обновит поле ввода.

По какой-то причине событие изменения не вызывается, когда Datepicker обновляет поле. Когда календарь всплывает, он меняет фокус, поэтому я тоже не могу его использовать. Любые идеи?


В итоге я использовал stackoverflow.com/a/30132949/293792, так как это, казалось, прямо ответило на вопрос
twobob

Ответы:


370

Вы можете использовать onSelectсобытие DatePicker .

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

Живой пример :

К сожалению, onSelectсрабатывает каждый раз , когда выбрана дата, даже если она не изменилась. Это недостаток дизайна в средстве выбора даты: он всегда срабатывает onSelect(даже если ничего не изменилось) и не генерирует никаких событий в базовом вводе при изменении. (Если вы посмотрите код этого примера, мы выслушиваем изменения, но они не вызываются.) Вероятно, при возникновении изменений должно возникать событие на входе (возможно, обычное changeсобытие или, возможно, средство выбора даты). конкретный).


Если вам нравится, конечно, вы можете устроить changeмероприятие на inputкостре:

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

Это сработает changeв основе inputдля любого обработчика, подключенного через jQuery. Но опять же, это всегда срабатывает. Если вы хотите использовать только реальные изменения, вам нужно сохранить предыдущее значение (возможно, через data) и сравнить.

Живой пример :


1
@ user760092: Я опубликовал этот ответ, а затем вышел, и буквально, когда я уходил, я подумал: «Вы знаете, вы можете вызвать changeобработчик (и)», и поэтому я обновил ответ этим. :-)
TJ Crowder

1
Я ходил кругами по кругу, пытаясь заставить это работать во всех сценариях, и это было сделано! Очень признателен!
Крис Невилл

7
Почему в мире они не сделали эти реальные события?
Джей К

1
Это для "выбора", а не для "изменения". Если вы выберете дату, а затем повторно выберете ее, это событие будет запущено. Некоторые разработчики захотят узнать, когда дата изменилась с какого-то начального состояния, чтобы узнать, являются ли данные «грязными» и их нужно сохранить. По этой причине я не одобряю вас в этом.
AndroidDev

4
@AndroidDev: я это уточнил. ( Конечно, у вас может быть; цель сайта - получить хорошие ответы ; поощряется уважительное редактирование, чтобы добиться этого.) Это недостаток дизайна в указателе даты, а не в ответе. (То, что он должен сделать, это запустить какое-то событие изменения на входе, если и только если изменение даты, но это не так.)
TJ Crowder

67

Ответ TJ Crowder ( https://stackoverflow.com/a/6471992/481154 ) очень хороший и все еще остается точным. Запуск события изменения в функции onSelect настолько близок, насколько вы собираетесь получить.

Однако в объекте datepicker ( lastVal) есть замечательное свойство , которое позволит вам условно инициировать событие изменения только для реальных изменений, не сохраняя значения самостоятельно:

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

Затем просто обработайте события изменения как обычно:

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

Кто-нибудь проверял это недавно? Это не работает для меня. i.lastVal возвращает неопределенное значение и не является одним из доступных свойств.
БК

Я просто реализовал это без каких-либо проблем. Работает как шарм.
DevSlick

это больше не работает, lastval больше не определяется
luke_mclachlan

4
@luke_mclachlan, lastValоднако, есть ;-)
Александр Дерк

lastValне существует в объекте datepicker, по крайней мере, в моем тестировании. Таким образом, это решение всегда будет вызывать изменения.
Николай


11

Я написал это, потому что мне нужно решение, чтобы вызвать событие, только если дата изменилась.

Это простое решение. Каждый раз, когда диалоговое окно закрывается, мы проверяем, изменились ли данные. Если это так, мы запускаем пользовательское событие и сбрасываем сохраненное значение.

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

Теперь мы можем подключить обработчики для этого пользовательского события ...

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

Я использую это с нокаутом, я не мог заставить его вызвать событие, когда пользователь удалил или вручную изменил дату, не выбирая дату на сборщике. Очень полезно.
Тони

Моя проблема с полями jQuery datepicker не совсем та, что опубликована здесь. Речь идет о событии изменения, которое запускается несколько раз. Я попробовал несколько решений, и это единственное, что действительно работает в моей ситуации.
Patee Gutee

Я сделал более или менее то же самое, что и это решение, и я думаю, что оно определенно работает лучше всего. Я опубликую то, что я сделал в отдельном ответе ...

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

14
Я думал, что это должно работать, но, к сожалению, нет. Он срабатывает только при изменении поля с помощью клавиатуры , а не при выборе из средства выбора даты. Раздражает.
Саймон Ист

1
Из документации по пользовательскому интерфейсу jQuery: «Этот виджет программно управляет значением своего элемента, поэтому событие собственного изменения может не сработать при изменении значения элемента».
Сэм Кауфман

Самое смешное, что я получаю противоположное этому - когда я вручную изменяю ввод с клавиатуры, событие не запускается. Но когда я изменяю значение поля через виджет, событие change срабатывает. Странный.
Ренан

Это прекрасно работает, когда я меняю с клавиатуры и когда я меняю с виджетом выбора даты.
Сэмми

как-то это вызывает несколько раз.
NMathur

9

Я использую bootstrap-datepicker, и ни одно из вышеуказанных решений не помогло мне. Этот ответ помог мне ..

событие изменения даты загрузчика начальной загрузки не запускается при ручном редактировании дат или очистке даты

Вот что я применил:

 $('.date-picker').datepicker({
     endDate: new Date(),
     autoclose: true,
 }).on('changeDate', function(ev){
        //my work here
    });

Надеюсь, что это может помочь другим.


4

На jQueryUi 1.9 мне удалось заставить его работать с помощью дополнительного значения данных и комбинации функций beforeShow и 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 );
        }
    }
});

Работает для меня :)


4

Я знаю, что это старый вопрос. Но я не смог получить событие jquery $ (this) .change () для корректного запуска onSelect. Таким образом, я использовал следующий подход для запуска события изменения через 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);
         }
     }
});

Ошибка «$ не определена» для этого фрагмента. Ооо
Michael12345

Вы отправляете событие изменения в событии onSelect, которое не совсем является желаемым эффектом, так как select будет срабатывать при каждом нажатии на дату, но это не обязательно означает, что дата действительно была изменена, т.е. пользователь мог щелкнуть ту же дату дважды.
Жак

@ Жак, ты прав. Я полагаю, что вы можете сравнить String dateText с this.value и запускать его, только если они разные.
tstrand66

@ Michael12345 я понимаю, что ты имеешь в виду. я изменил его так, чтобы это больше не фрагмент. мои извинения.
tstrand66


3

Пытаться :

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

1

Руководство говорит:

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

Так:

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

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

Работает для меня.


1

Мое решение:

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 выбранный код события изменения значения ниже

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

если вы используете wdcalendar, это поможет вам

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

у меня событие onReturn работает

надеюсь, это поможет


0

Я думаю, что ваша проблема может заключаться в том, как настроен ваш DatePicker. Почему бы вам не отключить вход ... не используйте altField. Вместо этого явно установите значения при срабатывании onSelect. Это даст вам контроль над каждым взаимодействием; текстовое поле пользователя и указатель даты.

Примечание. Иногда вам нужно вызывать подпрограмму для .change (), а не для .onSelect (), потому что onSelect может вызываться для разных взаимодействий, которые вы не ожидаете.

Псевдокод:

$('#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
    });
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.