ปัญหาเหตุการณ์การเปลี่ยน jQuery Datepicker onchange


239

ฉันมีรหัส JS ซึ่งเมื่อคุณเปลี่ยนฟิลด์มันจะเรียกรูทีนการค้นหา ปัญหาคือฉันไม่พบเหตุการณ์ jQuery ใด ๆ ที่จะทำงานเมื่อ Datepicker อัพเดตฟิลด์อินพุต

ด้วยเหตุผลบางอย่างเหตุการณ์การเปลี่ยนแปลงจะไม่ถูกเรียกเมื่อ Datepicker อัปเดตฟิลด์ เมื่อปฏิทินปรากฏขึ้นมันจะเปลี่ยนโฟกัสดังนั้นฉันจึงไม่สามารถใช้สิ่งนั้นได้ ความคิดใด ๆ


ฉันลงเอยด้วยการใช้stackoverflow.com/a/30132949/293792เนื่องจากสิ่งนี้ดูเหมือนจะตอบคำถามโดยตรง
twobob

คำตอบ:


370

คุณสามารถใช้ datepicker ของเหตุการณ์onSelect

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

ตัวอย่างสด :

น่าเสียดายที่onSelectไฟไหม้เมื่อใดก็ตามที่มีการเลือกวันที่แม้ว่าจะไม่ได้เปลี่ยน นี่เป็นข้อบกพร่องของการออกแบบใน datepicker: มันจะทำการยิงเสมอonSelect(แม้ว่าจะไม่มีอะไรเปลี่ยนแปลง) และจะไม่ส่งเหตุการณ์ใด ๆ ในอินพุตพื้นฐานเมื่อมีการเปลี่ยนแปลง (ถ้าคุณดูในรหัสของตัวอย่างนั้นเรากำลังฟังการเปลี่ยนแปลง แต่มันไม่ได้ถูกยกขึ้น) มันน่าจะเป็นเหตุการณ์ในอินพุตเมื่อสิ่งต่าง ๆ เปลี่ยนแปลง (อาจเป็นchangeเหตุการณ์ปกติหรืออาจเป็น datepicker- หนึ่ง)


แน่นอนถ้าคุณชอบคุณสามารถสร้างchangeเหตุการณ์บนinputกองไฟ:

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

ที่จะยิงchangeบนพื้นฐานinputสำหรับการจัดการใด ๆ ติดยาเสพติดผ่านทาง jQuery แต่อีกครั้งมันจะยิงมันเสมอ หากคุณต้องการเริ่มการเปลี่ยนแปลงที่แท้จริงเท่านั้นคุณจะต้องบันทึกค่าก่อนหน้า (อาจเป็นผ่านdata) และเปรียบเทียบ

ตัวอย่างสด :


1
@ user760092: ฉันโพสต์คำตอบนี้และจากนั้นก็ออกไปและตามตัวอักษรที่ฉันทิ้งฉันคิดว่า "คุณรู้คุณสามารถเรียกchangeตัวจัดการ" และดังนั้นฉันจึงได้ปรับปรุงคำตอบด้วย :-)
TJ Crowder

1
ฉันได้วนไปวนมาเป็นวงกลมพยายามจะให้มันทำงานในทุกสถานการณ์และมันก็ทำเสร็จแล้ว! ชื่นชมมาก!
Chris Nevill

7
ทำไมพวกเขาถึงไม่ทำเหตุการณ์จริงเหล่านั้น?
Jay K

1
สิ่งนี้มีไว้สำหรับ "การเลือก" และไม่ใช่สำหรับ "การเปลี่ยนแปลง" หากคุณเลือกวันที่จากนั้นเลือกอีกครั้งเหตุการณ์นี้จะเริ่มขึ้น นักพัฒนาบางคนจะต้องการทราบเมื่อวันที่เปลี่ยนจากสถานะเริ่มต้นบางอย่างเพื่อทราบว่าข้อมูลนั้น "สกปรก" และจำเป็นต้องบันทึกหรือไม่ ด้วยเหตุผลนี้ฉันกำลังลงมือคุณในเรื่องนี้
AndroidDev

4
@AndroidDev: ฉันชี้แจงว่า (แน่นอนคุณอาจมีเป้าหมายของเว็บไซต์คือการมีคำตอบที่ดีการแก้ไขอย่างเคารพเพื่อให้บรรลุซึ่งได้รับการสนับสนุน) มันเป็นข้อบกพร่องในการออกแบบใน datepicker ไม่ใช่คำตอบ (สิ่งที่ควรทำคือการยิงเหตุการณ์การเปลี่ยนแปลงบางชนิดในการป้อนข้อมูลและถ้าหากการเปลี่ยนวัน แต่ก็ไม่ได้.)
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 ส่งคืนไม่ได้กำหนดและไม่ปรากฏว่าเป็นหนึ่งในคุณสมบัติที่มี
BK

ฉันเพิ่งใช้สิ่งนี้โดยไม่มีปัญหาเลย ทำงานเหมือนจับใจ
DevSlick

สิ่งนี้ไม่ทำงานอีกต่อไป Lastval ไม่ได้ถูกกำหนดอีกต่อไป
luke_mclachlan

4
@luke_mclachlan lastValอย่างไรก็ตาม ;-)
Alexander Derck

lastValไม่มีอยู่ในวัตถุ datepicker อย่างน้อยก็ในการทดสอบของฉัน ดังนั้นวิธีนี้จะทำให้เกิดการเปลี่ยนแปลงเสมอ
Nicholas


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
});

ฉันใช้สิ่งนี้กับสิ่งที่น่าพิศวงฉันไม่สามารถเรียกเหตุการณ์เมื่อผู้ใช้ลบหรือเปลี่ยนวันด้วยตนเองโดยไม่เลือกวันที่ตัวเลือก มีประโยชน์มาก
Tony

ปัญหาของฉันกับเขตข้อมูล jQuery datepicker ไม่ตรงกับที่ลงรายการบัญชีที่นี่ มันเกี่ยวกับเหตุการณ์การเปลี่ยนแปลงที่เกิดขึ้นหลายครั้ง ฉันลองใช้วิธีแก้ปัญหาต่าง ๆ และนี่เป็นทางเดียวที่ใช้งานได้จริงในสถานการณ์ของฉัน
Patee Gutee

ฉันทำสิ่งนี้มากขึ้นหรือน้อยลงด้วยวิธีนี้และฉันคิดว่ามันใช้งานได้ดีที่สุด ฉันจะโพสต์สิ่งที่ฉันทำในคำตอบแยกต่างหาก ...

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

14
ฉันคิดว่ามันน่าจะใช้ได้ แต่น่าเสียดายที่ไม่ใช่ มันจะถูกเรียกเมื่อมีการเปลี่ยนแปลงฟิลด์โดยใช้แป้นพิมพ์ไม่ใช่เมื่อเลือกจากตัวใช้เลือกวันที่ น่ารำคาญ
Simon East

1
จาก jQuery UI docs: "วิดเจ็ตนี้จัดการค่าขององค์ประกอบโดยทางโปรแกรมดังนั้นเหตุการณ์การเปลี่ยนแปลงดั้งเดิมอาจไม่ถูกเรียกใช้เมื่อองค์ประกอบของค่าเปลี่ยนแปลง"
Sam Kauffman

สิ่งที่ตลกคือฉันได้รับสิ่งที่ตรงกันข้าม - เมื่อฉันเปลี่ยนอินพุตด้วยมือผ่านคีย์บอร์ดจะไม่มีเหตุการณ์ใดเกิดขึ้น แต่เมื่อฉันเปลี่ยนค่าของฟิลด์ผ่านวิดเจ็ตเหตุการณ์การเปลี่ยนแปลงจะเริ่มทำงาน แปลก
Renan

สิ่งนี้ใช้ได้ดีเมื่อฉันเปลี่ยนด้วยแป้นพิมพ์และเมื่อฉันเปลี่ยนด้วยวิดเจ็ตตัวเลือกวันที่
Sammie

อย่างใดเรียกมันหลายครั้ง
NMathur

9

ฉันใช้ bootstrap-datepicker และไม่มีวิธีแก้ปัญหาใดที่ใช้ได้สำหรับฉัน คำตอบนี้ช่วยฉัน ..

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 () เหตุการณ์เพื่อเริ่มต้นอย่างถูกต้องบนเลือก ดังนั้นฉันจึงไปด้วยวิธีการต่อไปนี้เพื่อยิงเหตุการณ์การเปลี่ยนแปลงผ่านทางวานิลลา 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 ซึ่งไม่ใช่เอฟเฟกต์ที่ต้องการเนื่องจากการเลือกจะเริ่มขึ้นทุกครั้งที่มีการคลิก แต่ไม่จำเป็นต้องหมายความว่าวันที่มีการเปลี่ยนแปลงจริงเช่นผู้ใช้อาจคลิกวันที่เดียวกัน สองครั้ง
Jacques

@Jacques คุณถูกต้อง ฉันเชื่อว่าคุณสามารถเปรียบเทียบ String dateText กับ this.value และใช้ไฟนี้เฉพาะเมื่อมันแตกต่างกัน
tstrand66

@ Michael12345 ฉันเห็นสิ่งที่คุณหมายถึง ฉันได้ทำการแก้ไขเพื่อไม่ให้เป็นข้อมูลโค้ดอีกต่อไป ขอโทษด้วย.
tstrand66



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

เหตุการณ์ในการกลับมาใช้งานได้สำหรับฉัน

หวังว่าความช่วยเหลือนี้


0

ฉันคิดว่าปัญหาของคุณอาจอยู่ที่การตั้งค่า datepicker ของคุณ ทำไมคุณไม่ยกเลิกการเชื่อมต่ออินพุต ... อย่าใช้ altField แทนที่จะตั้งค่าอย่างชัดเจนเมื่อ onSelect fires สิ่งนี้จะทำให้คุณสามารถควบคุมแต่ละการโต้ตอบ ฟิลด์ข้อความผู้ใช้และ datepicker

หมายเหตุ: บางครั้งคุณต้องเรียกรูทีนบน. 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
    });
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.