jQuery Datepicker onchange olay sorunu


239

Bir alanı değiştirdiğinizde bir arama rutini çağıran bir JS kodu var. Sorun Datepicker giriş alanını güncelleştirdiğinde tetiklenecek herhangi bir jQuery olayları bulamıyor olmasıdır.

Nedense, Datepicker alanı güncellediğinde bir change olayı çağrılmaz. Takvim açıldığında odağı değiştirir, böylece onu da kullanamam. Herhangi bir fikir?


Stackoverflow.com/a/30132949/293792 kullanarak sona erdi çünkü bu doğrudan soruya cevap gibi görünüyordu
twobob

Yanıtlar:


370

Datepicker onSelectolayını kullanabilirsiniz .

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

Canlı örnek :

Maalesef, onSelectbir tarih seçildiğinde, değişmemiş olsa bile tetiklenir. Her zaman yangınlar: Bu datepicker bir tasarım kusur onSelect(hiçbir şey değişti bile) ve gelmez değişikliği yatan girişinde herhangi olayı. (Bu örneğin koduna bakarsanız, değişiklikleri dinliyoruz, ancak bunlar yükseltilmiyor.) İşler değiştiğinde büyük olasılıkla girdi üzerinde bir olay changebaşlatmalıdır (muhtemelen olağan olay veya muhtemelen bir tarih seçici- belirli bir).


İsterseniz, elbette, changeetkinliği inputateşte yapabilirsiniz:

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

Bu jQuery ile bağlanmış herhangi bir işleyici changeiçin altta ateş edecek input. Ama yine de, her zaman ateş ediyor. Yalnızca gerçek bir değişikliğe ateş etmek istiyorsanız, önceki değeri (muhtemelen üzerinden data) kaydetmeniz ve karşılaştırmanız gerekir.

Canlı örnek :


1
@ user760092: Bu yanıtı gönderdim ve sonra dışarı çıktım ve tam anlamıyla ayrılırken "Biliyorsunuz, changeişleyiciyi / işleyicileri tetikleyebilirsiniz" diye düşündüm ve cevabı bununla güncelledim. :-)
TJ Crowder

1
Ben bunu tüm senaryolarda çalışmak için almaya çalışırken çevrelerinde dolaştım ve bu yaptı! Çok takdir!
Chris Nevill

7
Neden dünyada bu gerçek olayları yapmadılar?
Jay K

1
Bu "seçim" içindir ve "değişim" için DEĞİLDİR. Bir tarih seçip yeniden seçerseniz, bu olay tetiklenir. Bazı geliştiriciler, verilerin "kirli" olup olmadığını ve kaydedilmesi gerekip gerekmediğini bilmek için bir tarihin başlangıç ​​durumundan ne zaman değiştiğini bilmek isteyecektir. Bu nedenle, sizi bu konuda küçümsüyorum.
AndroidDev

4
@AndroidDev: Bunu açıkladım. ( Sen elbette olabilir; sitenin amacı sahip olmaktır iyi cevaplar , yani teşvik edilmektedir ulaşmak saygılı düzenleme.) O değil cevap, datepicker bir tasarım kusur. (Yapması gereken , yalnızca tarih değiştirilirse, ancak değişmezse, girişte bir tür değişiklik olayı
başlatmaktır

67

TJ Crowder'ın yanıtı ( https://stackoverflow.com/a/6471992/481154 ) çok iyi ve hala doğru. OnSelect işlevi içindeki change olayını tetiklemek, alacağınız kadar yakındır.

Ancak, datepicker nesnesinde ( lastVal) , değerleri kendiniz depolamak zorunda kalmadan değişiklik olayını yalnızca gerçek değişikliklerde koşullu olarak tetiklemenizi sağlayacak güzel bir özellik vardır :

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

Sonra normal gibi değişiklik olaylarını yönetin:

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

Bunu yakın zamanda test eden var mı? Benim için işe yaramıyor. i.lastVal tanımsız olarak döner ve kullanılabilir özelliklerden biri gibi görünmez.
BK

Bunu hiç sorun olmadan uyguladım. Tıkır tıkır çalışıyor.
DevSlick

bu artık çalışmıyor, son değer artık tanımlanmadı
luke_mclachlan

4
@luke_mclachlan lastValAncak ;-)
Alexander Derck

lastValdatepicker nesnesinde, en azından testlerimde yok. Yani bu çözüm her zaman değişikliği tetikleyecektir.
Nicholas

13

Datepicker nesnesinde onSelect olayını arıyorsunuz :

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

11

Bunu yazdım çünkü bir olayı ancak tarih değiştiğinde tetiklemek için bir çözüme ihtiyacım vardı.

Basit bir çözümdür. İletişim kutusu her kapatıldığında verilerin değişip değişmediğini test ederiz. Varsa, özel bir etkinliği tetikleriz ve depolanan değeri sıfırlarız.

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

Şimdi bu özel etkinlik için işleyicileri bağlayabiliriz ...

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

Bunu nakavt ile kullanıyorum, kullanıcı seçicide bir tarih seçmeden tarihi sildiğinde veya manuel olarak değiştirdiğinde bir olayı tetikleyemedim. Çok yararlı.
Tony,

JQuery datepicker alanlarıyla ilgili sorunum, burada yayınlanan alanla tam olarak aynı değil. Birden çok kez tetiklenen değişiklik olayı ile ilgilidir. Birkaç çözüm denedim ve durumumda çalışan tek çözüm bu.
Patee Gutee

Bu çözümle az çok aynı şeyi yaptım ve kesinlikle en iyisi olduğunu düşünüyorum. Ayrı bir cevapta ne yaptığımı

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

14
Bunun işe yarayacağını düşündüm, ama maalesef işe yaramadı. Tarih seçiciden seçim yaparken değil, yalnızca alan klavye kullanılarak değiştirildiğinde tetiklenir . Can sıkıcı.
Simon East

1
JQuery UI dokümanlarından: "Bu pencere öğesi, öğesinin değerini programlı olarak değiştirir, bu nedenle öğenin değeri değiştiğinde yerel bir değişiklik olayı tetiklenmeyebilir."
Sam Kauffman

Komik olan şu ki bunun tam tersini görüyorum - klavyeden elle girişi değiştirdiğimde hiçbir olay tetiklenmiyor. Ancak, alanın değerini widget aracılığıyla değiştirdiğimde, change olayı tetiklenir. Garip.
Renan

Bu, klavye ile değiştirdiğimde ve tarih seçici widget'ıyla değiştirdiğimde işe yarar.
Sammie

bir şekilde bu birden çok kez çağırıyor.
NMathur


4

JQueryUi 1.9'da, ek bir veri değeri ve beforeShow ve onSelect işlevlerinin bir kombinasyonu ile çalışmasını sağladım:

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

Benim için çalışıyor :)


4

Bunun eski bir soru olduğunu biliyorum. Ama doğru ateş etmek jquery $ (this) .change () olay alamadım. Bu yüzden vanilya js aracılığıyla değişim olayını ateşlemek için aşağıdaki yaklaşımla gittim.

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

Bu snippet için "'$' tanımsız" hatası. Ah oh.
Michael12345

OnSelect etkinliğinde, bir tarih her tıklandığında tetikleneceği için istenen efekt olmayan bir değişiklik etkinliği gönderiyorsunuz, ancak tarihin gerçekten değiştirildiği anlamına gelmez, yani kullanıcı aynı tarihi tıklamış olabilir iki defa.
Jacques

@ Haklısın. i string dateText this.value karşılaştırmak ve sadece farklı ise bu ateş inanıyorum.
tstrand66

@ Michael12345 ne demek istediğini anlıyorum. ben artık bir pasajı artık değiştirilmiş. özür dilerim.
tstrand66

3

Bunu dene

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

Bu yardımcı olur umarım:)


3

Deneyin :

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

1

Kılavuz diyor:

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

Yani:

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

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

Benim için çalışıyor.


1

Soluthion'um:

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 tarafından seçilen değer değişikliği olay kodu aşağıda

/* 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 kullanıyorsanız bu size yardımcı olacaktır

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

Geri dönüş etkinliği benim için çalışıyor

umarım bu yardım


0

Bence senin sorunun tarih seçicinin kurulumunda yatıyor olabilir. Giriş bağlantısını neden kesmiyorsunuz ... altField kullanmayın. Bunun yerine, onSelect tetiklendiğinde değerleri açıkça ayarlayın. Bu size her etkileşimin kontrolünü verecektir; kullanıcı metin alanı ve tarih seçici.

Not: Bazen .onSelect () yerine .change () yerine rutini çağırmanız gerekir, çünkü onSelect beklemediğiniz farklı etkileşimlerde çağrılabilir.

Sahte 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
    });
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.