การวาง datepicker () บนองค์ประกอบที่สร้างแบบไดนามิก - JQuery / JQueryUI


116

ฉันได้สร้างกล่องข้อความแบบไดนามิกและต้องการให้แต่ละกล่องสามารถแสดงปฏิทินได้เมื่อคลิก รหัสที่ฉันใช้คือ:

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

ซึ่งจะใช้ได้เฉพาะในกล่องข้อความแรกแม้ว่ากล่องข้อความทั้งหมดของฉันจะมีคลาสที่เรียกว่า datepicker_recurring_start

ความช่วยเหลือของคุณได้รับการชื่นชมมาก!


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

ฉันกำลังโหลดโค้ดด้านหลังด้วย PHP
แพร่หลาย

ฉันคิดว่าคุณอาจสับสน แต่ก็ยากที่จะบอกด้วยข้อมูลที่คุณให้มา ดังนั้นเพื่อยืนยันว่าคุณสามารถยืนยันความหมายของ 'กล่องข้อความที่สร้างขึ้นแบบไดนามิก' ได้อย่างไร
Tr1stan

หากฉันกำลังโหลด 'page one' php จะดู db เพื่อดูจำนวนวันที่ใน 'page one' และแสดงขึ้นมา ดังนั้นเมื่อ 'page one' โหลดขึ้นมาจะมี textbox 4 อันซึ่งต้องโหลด datepicker () 'หน้าสอง' มี 7 ช่องข้อความซึ่งต้องโหลดฟังก์ชัน datepicker ()
แพร่หลาย

หากคุณมีปัญหากับตัวเลือกข้อมูลไม่ทำงานหลังจากการโทรครั้งแรกโปรดดูคำตอบนี้: stackoverflow.com/a/16283547/1329910ปัญหาของคุณอาจเกี่ยวข้องกับ datepicker ที่เพิ่มคลาสของตัวเอง: hasDatepicker
Vlad

คำตอบ:


271

นี่คือเคล็ดลับ:

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

การสาธิต

$('...selector..').on('..event..', '...another-selector...', ...callback...);ไวยากรณ์หมายถึง:
เพิ่มฟังให้...selector..(คนbodyในตัวอย่างของเรา) สำหรับเหตุการณ์..event..( 'โฟกัส' ในตัวอย่างของเรา) สำหรับลูกหลานทั้งหมดของโหนดที่ตรงกันที่ตรงกับตัวเลือก...another-selector...( .datepicker_recurring_startในตัวอย่างของเรา) ให้ใช้ตัวจัดการเหตุการณ์...callback...(ฟังก์ชันอินไลน์ในตัวอย่างของเรา)

ดูhttp://api.jquery.com/on/และโดยเฉพาะอย่างยิ่งส่วนเกี่ยวกับ "เหตุการณ์ที่ได้รับมอบหมาย"


4
นี่คือโซลูชันที่สามารถใช้งานได้กับการต่อท้ายแบบไดนามิกทุกประเภท +1 ให้กับคุณ
DangerMonkey

5
แม้ว่าฉันจะดูแปลก ๆ ที่คุณต้องการโทรหา.datapicker()ทุกครั้งที่ textbox ได้รับโฟกัส - ดังนั้นคุณควรระมัดระวังกับแนวทางนี้ (สมมติว่าฉันอ่านสิ่งนี้ถูกต้อง) อย่างไรก็ตามฉันคิดว่าคุณพอใจกับสิ่งนี้.datapicker()เนื่องจากอาจตรวจสอบว่ามีการสร้าง datepicker หรือไม่ก่อนที่จะพยายามสร้างใหม่ ด้วยรหัสอื่นคุณอาจไม่มีพระคุณนี้ นอกจากนี้. on (มีเฉพาะใน JQuery 1.7 เท่านั้นดังนั้นโปรดตรวจสอบให้แน่ใจว่าคุณใช้เวอร์ชันที่ถูกต้อง
Tr1stan

3
datepicker ฉลาดพอที่จะตรวจสอบว่ามันถูกสร้างขึ้นแล้วหรือไม่ (ส่วนประกอบ jQueryUI ทั้งหมด) หากเวอร์ชัน jQuery ต่ำกว่า 1.7 คุณสามารถใช้live ได้
ilyes kooli

7
คุณอาจต้องการเพิ่มตัวกรอง:not(.hasDatepicker)
Salman A

1
ระวังการใช้ jQuery.clone () ภายในพื้นที่ที่มี datepicker หากคุณทำเช่นนั้นให้เพิ่มสิ่งนี้เพื่อลบคลาส hasDatepicker และ id datepicker จะเพิ่มให้กับอินพุตของคุณ: .... find ('input.hasDatepicker'). removeClass ('hasDatepicker'). removeAttr ('id');
yahermann

45

สำหรับฉันด้านล่าง jquery ทำงาน:

เปลี่ยน "body" เป็นเอกสาร

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

ขอบคุณข้อมูลskafandri

หมายเหตุ: ตรวจสอบว่า ID ของคุณแตกต่างกันในแต่ละฟิลด์


ถูกต้อง - สำหรับฉันฉันต้องใช้ $ (document) ไม่ใช่ $ ('body') - จัดเรียงปัญหาด้วยโค้ดขนาดเล็ก ฉันสามารถทำให้ตัวอย่างใช้งานได้โดยไม่มีปัญหา แต่และทันทีที่ฉันเพิ่มจาวาสคริปต์จำนวนมากลงในซอโค้ดนี้ก็ไม่เหมาะกับฉันอีกต่อไป ขอบคุณทั้งคู่
Tom Stickel

16

คำตอบที่ยอดเยี่ยมโดย skafandri +1

นี่เป็นเพียงการอัปเดตเพื่อตรวจสอบคลาส hasDatepicker

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

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

});

1
จากนั้นสามารถย่อเป็น$('body').on('focus',".datepicker:not(.hasDatepicker)", function(){$(this).datepicker();});?
Luke Stevenson

11

ตรวจสอบให้แน่ใจองค์ประกอบของคุณที่มี.date-pickerระดับไม่ได้มีhasDatepickerระดับ หากเป็นเช่นนั้นแม้แต่การพยายามเริ่มต้นใหม่อีกครั้ง$myDatepicker.datepicker();ก็จะล้มเหลว! แต่คุณต้องทำ ...

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

เป๊ะ! องค์ประกอบที่โหลดแบบไดนามิกไม่ได้เป็นปัญหาสำหรับฉันดังนั้นวิธีนี้จึงใช้ได้ผล
Sterling Beason

6

คุณต้องเรียกใช้.datepicker();อีกครั้งหลังจากที่คุณสร้างองค์ประกอบกล่องข้อความอื่นแบบไดนามิกแล้ว

ฉันขอแนะนำให้ทำในวิธีการโทรกลับของการโทรที่กำลังเพิ่มองค์ประกอบใน DOM

สมมติว่าคุณใช้วิธีการโหลด JQuery เพื่อดึงองค์ประกอบจากแหล่งที่มาและโหลดลงใน DOM คุณจะต้องทำสิ่งนี้:

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

1
สิ่งนี้ไม่ได้ผลในทางปฏิบัติเสมอไปจากประสบการณ์ของฉัน กรณีที่ดีที่สุดคือการเพิ่ม ID เฉพาะให้กับองค์ประกอบของคุณและใช้ ID เหล่านั้นเพื่ออ้างอิงและใช้ datepicker ดูเหมือนว่าปลั๊กอินภายในจะใช้ตัวเลือกเหล่านั้น
Wes Johnson

1

วิธีการใหม่สำหรับองค์ประกอบไดนามิกคือMutationsObserver .. ตัวอย่างต่อไปนี้ใช้underscore.jsเพื่อใช้ฟังก์ชัน (_.each)

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

นี่คือสิ่งที่ใช้ได้ผลสำหรับฉัน (ใช้ jquery datepicker):

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

0

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

นี่คือสิ่งที่ได้ผลในที่สุด:

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

หวังว่านี่จะช่วยใครบางคนได้เพราะสิ่งนี้ทำให้ฉันย้อนกลับไปเล็กน้อย


0

คุณสามารถเพิ่ม class .datepicker ในฟังก์ชัน javascript เพื่อให้สามารถเปลี่ยนประเภทอินพุตแบบไดนามิก

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

0

ฉันได้แก้ไขคำตอบของ @skafandri เพื่อหลีกเลี่ยงการใช้ตัวdatepickerสร้างซ้ำกับอินพุตทั้งหมดที่มี.datepicker_recurring_startคลาส

นี่คือ HTML:

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

นี่คือ JS:

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

นี่คือการสาธิตที่ใช้งานได้


0

นี่คือสิ่งที่ใช้ได้ผลสำหรับฉันบน JQuery 1.3 และแสดงในคลิกแรก / โฟกัส

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

สิ่งนี้ต้องการให้ข้อมูลของคุณมีคลาส 'mostrar_calendario'

Live มีไว้สำหรับ JQuery 1.3+ สำหรับเวอร์ชันที่ใหม่กว่าคุณต้องปรับให้เป็น "เปิด"

ดูเพิ่มเติมเกี่ยวกับความแตกต่างที่นี่http://api.jquery.com/live/


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