Vấn đề về sự kiện trao đổi ngày của jQuery


238

Tôi có một mã JS trong đó khi bạn thay đổi một trường, nó gọi một thói quen tìm kiếm. Vấn đề là tôi không thể tìm thấy bất kỳ sự kiện jQuery nào sẽ kích hoạt khi Datepicker cập nhật trường đầu vào.

Vì một số lý do, một sự kiện thay đổi không được gọi khi Datepicker cập nhật trường. Khi lịch bật lên, nó sẽ thay đổi trọng tâm vì vậy tôi cũng không thể sử dụng nó. Có ý kiến ​​gì không?


Tôi đã kết thúc bằng stackoverflow.com/a/30132949/293792 vì điều này dường như trả lời trực tiếp câu hỏi
Twobob

Câu trả lời:


369

Bạn có thể sử dụng onSelectsự kiện hẹn hò .

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

Ví dụ trực tiếp :

Thật không may, onSelectbắn bất cứ khi nào một ngày được chọn, ngay cả khi nó không thay đổi. Đây là một lỗ hổng thiết kế trong công cụ hẹn hò: Nó luôn kích hoạt onSelect(ngay cả khi không có gì thay đổi) và không kích hoạt bất kỳ sự kiện nào trên đầu vào cơ bản khi thay đổi. (Nếu bạn nhìn vào đoạn code ví dụ đó, chúng tôi đang lắng nghe những thay đổi, nhưng họ không được nâng lên.) Nó có lẽ nên bắn một sự kiện vào đầu vào khi mọi thứ thay đổi (có thể là thông thường changesự kiện, hoặc có thể là một datepicker- cụ thể một).


Nếu bạn thích, tất nhiên, bạn có thể làm cho changesự kiện này inputbùng cháy:

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

Điều đó sẽ kích changehoạt cơ bản inputcho bất kỳ trình xử lý nào được nối thông qua jQuery. Nhưng một lần nữa, nó luôn bắn nó. Nếu bạn chỉ muốn thực hiện một thay đổi thực sự, bạn sẽ phải lưu giá trị trước đó (có thể thông qua data) và so sánh.

Ví dụ trực tiếp :


1
@ user760092: Tôi đã đăng câu trả lời này và sau đó đi ra ngoài, và theo nghĩa đen khi tôi rời đi, tôi nghĩ rằng "Bạn biết đấy, bạn có thể kích hoạt change(các) người xử lý" và vì vậy tôi đã cập nhật câu trả lời với điều đó. :-)
TJ Crowder

1
Tôi đã đi vòng tròn trong vòng tròn cố gắng để làm cho điều này hoạt động trong tất cả các kịch bản và điều này đã làm điều đó! Nhiều đánh giá cao!
Chris Nevill

7
Tại sao trên thế giới họ không thực hiện những sự kiện thực tế đó?
Jay K

1
Đây là để "chọn" và KHÔNG cho "thay đổi". Nếu bạn chọn một ngày và sau đó chọn lại, sự kiện này sẽ được kích hoạt. Một số nhà phát triển sẽ muốn biết khi nào một ngày đã thay đổi từ một số trạng thái ban đầu để biết liệu dữ liệu có "bẩn" hay không và cần được lưu lại. Vì lý do này, tôi đánh giá thấp bạn về điều này.
AndroidDev

4
@AndroidDev: Tôi đã làm rõ điều đó. (Tất nhiên, bạn có thể có, mục tiêu của trang web là có câu trả lời tốt ; chỉnh sửa tôn trọng để đạt được điều đó được khuyến khích.) Đó là một lỗ hổng thiết kế trong công cụ hẹn hò, không phải trong câu trả lời. (Những gì cần làm là thực hiện một sự kiện thay đổi nào đó trên đầu vào, nếu và chỉ khi thay đổi ngày, nhưng không.)
TJ Crowder

67

Câu trả lời của TJ Crowder ( https://stackoverflow.com/a/6471992/481154 ) là rất tốt và vẫn chính xác.Kích hoạt sự kiện thay đổi trong chức năng onSelect cũng gần như bạn sẽ nhận được.

Tuy nhiên, có một thuộc tính đẹp trên đối tượng datepicker ( lastVal) sẽ cho phép bạn kích hoạt có điều kiện sự kiện thay đổi chỉ trên các thay đổi thực tế mà không phải tự lưu trữ giá trị:

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

Sau đó, chỉ cần xử lý các sự kiện thay đổi như bình thường:

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

Có ai đã thử nghiệm điều này gần đây? Nó không làm việc cho tôi. i.lastVal trả về không xác định và nó dường như không phải là một trong những thuộc tính có sẵn.
BK

Tôi chỉ thực hiện điều này mà không có vấn đề gì cả. Hoạt động như một lá bùa.
DevSlick

điều này không còn hoạt động nữa, Lastval không còn được xác định
luke_mclachlan

4
@luke_mclachlan lastValtuy nhiên là ;-)
Alexander Derck

lastValkhông tồn tại trên đối tượng datepicker, ít nhất là trong thử nghiệm của tôi. Vì vậy, giải pháp này sẽ luôn luôn kích hoạt sự thay đổi.
Nicholas

13

Bạn đang tìm kiếm sự kiện onSelect trong đối tượng datepicker:

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

11

Tôi đã viết điều này bởi vì tôi cần một giải pháp để kích hoạt một sự kiện chỉ khi ngày thay đổi.

Đó là một giải pháp đơn giản. Mỗi lần hộp thoại đóng lại, chúng tôi sẽ kiểm tra xem dữ liệu đã thay đổi chưa. Nếu có, chúng tôi kích hoạt một sự kiện tùy chỉnh và đặt lại giá trị được lưu trữ.

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

Bây giờ chúng ta có thể kết nối các trình xử lý cho sự kiện tùy chỉnh đó ...

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

Tôi đang sử dụng tính năng này với loại trực tiếp, tôi không thể kích hoạt sự kiện khi người dùng xóa hoặc thay đổi ngày theo cách thủ công mà không chọn ngày trên bộ chọn. Rất hữu ích.
Tony

Vấn đề của tôi với các trường ngày tháng của jQuery không hoàn toàn giống với trường được đăng ở đây. Đó là về sự kiện thay đổi bắn nhiều lần. Tôi đã thử một vài giải pháp và đây là giải pháp duy nhất thực sự hoạt động trong tình huống của tôi.
Patee Gutee

Tôi đã làm ít nhiều giống như giải pháp này và tôi nghĩ rằng nó chắc chắn hoạt động tốt nhất. Tôi sẽ đăng những gì tôi đã làm trong một câu trả lời riêng biệt ...

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

14
Tôi nghĩ rằng điều này nên làm việc, nhưng tiếc là không. Nó chỉ được kích hoạt khi trường được thay đổi bằng bàn phím , không phải khi chọn từ bộ chọn ngày. Làm phiền.
Simon East

1
Từ các tài liệu UI của jQuery: "Tiện ích này thao tác giá trị của phần tử của nó theo chương trình, do đó, một sự kiện thay đổi gốc có thể không được kích hoạt khi giá trị của phần tử thay đổi."
Sam Kauffman

Điều buồn cười là tôi đang nhận được điều ngược lại - khi tôi thay đổi đầu vào bằng tay thông qua bàn phím, không có sự kiện nào được kích hoạt. Nhưng khi tôi thay đổi giá trị của trường thông qua tiện ích, sự kiện thay đổi sẽ được kích hoạt. Lạ
Renan

Điều này hoạt động tốt khi tôi thay đổi bằng bàn phím và khi tôi thay đổi với tiện ích chọn ngày.
Sammie

bằng cách nào đó điều này gọi nhiều lần.
NMathur

9

Tôi đang sử dụng bootstrap-datepicker và không có giải pháp nào ở trên làm việc cho tôi. Câu trả lời này đã giúp tôi ..

Sự kiện ngày thay đổi ngày khởi động của bootstrap không kích hoạt khi chỉnh sửa thủ công ngày hoặc xóa ngày

Đây là những gì tôi áp dụng:

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

Hy vọng điều này có thể giúp đỡ người khác.


4

Trên jQueryUi 1.9 Tôi đã quản lý để làm cho nó hoạt động thông qua một giá trị dữ liệu bổ sung và kết hợp các hàm beforeShow và 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 );
        }
    }
});

Làm việc cho tôi :)


4

Tôi biết đây là một câu hỏi cũ. Nhưng tôi không thể có được sự kiện jquery $ (this) .change () để bắn chính xác trênSelect. Vì vậy, tôi đã đi với cách tiếp cận sau đây để kích hoạt sự kiện thay đổi thông qua 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ỗi "'$' không xác định" cho đoạn trích này. À ồ.
Michael12345

Bạn đang gửi một sự kiện thay đổi trong sự kiện onSelect không mang lại hiệu quả mong muốn vì chọn sẽ kích hoạt mỗi lần nhấp vào một ngày nhưng điều đó không nhất thiết có nghĩa là ngày thực sự thay đổi, tức là người dùng có thể đã nhấp vào cùng một ngày hai lần.
Jacques

@Jacques bạn đúng. Tôi tin rằng bạn có thể so sánh String dateText với this.value và chỉ kích hoạt điều này nếu chúng khác nhau.
tstrand66

@ Michael12345 tôi hiểu ý của bạn. tôi đã sửa đổi nó để nó không còn là một đoạn trích nữa. lời xin lỗi của tôi.
tstrand66

3

Thử cái này

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

Hi vọng điêu nay co ich:)


3

Thử :

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

1

Hướng dẫn nói:

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

Vì thế:

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

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

Làm việc cho tôi.


1

Lời khuyên của tôi:

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 chọn mã sự kiện thay đổi giá trị bên dưới

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

nếu bạn đang sử dụng wdcalWiki, điều này sẽ giúp bạn

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

sự kiện onReturn hoạt động với tôi

hy vọng điều này giúp đỡ


0

Tôi nghĩ vấn đề của bạn có thể nằm ở cách thiết lập datepicker của bạn. Tại sao bạn không ngắt kết nối đầu vào ... không sử dụng altField. Thay vào đó, thiết lập rõ ràng các giá trị khi onSelect kích hoạt. Điều này sẽ cung cấp cho bạn quyền kiểm soát từng tương tác; trường văn bản người dùng và datepicker.

Lưu ý: Đôi khi bạn phải gọi thủ tục trên .change () chứ không phải .onSelect () vì onSelect có thể được gọi trên các tương tác khác nhau mà bạn không mong đợi.

Mã giả:

$('#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
    });
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.