Проблема при клонировании 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.. (тот, из которого он был клонирован).
Я пытался уничтожить экземпляр (inexisting) до этого:
newDiv.find('input.datefield').datepicker('destroy').datepicker();
Не повезло..
Я проверил, как он отслеживает экземпляры и вручную очищает данные следующим образом:
newDiv.find('input.datefield').data('datepicker', false).datepicker('destroy').datepicker();
По-прежнему не повезло.
Что я не понимаю, так это то, что только поведение выбора даты является ошибкой, все остальное работает так, как ожидалось.
Я действительно не знаю, что еще проверить сейчас.
Ответы
Ответ 1
Вот проблема. datepicker создает атрибуты идентификаторов на основе UUID для полей ввода, которые он связывает при его инициализации. Вы клонируете эти элементы, вы получаете больше элементов с одинаковым идентификатором (который не нравится jQuery) или другим идентификатором, если ваша рутина клонирования управляет этим (что означает, что datepicker не знает о клонах). Другими словами, datepicker только инициализирует все элементы, соответствующие вашему селектору, в момент его вызова. на самом деле не имеет смысла пытаться уничтожать/отключать/включать снова и снова, когда вы можете просто обернуть вызов init внутри любой функции, которую вы используете для создания клонов.
Поскольку мои функции клона обычно копируются из скрытых элементов DOM, а не из видимых, у меня есть роскошь, решающая, нужно ли связывать до или после клонирования. Итак, make #templateDiv - скрытый элемент на вашей странице с уже включенным элементом INPUT.
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();
}
и это в значительной степени делает это. Clone (true), когда это возможно, это сэкономит вам головные боли в долгосрочной перспективе.
Ответ 2
Это работает для меня с 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
not hadDatepicker
и в одно время вы написали mydiv
, а в следующий раз переменная mydiv
, которая не является одинаковой.
Ответ 3
Если вы вызываете .datepicker('destroy').removeAttr('id')
перед клонированием, а затем повторно запустите сборщик дат, он будет работать.
Кажется, это ошибка с уничтожением, поскольку она должна вернуть элемент обратно в исходное состояние.
Ответ 4
просто
$('input.datefield').datepicker("destroy");
перед клонированием div.
Затем после, вставляя клон, снова привяжите datepicker
$('input.datefield').datepicker();
своего рода "хакерское" решение, но оно отлично работает.
Ответ 5
$('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();
и он будет работать отлично!
Ответ 6
Как насчет изменения порядка?
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();
Честно говоря, я не знаю, как датпикер работает внутри. Я подозреваю, что он хранит что-то в хранилище JQuery DOM. Позвольте избежать его копирования любой ценой.
(У вас может быть длинная бизнес-логика между этими строками кода. Дело в том, что у вас есть резервная копия #someDiv, прежде чем положить на нее датупинг.)
Ответ 7
Удостоверьтесь, что ваш новый клонированный дампинг имеет другое имя и идентификатор, чем оригинал. Если оба они имеют одинаковое имя, то поведение, которое вы описываете, будет нормальным.
Попробуйте изменить эту последнюю строку на что-то вроде:
newDiv.find('input.datefield').attr('id', 'newDatePicker').attr('name', 'newDatePicker').datepicker();
Ответ 8
Полное решение, которое работает для меня.
//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>
Надеюсь, это поможет вам.
Добрый день
Ответ 9
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']
});
Ответ 10
Это может быть немного поздно, но все предложения, приведенные выше, не помогли мне, я придумал для этого легкое решение.
Во-первых, что вызывает проблему:
JQuery присваивает datepicker идентификатору элемента. если вы клонируете элемент, то тот же идентификатор также может быть клонирован. который 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++;
});
и происходит волшебство
Ответ 11
Datepicker не делает, если идентификатор элемента изменен. Поэтому лучше не изменять идентификатор элемента, если это необходимо. Но если вам действительно нужно изменить идентификатор, и этот измененный идентификатор должен работать с datepicker, то следуйте ему:
$(selector).removeClass('hasDatepicker');
$(selector).datepicker({
changeMonth: true,
changeYear: true
});