При клонировании перетаскиваемого объекта в пользовательском интерфейсе jQuery, как вы можете перенести данные и события в новый элемент?
У меня есть перетаскиваемый элемент с набором helper: 'clone'
, но когда он клонирует элемент, ни один из data()
или событий не сохраняется в новом элементе.
Я пробовал несколько способов повторно привязать data()
, но я не могу выбрать новый элемент, а также старый элемент в том же самом выражении.
Например, я могу выбрать начальный элемент в перетаскиваемом событии stop()
:
$blah.draggable({
helper: 'clone',
stop: function(ev, ui) {
var oldData = $(ev.target).data('blah');
}
});
И я также могу получить новый элемент в событии droppable drop()
:
$blah.droppable({
drop : function(ev, ui) {
var $newElement = ui.draggable;
}
});
Но я не могу понять, как получить оба в одном и том же случае.
Что бы я хотел сделать, так это передача данных, например:
$newElement.data('blah', $oldElement.data('blah'));
Или иначе сделайте данные постоянными, как вы можете с помощью $blah.clone(true);
Ответы
Ответ 1
Чтобы получить доступ к данным исходного элемента в drop, вы можете использовать ui.draggable.context. В приведенном ниже примере контекст будет ссылаться на исходный элемент перетаскивания, и у вас есть доступ ко всему его содержимому. Draggable ссылается на новый элемент, который отбрасывается.
$("#droppable").droppable({
drop: function(ev, ui) {
console.log(ui);
console.log(ui.draggable.context);
console.log($(ui.draggable.context).data('pic'));
}
});
Ответ 2
Я не слишком много работал с droppable, но не мог бы вы просто сделать что-то вроде этого?
$(".draggable").draggable({
helper: 'clone'
});
$("#droppable").droppable({
drop: function(ev, ui) {
$(this).append(ui.draggable.clone(true));
}
});
Кажется, работает, если там что-то не хватает:
http://jsfiddle.net/hasrq/
Ответ 3
Оказывается, проблема была сортируемой, а не draggable/droppable (позже я добавлял сортировку, но понял, что это не часть проблемы здесь, поэтому я оставил ее из исходного вопроса).
В итоге я использовал некоторую комбинацию решения @kingjiv выше, а также не самый лучший хак, но, по крайней мере, он работает:
$blah.sortable({
receive: function(ev, ui) {
// setting a global variable here
MyGlobals.cloneCache = ui.item.clone(true);
},
stop: function(ev, ui) {
$(ui.item).replaceWith(MyGlobals.cloneCache);
}
});
Идея состоит в том, что вы сначала клонируете исходный элемент в событии receive()
, кешируете это в переменной, а затем заменяете элемент на событие stop()
.
Вид уродливый, но по крайней мере он работает.
Ответ 4
ui.item
относится к перетаскиваемому элементу. Когда объект перетаскивается, нет встроенного способа доступа к целевому элементу из функции receive
. Однако есть немного хакерский способ, как это сделать:
$blah.sortable({
receive: function (ev, ui) {
var $target = $(this).data().sortable.currentItem;
var $source = $(ui.sender);
// now you can copy data from source to target
$target.data('data-item', $source.data('data-item'));
}
});