проблема при клонировании JQuery UI DatePicker - PullRequest
15 голосов
/ 14 марта 2010

У меня есть div, в котором есть указатель даты. Я использую что-то вроде этого, чтобы клонировать это:

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();

Это урезанная версия моего кода. Он работает, и календарь отображается, как и ожидалось, там, где он ожидается ... но при нажатии на дату значение предыдущий указатель даты обновляется .. (то, с которого оно было клонировано).

Я пытался уничтожить (несуществующий) экземпляр раньше, как это:

newDiv.find('input.datefield').datepicker('destroy').datepicker();

Не повезло ..

Я проверил, как он отслеживает экземпляры, и вручную очистил данные следующим образом:

newDiv.find('input.datefield').data('datepicker', false).datepicker('destroy').datepicker();

Все еще не повезло.

Чего я не понимаю, так это того, что только поведение при выборе даты глючит, все остальное работает как положено.

Я действительно не знаю, что еще проверить сейчас ..

Ответы [ 12 ]

39 голосов
/ 14 марта 2010

Это работает для меня с 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, что не совпадает.

26 голосов
/ 27 марта 2010

Вот проблема. datepicker создает атрибуты идентификатора на основе UUID для полей ввода, которые он связывает при инициализации. Клонирование этих элементов приводит к появлению большего количества элементов с одинаковым идентификатором (который не нравится jQuery) или с другим идентификатором, если ваша процедура клона управляет этим (что означает, что средство выбора даты не знает о клонах). Другими словами, datepicker только инициализирует все элементы, соответствующие вашему селектору, в тот момент, когда вы его вызываете. на самом деле не имеет смысла пытаться уничтожать / отключать / включать снова и снова, когда вы можете просто обернуть init вызов внутри любой функции, которую вы используете для создания клонов.

Поскольку мои функции клонирования обычно копируют из скрытых элементов DOM, а не из видимых, я могу позволить себе роскошь решать, нужно ли связывать до или после клонирования. Итак, сделайте #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();
}

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

7 голосов
/ 12 марта 2012

Если вы позвоните .datepicker('destroy').removeAttr('id') перед клонированием, а затем повторно запустите средство выбора даты, оно будет работать.

Это похоже на ошибку в destroy, так как предполагается, что элемент возвращается в исходное состояние.

3 голосов
/ 19 июня 2010

просто сделай

$('input.datefield').datepicker("destroy");

до клонирования div. Затем после вставки клона снова свяжите указатель даты

$('input.datefield').datepicker();

вроде "хакерского" решения, но оно отлично работает.

1 голос
/ 30 мая 2018

Вот как это у меня сработало:

Сначала вам нужно удалить класс hasDatepicker из клонированных элементов, потому что это то, что мешает DatePicker присоединяться к определенному элементу.

Затем вы должны удалить атрибут id из каждого из клонированных элементов, иначе .datepicker () будет предполагать, что datepicker добавлен в этот элемент.

После этого вызова. datepicker () для клонированного элемента.

newDiv.find('.classAttributeGivenForDatepicker').each(function() {
   $(this).removeAttr('id').removeClass('hasDatepicker');
   $(this).datepicker({dateFormat: 'dd-mm-yy', minDate: 0, autoclose: true,});
});
1 голос
/ 27 октября 2010
$('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();

и будет отлично работать!

0 голосов
/ 01 февраля 2017

Datepicker не делает, если ID элемента изменен. Поэтому лучше не менять id элемента, если это необходимо. Но если вам действительно нужно изменить идентификатор, и этот измененный идентификатор должен работать с DatePicker, тогда следуйте ему :

$(selector).removeClass('hasDatepicker');
$(selector).datepicker({
  changeMonth: true,
  changeYear: true
});
0 голосов
/ 17 июня 2013

Это может быть немного поздно, но все вышеизложенные предложения не сработали для меня, я нашел простое решение для этого.

Во-первых, что вызывает проблему: JQuery назначает указатель даты идентификатору элемента. если вы клонируете элемент, то такой же идентификатор может быть также клонирован. который jQuery не любит. Вы можете получить либо ошибку нулевой ссылки, либо дату, назначенную первому полю ввода, независимо от того, в каком поле ввода вы щелкнули.

Решение:

1) уничтожить DatePicker 2) назначить новые уникальные идентификаторы для всех полей ввода 3) назначить указатель даты для каждого ввода

Убедитесь, что ваш ввод примерно такой

<input type="text" name="ndate[]" id="date1" class="n1datepicker">

Прежде чем клонировать, уничтожьте сборщик дат

$('.n1datepicker').datepicker('destroy');

После того, как вы клонируете, добавьте также эти строки

var i = 0;
$('.n1datepicker').each(function () {
    $(this).attr("id",'date' + i).datepicker();
    i++;
});

и происходит волшебство

0 голосов
/ 19 декабря 2012
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']
    });
0 голосов
/ 08 ноября 2012

Полное решение, которое работает для меня.

//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>

Надеюсь, это поможет вам.

Добрый день

...