Пользовательский интерфейс jQuery: отмена сортировки при отбрасывании

#javascript #jquery #jquery-ui #jquery-ui-sortable #jquery-droppable

#javascript #jquery #jquery-ui #jquery-ui-sortable #jquery-droppable

Вопрос:

Я использую jQuery 1.5.1 и jQuery UI 1.8.11.

Я добавил сортировку для ряда элементов — задача здесь состоит в том, чтобы разрешить перетаскивание для сортировки, все это работает нормально.

Но я также хочу включить отбрасывание, чтобы элемент можно было отбросить в область «копировать меня» — задача там будет дублировать элемент (я доработаю это позже)

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

Что я хочу сделать, так это отменить эту сортировку при срабатывании события drop.

Вы можете увидеть мою проблему в действии здесь (просто перетащите «Элемент 1» в область «Отбросить для копирования элемента», и вы увидите, что сортировка не отменяется)

Как вы можете видеть, я попробовал следующее в отбрасываемом событии «drop» (предлагается из документов jQuery UI), но, похоже, это не работает…

 $(this).sortable('cancel');
  

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

Спасибо

Комментарии:

1. Что вы подразумеваете под отменой? Отмена остановит сортировку и оставит то, что вы сортировали, в том месте, где вы его оставили.

2. @jQuerybeast: Да, это то, что я хочу, «отмена» вернет элемент в исходное пространство. Итак, в моем JSFiddle, если вы попытаетесь скопировать элемент 1, произойдет копирование, и item1 должен вернуться к началу … в тот момент, когда он перемещается вниз, поскольку это была последняя позиция выделения перед событием удаления

3. Отмена работает не с сортировкой, а с перетаскиванием. В sortable вы можете отменить / остановить всю функцию.

4. @jQuerybeast: Да, я зашел так далеко, попробовав отменить в исходном контейнере DIV. Это привело к возврату элемента, но остановило работу сортировки. Итак, я подумал, может быть, я мог бы отменить, а затем повторно добавить сортируемую функцию — но это, похоже, тоже не работает (оно не добавляется повторно). Есть идеи?

5. @jQuerybeast: мне удалось найти решение моей проблемы и опубликовать свой собственный ответ. На всякий случай, если вам интересно посмотреть, как я это сделал 😉

Ответ №1:

Хорошо, итак, я разработал решение, которое выполняет эту работу.

код отмены работает, если он есть в событии «stop» функции сортировки. Однако это будет применяться только после завершения «возврата». Проблема в том, что я пытался скопировать / вернуть элемент из отбрасываемого события «drop», и это было слишком рано.

Решение состоит в том, чтобы дождаться завершения события «stop», и для достижения этой цели мне пришлось создать флаг «ожидание копирования», который будет проверяться в событии «stop».

Вот пример

Это все еще кажется неправильным (с точки зрения UX), но работает правильно, и вы всегда можете установить для функции сортировки значение revert равным false, чтобы получить немного лучшее представление.

Код из примера выглядит следующим образом…

 var itemCount = 3;
var awaitingCopy = false;

$(init);

function init() {
    $("#Items").sortable({
        revert: true,
        placeholder: "ItemPlaceHolder",
        opacity: 0.6,
        start: StartDrag,
        stop: StopDrag
    });

    $("#CopyItem").droppable({
        hoverClass: "CopyItemActive",
        drop: function(event, ui) {
            awaitingCopy = true;
        }
    });

    $("#NewItem").click(function(e) {
        e.preventDefault();
        itemCount  ;
        var element = $("<div class='Item'>Item "   itemCount   "</div>");
        $("#Items").append(element);
        element.hide().slideDown(500);
    });
}

function CopyItem(element) {
    awaitingCopy = false;
    var clone = element.clone();
    $("#Items").append(clone);
    clone.hide().slideDown(500);
}

function StartDrag() {
    $("#NewItem").hide();
    $("#CopyItem").show();
}

function StopDrag(event, ui) {
    if (awaitingCopy) {
        $(this).sortable('cancel');
        CopyItem($(ui.item));
    }
    $("#NewItem").show();
    $("#CopyItem").hide();
}
  

В любом случае, надеюсь, это поможет другим, кто хочет такого же эффекта… однако не крадите мой дизайн 😉

Комментарии:

1. Это помогло мне найти решение, но я просто хотел бы отметить, что глобальная переменная была ненужной — похоже, вы не использовали правильный селектор jQuery. Вместо $(this). sortable(‘отмена’);, это должно было быть $(«#Items»).sortable(‘отмена’);