jQuery UI - клонировать список для удаления / сортировки после события перетаскивания

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

Взгляните на эту урезанную скрипку: http://jsfiddle.net/DKBU9/1/ ( пропущено sortable ())

HTML

<ul id="draggables">

    <li>foo1</li>
    <li>foo2</li>
    <li>foo3</li>

</ul>

<ul class="droppable new">

</ul>

JS

$('#draggables > li').draggable({
    appendTo: 'document',
    revert: 'invalid'
});

$('.droppable > li').draggable({
    appendTo: 'document',
    revert: 'invalid'
});

$('#draggables').droppable({
    accept: '.droppable > li',
    drop: function(event, ui) {
        ui.draggable.detach().css({top: 0,left: 0}).appendTo($(this));
    } 
});

$('.droppable').droppable({
    accept: '#draggables > li',
    drop: function(event, ui) {
        if($(this).hasClass('new')) {
            var clone = $(this).clone(true, true);
            $(this).removeClass('new').after(clone);
        }
        ui.draggable.detach().css({top: 0,left: 0}).appendTo($(this));    
    }
});

Как видите, перетаскивание работает для начальных элементов, но не сохраняется в клоне. Я думал clone(true, true) скопировал совпадающие и дочерние элементы и их обработчики событий.

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

В конечном итоге я хочу иметь возможность перетаскивать между списком «пул» и клонированными списками и между самими клонированными списками, а также сортировать элементы в клонированных списках.


person Bobe    schedule 07.01.2014    source источник


Ответы (1)


Взгляните на эту скрипку.

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

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

В этом случае проще просто добавить отбрасываемое событие после клонирования.

Новая функция:

function initDrop($element)
{
    $element.droppable({
        accept: '#draggables > li',
        drop: function(event, ui) {
            if($(this).hasClass('new')) {
                var clone = $(this).clone();                
                $(this).after(clone);
                $(this).removeClass('new');
                initDrop( clone );
            }
            ui.draggable.detach().css({top: 0,left: 0}).appendTo($(this));    
        }
    });
}

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

person acarlon    schedule 07.01.2014
comment
Отлично работает, спасибо. Думаю, теперь я немного лучше понимаю clone (). Я читал эту часть о плагинах, но я как бы бегло ее рассмотрел. Отчасти поэтому моя попытка выполнить аналогичную рекурсивную функцию потерпела неудачу. Можно ли добавить к этому sortable ()? Я только что привязал его к концу функции droppable (), но draggable () имеет прецедент для события перетаскивания. - person Bobe; 07.01.2014
comment
@Bobe - Рад помочь. Возможна совместная работа sortable () и droppable (). Возможно, вы захотите попробовать и опубликовать новый вопрос SO, если у вас возникнут проблемы. Если вы это сделаете, вы можете разместить ссылку в комментариях здесь, и я посмотрю. - person acarlon; 07.01.2014
comment
Я потратил на это много времени, но так и не смог добиться желаемого результата. Я создал новый вопрос, если вы хотите взглянуть: stackoverflow.com/questions/20986157/ - person Bobe; 08.01.2014