JQuery DatePicker не работает на динамически создаваемых HTML - PullRequest
17 голосов
/ 10 марта 2012

Я динамически создаю пару div с внутренним контролем.Два из этих элементов управления должны быть сборщиками даты.Но по какой-то причине они не отображаются (отображается только входной текст). Это работает, если я создаю статический HTML, но не когда я использую динамический.

Это код, который я использую для генерацииHTML (я вижу div)

var ShowContainerDiv = document.createElement('DIV');

var btnShowDiv = document.createElement('DIV');
btnShowDiv.id = 'btnShowDiv ';
btnShowDiv.title = 'Change';
btnShowDiv.index = 120;

var lblShow = document.createElement('label')
lblShow.htmlFor = "btnShowDiv";
lblShow.appendChild(document.createTextNode('Show'));
btnShowDiv.appendChild(lblShow );
btnShowDiv.onclick = function () {
    dropdown.style.visibility = "visible";
};

var dropdown = document.createElement('DIV');
dropdown.style.backgroundColor = 'white';
dropdown.style.borderStyle = 'solid';
dropdown.style.borderWidth = '2px';
dropdown.style.cursor = 'pointer';
dropdown.style.textAlign = 'left';
dropdown.style.width = '150px';

var chkRed = document.createElement("input");
chkRed.type = "checkbox";
chkRed.id = "chkRed";
chkRed.value = "Red";
chkRed.checked = false;
var lblRed = document.createElement('label')
lblRed.htmlFor = "chkRed";
lblRed.style.color = "#F00";
lblRed.appendChild(document.createTextNode('Red'));

var chkYellow = document.createElement("input");
chkYellow.type = "checkbox";
chkYellow.id = "chkYellow";
chkYellow.value = "Yellow";
chkYellow.checked = false;
var lblYellow = document.createElement('label')
lblYellow.htmlFor = "chkYellow";
lblYellow.style.color = "#FF0";
lblYellow.appendChild(document.createTextNode('Yellow'));

var chkGreen = document.createElement("input");
chkGreen.type = "checkbox";
chkGreen.id = "chkGreen";
chkGreen.value = "Green";
chkGreen.checked = false;
var lblGreen = document.createElement('label')
lblGreen.htmlFor = "chkGreen";
lblGreen.style.color = "#0F0";
lblGreen.appendChild(document.createTextNode('Green'));

var dateFrom = document.createElement("input");
dateFrom.id = "txtDateFrom";
dateFrom.type = "text";
dateFrom.className = "datepicker";
dateFrom.style.width = "70px";
dateFrom.readonly = "readonly";
var lblDateFrom = document.createElement('label')
lblDateFrom.htmlFor = "txtDateFrom";
lblDateFrom.appendChild(document.createTextNode('From'));

var dateTo = document.createElement("input");
dateTo.id = "txtDateTo";
dateTo.type = "text";
dateTo.className = "datepicker";
dateTo.style.width = "70px";
dateTo.readonly = "readonly";
var lblDateTo = document.createElement('label')
lblDateTo.htmlFor = "txtDateTo";
lblDateTo.appendChild(document.createTextNode('To'));

var btnDone = document.createElement("input");
btnDone.type = "button";
btnDone.name = "btnDone";
btnDone.value = "Done";
btnDone.onclick = function () {
    dropdown.style.visibility = "hidden";
};

dropdown.appendChild(chkRed);
dropdown.appendChild(lblRed);
dropdown.appendChild(document.createElement("BR"));
dropdown.appendChild(chkYellow);
dropdown.appendChild(lblYellow);
dropdown.appendChild(document.createElement("BR"));
dropdown.appendChild(chkGreen);
dropdown.appendChild(lblGreen);
dropdown.appendChild(document.createElement("BR"));
dropdown.appendChild(dateFrom);
dropdown.appendChild(document.createElement("BR"));
dropdown.appendChild(dateTo);
dropdown.appendChild(document.createElement("BR"));
dropdown.appendChild(btnDone);

ShowContainerDiv.appendChild(btnShowDiv);
ShowContainerDiv.appendChild(dropdown);

g.event.addDomListener(btnShowDiv, 'click', function () {
    dropdown.visible = true;
    dropdown.style.visibility = "visible";
});

g.event.addDomListener(btnDone, 'click', function () {
    dropdown.visible = false;
    dropdown.style.visibility = "hidden";
});

map.controls[g.ControlPosition.TOP_RIGHT].push(ShowContainerDiv);

Затем в файле .js у меня есть это (я проверил, и я включаю файл)

$(document).ready(function () {
    $(".datepicker").datepicker({
        dateFormat: 'yy/m/d',
        firstDay: 1,
        changeMonth: true,
        changeYear: true,
        showOn: 'both',
        autosize: true,
        buttonText: "Select date",
        buttonImage: '../Content/images/calendar.png',
        buttonImageOnly: true
    });
});

Почему средство выбора датыне появляется?Спасибо!Гильермо.

Ответы [ 10 ]

26 голосов
/ 05 августа 2012

Когда вы пишете

$(document).ready(function () {
    $(".datepicker").datepicker({...});
});

Этот фрагмент выполняется сразу после загрузки страницы.Таким образом, ваши динамические датеры еще не там.Вам нужно вызвать $(aSuitableSelector).datepicker(...) для каждого вновь вставленного элемента.Во-первых, используйте var для хранения ваших опций:

var datePickerOptions = {
    dateFormat: 'yy/m/d',
    firstDay: 1,
    changeMonth: true,
    changeYear: true,
    // ...
}

Это позволяет вам писать

 $(document).ready(function () {
    $(".datepicker").datepicker(datePickerOptions);
 });

и писать

 // right after appending dateFrom to the document ...
 $(dateFrom).datepicker(datePickerOptions);

 //...

 // right after appending dateTo ...
 $(dateTo).datepicker(datePickerOptions);

Вы также можете использовать JQueryспособность прослушивать изменения DOM , чтобы избежать необходимости применять магию JS к вновь вставленным элементам - но я не думаю, что это того стоит.

3 голосов
/ 24 июня 2018

Самый простой способ найти средство выбора даты для динамически добавляемого поля ввода:

    $('body').on('focus',".datepicker", function(){
        $(this).datepicker();
    });
2 голосов
/ 17 августа 2018

Вы можете просто использовать это.

$('body').on('focus',".date-picker", function(){
  $(this).datepicker();
});
2 голосов
/ 06 августа 2012

Самый простой способ, который я нашел, чтобы решить эту проблему, это использовать плагин livequery:

http://docs.jquery.com/Plugins/livequery

Вместо того, чтобы применять указатели даты ко всем объектам определенного класса, вы говорите LiveQueryприменить его к этим объектам.LiveQuery, в свою очередь, продолжит применять указатель даты, даже когда впоследствии будет изменена ваша DOM.

Я не видел падений производительности при использовании этого, и изменения кода действительно минимальны (вам нужнодобавить плагин на страницу и изменить только одну строку кода).

Вы будете использовать его так:

$(".datepicker").livequery(
        function(){ 
            // This function is called when a new object is found. 
            $(this).datepicker({ ...}});
        }, 
        function() { 
            // This function is called when an existing item is being removed. I don't think you need this one so just leave it as an empty function.
        }
); 

С этого момента каждый раз, когда вы добавляете объект скласс datepicker, плагин datepicker будет автоматически применен к нему.

0 голосов
/ 21 ноября 2017

Пожалуйста, добавьте ниже код после добавления элемента.

$(".datepicker").datepicker({
        dateFormat: 'yy/m/d',
        firstDay: 1,
        changeMonth: true,
        changeYear: true,
        showOn: 'both',
        autosize: true,
        buttonText: "Select date",
        buttonImage: '../Content/images/calendar.png',
        buttonImageOnly: true
    });
0 голосов
/ 17 мая 2016
$( ".datepicker" ).datepicker({inline: true,dateFormat: "dd-mm-yy"});
0 голосов
/ 19 января 2016

Я поместил

$( "#InstallDate" ).datepicker({
  showOn: "button",
    minDate: 0, // no past dates
  buttonImage: "../images/Date.png",
  buttonImageOnly: true,
  buttonText: "Select date",
  dateFormat: 'yy-mm-dd',
}); 

в файл сценария DatePicker.js, а затем добавил следующую строку в конце сгенерированной формы Ajax Html

<script type='text/javascript' src='/inc/DatePicker.js'></script> 
0 голосов
/ 05 августа 2012

Код, который связывает указатели даты, лучше всего выполнять сразу после динамического создания html. Если вы хотите сохранить код для инициализации datepicker в отдельном файле, я бы рекомендовал следующий подход: После того, как вы закончите генерировать свой HTML (я предполагаю, что он генерируется на готовом документе), используйте

$(document).trigger("customHtmlGenerated");

А в файле datepicker вместо $(document).ready(function(){...}) используйте $(document).bind("customHtmlGenerated", function(){...});

0 голосов
/ 10 марта 2012

Вероятно, дело в том, в каком порядке запускается JavaScript.Попробуйте поставить

$(".datepicker").datepicker({
    dateFormat: 'yy/m/d',
    firstDay: 1,
    changeMonth: true,
    changeYear: true,
    showOn: 'both',
    autosize: true,
    buttonText: "Select date",
    buttonImage: '../Content/images/calendar.png',
    buttonImageOnly: true
});

После вашего JavaScript, который создает HTML.

0 голосов
/ 10 марта 2012

Код jQuery выполняется, когда документ готов: это означает, что когда начальная разметка вашей страницы готова, а не после того, как ваши файлы javascript были запущены.

Полагаю, ваш код для инициализации средства выбора даты запускается до , ваш скрипт, создающий элементы, работает, поэтому ничего не происходит.


Попробуйте выполнить код jquery, когда страница загружена, используя .load () вместо .ready (). Событие load вызывается, когда загружены все ресурсы (js, image ...).

$(window).load(function () {
    $(".datepicker").datepicker({
        ...
    });
});

Вы также можете просто использовать способ выполнения JavaScript. Скрипты выполняются в том порядке, в каком они встречаются на странице. Чтобы вы могли:

  • переместите свои скрипты прямо перед закрывающим тегом тела `` `
  • убедитесь, что ваш первый скрипт (создание элементов) предшествует коду datepicker
  • удалить обработчик .ready () для средства выбора даты. Когда вы помещаете ваш скрипт в конец, он неявно запускается, когда DOM готов ...
...