проблема при клонировании jQuery UI datepicker
у меня есть div, в котором есть datepicker. Я использую что-то вроде этого, чтобы клонировать его:
mydiv = $('#someDiv');
// works fine so far
mydiv.find('input.datefield').datepicker();
// clone without the events and insert
newDiv = myDiv.clone(false).insertAfter(myDiv);
// datepicker won't re-init if this class is present
newDiv.find('.hadDatepicker').removeClass('hadDatepicker');
// reinitialize datepicker
newDiv.find('input.datefield').datepicker();
это урезанная версия мой код. Он работает, и календарь отображается так, как ожидалось, где это ожидается .. но когда дата нажата, значение datepicker обновляется.. (тот, из которого он был клонирован).
Я пытался уничтожить (несуществующий) экземпляр раньше, как это:
newDiv.find('input.datefield').datepicker('destroy').datepicker();
не повезло ..
Я проверил, как он отслеживает экземпляры и вручную очищает данные следующим образом:
newDiv.find('input.datefield').data('datepicker', false).datepicker('destroy').datepicker();
по-прежнему не повезло.
Я не понимаю, что только поведение выбора даты является багги, все остальное работает так, как ожидалось.
Я действительно не знаю, что еще проверить ..
12 ответов
вот в чем проблема. datepicker создает атрибуты идентификаторов на основе UUID для полей ввода, которые он связывает при инициализации. Клонирование этих элементов приводит к большему количеству элементов с тем же ID (который не нравится jQuery) или другим ID, если ваша процедура клонирования управляет этим (что означает, что datepicker не знает о клонах). другими словами, datepicker инициализирует только все элементы, соответствующие вашему селектору во время его вызова. это на самом деле меньше смысла чтобы попытаться уничтожить/отключить / включить снова и снова, когда вы можете просто обернуть вызов init внутри любой функции, которую вы используете для создания клонов.
поскольку мои функции клонирования обычно копируются из скрытых элементов DOM, а не видимых, у меня есть роскошь решить, нужно ли мне связываться до или после клонирования. Итак, сделайте #templateDiv скрытым элементом на Вашей странице с элементом ввода уже там.
mydiv = $('#templateDiv');
mydest = $('#someDiv');
function make_the_donuts() {
newDiv = myDiv.clone(true).insertAfter(mydest);
// attach datepickers by instance rather than by class
newDiv.find('input.datefield').datepicker();
}
и это в значительной степени делает это. Клонировать (true) всякий раз, когда вы можете, это избавит вас от головной боли в долгосрочной перспективе.
это работает для меня с jQuery UI 1.7.2
var mydiv = $('#someDiv');
mydiv.find('input.datefield').datepicker();
var newDiv = mydiv.clone(false).attr("id", "someDiv2").insertAfter(mydiv);
newDiv.find('input.datefield')
.attr("id", "")
.removeClass('hasDatepicker')
.removeData('datepicker')
.unbind()
.datepicker();
проверить http://jsbin.com/ahoqa3/2 для быстрой демонстрации
кстати. кажется, у вас разные ошибки в коде вашего вопроса. Класс css является hasDatepicker
не hadDatepicker
и в свое время вы написали mydiv
и в следующий раз, когда переменная myDiv
что не одно и то же.
Если вы называете .datepicker('destroy').removeAttr('id')
перед клонированием, а затем повторно init выбора даты он будет работать.
это похоже на ошибку с destroy, так как предполагается вернуть элемент обратно в исходное состояние.
просто делать
$('input.datefield').datepicker("destroy");
перед клонированием div. Тогда после вставка клона снова привязать datepicker
$('input.datefield').datepicker();
своего рода "хакерское" решение, но оно отлично работает.
$('input.datefield').datepicker("destroy");
$('input.datefield').datepicker();
он работает хорошо. Но просто делая это, datepicker откроется на клонированном входе и установит дату на исходный вход (потому что у них один и тот же идентификатор)
чтобы решить эту проблему, вы должны изменить атрибут id клонированного ввода.
dp = < cloned input >
var d = $('input.vDateField');
dp.removeClass('hasDatepicker');
dp.attr('id', dp.attr('id')+d.length);
d.datepicker("destroy");
d.datepicker();
и это будет работать отлично!
вот как это работает для меня:
сначала вам нужно удалить класс hasDatepickerfrom клонированные элементы, потому что это то, что предотвращает datepicker от подключения к конкретному элементу.
тогда вы должны удалить id атрибут от каждого из клонированных элементов else .datepicker () предполагает, что datepicker добавляется к этому элементу.
после этого звонка .datepicker() на клонируются элемент.
newDiv.find('.classAttributeGivenForDatepicker').each(function() {
$(this).removeAttr('id').removeClass('hasDatepicker');
$(this).datepicker({dateFormat: 'dd-mm-yy', minDate: 0, autoclose: true,});
});
Как насчет изменения порядка?
mydiv = $('#someDiv');
// clone without the events and insert
newDiv = myDiv.clone(false).insertAfter(myDiv);
// datepicker won't re-init if this class is present
// not necessary anymore
// newDiv.find('.hadDatepicker').removeClass('hadDatepicker');
newDiv.find('input.datefield').datepicker();
// datepicker attached as a last step
mydiv.find('input.datefield').datepicker();
честно говоря, я не знаю, как datepicker работает внутри. Моя догадка заключается в том, что он хранит что-то в хранилище jQuery DOM. Давайте избегать копирования любой ценой.
(между этими строками кода может быть длинная бизнес-логика. Дело в том, чтобы иметь резервную копию #someDiv, прежде чем ставить на нее datepicker.)
убедитесь, что ваш недавно клонированный datepicker имеет другое имя и идентификатор, чем оригинал. Если они оба имеют одно и то же имя, то поведение, которое вы описываете, будет нормальным.
попробуйте изменить эту последнюю строку на что-то вроде:
newDiv.find('input.datefield').attr('id', 'newDatePicker').attr('name', 'newDatePicker').datepicker();
комплексное решение, которое работает для меня.
//before
$('input.fecha').datepicker("destroy");
newcell.innerHTML = table.rows[0].cells[i].innerHTML;
//change de input id
$("input.fecha").attr("id", function (arr) {return "fecha" + arr;});
//after
$('input.fecha').datepicker({defaultDate: "+1w",changeMonth: true,numberOfMonths: 1, showOn: "button", buttonImage: "<?php echo base_url() ?>images/calendar.gif", buttonImageOnly: true, showLabel:false, dateFormat:"yy-mm-dd"});
и таблица html td.
<td><?php echo form_input(array('name' => 'fecha','id' => 'fecha','class' => 'fecha')); ?></td>
надеюсь, это поможет вам.
Добрый день
var dt = new Date();
var month = dt.getMonth();
var day = dt.getDate();
var year = dt.getFullYear()-5;
$newClone.children().children("#fna"+clickID)
.attr({
'id': 'fna1'+newID,
'name': 'fna'+newID,
'value': day + '-' + month + '-' + year
})
.datepicker("destroy")
.datepicker({
firstDay: 1,
changeMonth: true,
changeYear: true,
yearRange: 'c-100:c',
defaultDate: '-1y',
dateFormat: 'dd-mm-yy' ,
nextText: "Mes siguiente",
prevText: "Mes anterior",
monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'],
dayNamesMin: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa']
});
это может быть немного поздно, но все вышеперечисленные предложения не сработали для меня, я придумал простое решение для этого.
во-первых, что вызывает проблему: JQuery назначает datepicker идентификатору элемента. если вы клонируете элемент, то тот же id также может быть клонирован. что не нравится jQuery. Вы можете получить ошибку нулевой ссылки или дату, назначенную первому полю ввода, независимо от того, какое поле ввода вы нажмете на.
устранение:
1) уничтожить datepicker 2) назначить новые уникальные идентификаторы для всех полей ввода 3) назначить datepicker для каждого входа
убедитесь, что ваш вход что-то вроде этого
<input type="text" name="ndate[]" id="date1" class="n1datepicker">
прежде чем клонировать, уничтожить datepicker
$('.n1datepicker').datepicker('destroy');
после клонирования добавьте эти строки также
var i = 0;
$('.n1datepicker').each(function () {
$(this).attr("id",'date' + i).datepicker();
i++;
});
и происходит волшебство
Datepicker не делает, если идентификатор элемента изменен. Таким образом, лучше не изменять идентификатор элемента, если это необходимо. но если вам действительно нужно изменить идентификатор, и этот измененный идентификатор должен работать с datepicker, следуйте за ним:
$(selector).removeClass('hasDatepicker');
$(selector).datepicker({
changeMonth: true,
changeYear: true
});