JQuery sortable получает 2 элемента, которые меняются местами

Я не могу узнать, как получить целевой элемент с jQuery UI sortable.

    $("#pages").sortable({
        opacity: 0.6,
        update: function(event, ui) {
            var first = ui.item; // First element to swap
            var second = ???? // Second element to swap
            swapOnServer(first, second);
        }
    });

Все параметры, которые я пробовал, указывают на перетаскиваемый элемент, но не тот, с которым он обменивается: ui.item[0], event.srcElement, event.toElement.

Кроме того, this указывает на элемент LIST (OL).

Говоря второй, я имею в виду следующее:

Оригинальный заказ:

| 0 | 1 | 2 | 3 |

Мы перетаскиваем элемент 1 и опускаем его в положение 3. Который закончится:

| 0 | 3 | 2 | 1 |

Итак, первый элемент равен 1, а второй - 3 (НЕПРАВИЛЬНО! см. ниже).

ОБНОВЛЕНИЕ: Я понял, что понял, что это неправильно. Новый порядок в этом случае будет.

| 0 | 2 | 3 | 1 |

В результате мой вопрос не имеет смысла. Спасибо всем за помощь. Я буду отмечать голос и отмечать ответ.

Итак, вопрос в том, как получить здесь второй элемент?


ТЕКУЩАЯ ПРОГРАММА (как нет условия для обмена в сортируемом) ниже. Он использует временный массив с заказами.

    var prevPagesOrder = [];
    $("#pages").sortable({
        start: function(event, ui) {
            prevPagesOrder = $(this).sortable('toArray');
        },
        update: function(event, ui) {
            var currentOrder = $(this).sortable('toArray');
            var first = ui.item[0].id;
            var second = currentOrder[prevPagesOrder.indexOf(first)];
            swapOnServer(first, second);
        }
    });

Спасибо,
Дмитрий.

Ответы

Ответ 1

На самом деле нет "второго" элемента. У вас есть предмет, и вы просто помещаете его в другое место. Предметы вокруг него соответственно корректируют свои позиции. Если вы хотите получить массив всех элементов, вы можете использовать метод toArray.

Ответ 2

Попробуйте использовать функцию serialize, которая дает вам хэш списка элементов в порядке.

Если вам просто нужен элемент, который новый элемент будет удален, прежде чем вы сможете это сделать:

$("#pages").sortable({
    opacity: 0.6,
    update: function(event, ui) {
        var first = ui.item; // First element to swap
        var second = ui.item.prev();
        swapOnServer(first, second);
    }
});

second будет null, если его в начале списка.

Ответ 3

взгляните на "Swapable" плагин jQuery:

http://plugins.jquery.com/project/Swapable

Он похож на "Sortable", но затронуты только два элемента выбранной группы: перетащил элемент и сбросил тот, который был заменен. Все остальные элементы остаются на своих нынешних позициях. Этот плагин построен на основе существующего "Sortable" плагина jQuery и наследует все возможности сортировки.

Ответ 4

Вы можете использовать draggable и droppable вместо sortable для достижения эффекта с возможностью замены. На практике это будет выглядеть следующим образом:

(function() {
    var droppableParent;

    $('ul .element').draggable({
        revert: 'invalid',
        revertDuration: 200,
        start: function () {
            droppableParent = $(this).parent();

            $(this).addClass('being-dragged');
        },
        stop: function () {
            $(this).removeClass('being-dragged');
        }
    });

    $('ul li').droppable({
        hoverClass: 'drop-hover',
        drop: function (event, ui) {
            var draggable = $(ui.draggable[0]),
                draggableOffset = draggable.offset(),
                container = $(event.target),
                containerOffset = container.offset();

            $('.element', event.target).appendTo(droppableParent).css({opacity: 0}).animate({opacity: 1}, 200);

            draggable.appendTo(container).css({left: draggableOffset.left - containerOffset.left, top: draggableOffset.top - containerOffset.top}).animate({left: 0, top: 0}, 200);
        }
    });
} ());

Демо, http://jsfiddle.net/FZ42C/1/.