dinamik olarak oluşturulan öğelere datepicker () koymak - JQuery / JQueryUI


116

Dinamik olarak metin kutuları oluşturdum ve her birinin tıklandığında bir takvim görüntüleyebilmesini istiyorum. Kullandığım kod:

$(".datepicker_recurring_start" ).datepicker();

Tüm metin kutularımın datepicker_recurrent_start adında bir sınıfa sahip olmasına rağmen, yalnızca ilk metin kutusunda çalışır.

Yardımınız çok takdir ediliyor!


"Dinamik olarak oluşturuldu" dediğinizde, sayfa yüklenmeden önce arka planda kodlama ile mi yoksa sayfa yüklendikten sonra javascript ile mi demek istiyorsunuz? Çünkü öğeler sayfa yüklendikten sonra eklenirse, her yeni metin kutusu eklendiğinde takvimi yeniden bağlamanız gerekir.
DangerMonkey

PHP ile arka planda kod yüklüyorum.
batmış

Sanırım kafanız karışıyor olabilir, ancak verdiğiniz bilgilerle bunu söylemek zor. Bu nedenle, sadece onaylamak için, lütfen 'dinamik olarak oluşturulmuş metin kutuları' ile ne demek istediğinizi onaylar mısınız?
Tr1stan

'Birinci sayfayı' yüklüyorsam, php 'birinci sayfada' kaç tane tarih metin kutusu olduğunu görmek için db'ye bakar ve onu görüntüler. Dolayısıyla 'birinci sayfa' yüklendiğinde, tarih seçiciyi () yüklemesi gereken 4 metin kutusu olacaktır. "sayfa iki", datepicker () işlevini yüklemesi gereken 7 metin kutusuna sahiptir.
batmış

İlk aramadan sonra veri seçicinin çalışmamasıyla ilgili bir sorununuz varsa, şu yanıtı kontrol edin: stackoverflow.com/a/16283547/1329910 Sorununuz, datepicker'ın kendi sınıfını eklemesiyle ilgili olabilir: hasDatepicker
Vlad

Yanıtlar:


270

işte hile:

$('body').on('focus',".datepicker_recurring_start", function(){
    $(this).datepicker();
});​

DEMO

$('...selector..').on('..event..', '...another-selector...', ...callback...);Sözdizimi aracı:
için bir dinleyici ekleyin ...selector..( bodyolay için bizim örneğimizde) ..event..(bizim örneğimizde 'odak'). Seçiciyle eşleşen eşleşen düğümlerin tüm alt öğeleri için ...another-selector...( .datepicker_recurring_startörneğimizde), olay işleyiciyi uygulayın ...callback...(örneğimizdeki satır içi işlevi)

Bkz http://api.jquery.com/on/ ve özellikle "yetkilendirilen olaylar" hakkında bölüm


4
Bu, her türlü dinamik eklemede işe yarayacak bir çözümdür. +1 size.
DangerMonkey

5
.datapicker()Metin kutusu her odak kazandığında aramak istemeniz bana garip gelse de - bu nedenle bu yaklaşıma dikkat etmek istersiniz (bunu doğru okuduğumu varsayarak). Ancak, .datapicker()yeniden oluşturmaya çalışmadan önce muhtemelen bir tarih seçici oluşturulup oluşturulmadığını kontrol edeceği için sorun olmayacağını düşünüyorum . Diğer kodla bu zarafete sahip olmayabilirsiniz. Ayrıca, .on (yalnızca JQuery 1.7'de tanıtıldı - bu yüzden doğru sürümü kullandığınızdan emin olun.
Tr1stan

3
datepicker, zaten oluşturulmuş olup olmadığını kontrol edecek kadar akıllıdır (bu arada tüm jQueryUI bileşenleri), jQuery sürümü
1.7'nin altındaysa

7
Bir filtre eklemek isteyebilirsiniz:not(.hasDatepicker)
Salman A

1
Tarih seçici içeren bir alan içinde jQuery.clone () kullanmaya dikkat edin. Bunu yaparsanız, hasDatepicker sınıfını kaldırmak için bunu ekleyin VE kimlik tarih seçici girdinize ekler: .... find ('input.hasDatepicker'). RemoveClass ('hasDatepicker'). RemoveAttr ('id');
yahermann

44

Benim için jquery'nin altında çalıştı:

"body" belgeye dönüştürülüyor

$(document).on('focus',".datepicker_recurring_start", function(){
    $(this).datepicker();
});

Skafandri sayesinde

Not: Her alan için kimliğinizin farklı olduğundan emin olun


Doğru - benim için $ ('body') yerine $ (belge) kullanmam gerekiyor - Küçük kod parçacıklarıyla sorunu sıralayın. Örneği sorunsuz bir şekilde çalıştırabilirim, ancak ve javascript'imden bir kısmını bir keman içine eklersem, bu kod artık benim için çalışmıyor. İkisine de teşekkürler.
Tom Stickel

16

Skafandri'den mükemmel cevap +1

Bu sadece hasDatepicker sınıfını kontrol etmek için güncellenmiştir.

$('body').on('focus',".datepicker", function(){

    if( $(this).hasClass('hasDatepicker') === false )  {
        $(this).datepicker();
    }

});

1
Bu daha sonra kısaltılabilir $('body').on('focus',".datepicker:not(.hasDatepicker)", function(){$(this).datepicker();});mi?
Luke Stevenson

11

.date-pickerSınıftaki öğenizin zaten bir hasDatepickersınıfı OLMADIĞINDAN emin olun . Varsa, yeniden başlatma girişimi bile $myDatepicker.datepicker();başarısız olacaktır! Bunun yerine yapmanız gereken ...

$myDatepicker.removeClass('hasDatepicker').datepicker();

Kesinlikle doğru! Dinamik olarak yüklenen öğeler benim için sorun olmaktan çıktı, bu nedenle bu çözüm işe yaradı.
Sterling Beason

6

.datepicker();Diğer metin kutusu öğelerini dinamik olarak oluşturduktan sonra tekrar çalıştırmanız gerekir .

Öğeleri DOM'a ekleyen çağrının geri çağrı yönteminde bunu yapmanızı tavsiye ederim.

Öyleyse, öğeleri bir kaynaktan almak ve DOM'a yüklemek için JQuery Load yöntemini kullandığınızı varsayalım, şöyle bir şey yaparsınız:

$('#id_of_div_youre_dynamically_adding_to').load('ajax/get_textbox', function() {
  $(".datepicker_recurring_start" ).datepicker();
});

1
Bu, benim deneyimlerime göre pratikte her zaman işe yaramıyor. En iyi durum, öğelerinize benzersiz kimlikler eklemek ve bu kimlikleri onlara başvurmak ve tarih seçiciyi uygulamak için kullanmaktır. Görünüşe göre eklenti bu seçicileri kullanıyor.
Wes Johnson

1

Dinamik elemanlar için yeni bir yöntemdir MutationsObserver .. Aşağıdaki örnekte underscore.js kullanımı (_.each) işlevine.

MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;    

var observerjQueryPlugins = new MutationObserver(function (repeaterWrapper) {

    _.each(repeaterWrapper, function (repeaterItem, index) {

        var jq_nodes = $(repeaterItem.addedNodes);

        jq_nodes.each(function () {

            // Date Picker
            $(this).parents('.current-repeateritem-container').find('.element-datepicker').datepicker({
                dateFormat: "dd MM, yy",
                showAnim: "slideDown",
                changeMonth: true,
                numberOfMonths: 1
            });

        });

    });

});

observerjQueryPlugins.observe(document, {
    childList: true,
    subtree: true,
    attributes: false,
    characterData: false
});

1

Benim için işe yarayan şey buydu (jquery datepicker kullanarak):

$('body').on('focus', '.datepicker', function() {
 $(this).removeClass('hasDatepicker').datepicker();
});

0

Diğer çözümlerin hiçbiri benim için işe yaramadı. Uygulamamda, tarih aralığı öğelerini jquery kullanarak belgeye ekliyorum ve ardından bunlara tarih seçici uyguluyorum. Yani olay çözümlerinden hiçbiri bir sebepten dolayı işe yaramadı.

Sonunda işe yarayan buydu:

$(document).on('changeDate',"#elementid", function(){
    alert('event fired');
});

Umarım bu birisine yardımcı olur çünkü bu beni biraz geride bıraktı.


0

giriş türünü dinamik olarak değiştirebilmek için bir javascript işlevine .datepicker sınıfını ekleyebilirsiniz

 $("#ddlDefault").addClass("datepicker");
 $(".datepicker").datetimepicker({ timepicker: false, format: 'd/m/Y', });

0

Yapıcıyı sınıflı datepickertüm girdilere yeniden uygulamayı önlemek için @skafandri yanıtını değiştirdim .datepicker_recurring_start.

İşte HTML:

<div id="content"></div>
<button id="cmd">add a datepicker</button>

İşte JS:

$('#cmd').click(function() {
  var new_datepicker = $('<input type="text">').datepicker();
  $('#content').append('<br>a datepicker ').append(new_datepicker);
});

işte çalışan bir demo


0

Bu, benim için JQuery 1.3'te işe yarayan ve ilk tıklama / odakta gösterilen şeydi

function vincularDatePickers() {
    $('.mostrar_calendario').live('click', function () {
        $(this).datepicker({ showButtonPanel: true, changeMonth: true, changeYear: true, showOn: 'focus' }).focus();
    });
}

bu, girdinizin 'mostrar_calendario' sınıfına sahip olmasını gerektirir

Canlı, JQuery 1.3+ içindir, daha yeni sürümler için bunu "açık" olarak uyarlamanız gerekir

Farkla ilgili daha fazla bilgiyi burada bulabilirsiniz http://api.jquery.com/live/


0
$( ".datepicker_recurring_start" ).each(function(){
    $(this).datepicker({
        dateFormat:"dd/mm/yy",
        yearRange: '2000:2012',
        changeYear: true,
        changeMonth: true
    });
});
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.