У меня очень простой вопрос. Используя sortable JQuery UI, я хочу отсортировать сразу два идентичных списка. Скажем, у меня есть два списка по 5 перетаскиваемых объектов в каждом. Сортировка одного списка также будет отсортировать другой список таким же образом. Есть ли способ сделать это с помощью JQuery UI?

У меня есть что-то вроде этого для начала ...

<div class="list1">
    <div class="quote1">1</div>
    <div class="quote2">2</div>
    <div class="quote3">3</div>
    <div class="quote4">4</div>
    <div class="quote5">5</div>
</div>

<div class="list2">
    <div class="quote1">1</div>
    <div class="quote2">2</div>
    <div class="quote3">3</div>
    <div class="quote4">4</div>
    <div class="quote5">5</div>
</div>

<script>
$(function() {
    $( ".list1" ).sortable();
    $( ".list1" ).disableSelection();

    $( ".list2" ).sortable();
    $( ".list2" ).disableSelection();
});
</script>
5
Yan Z 19 Дек 2013 в 01:15

2 ответа

Лучший ответ

Вы можете использовать одну процедуру для обоих списков, если вы используете идентификаторы для идентификации каждого списка, и классы для идентификации всех списков, которые можно отсортировать.

Обратите внимание, что в демонстрации jsFiddle вы изменили свой HTML.

демонстрация jsFiddle

Вот рабочий код:

var lst, pre, post; //lst == name of list being sorted

$(".sortlist").sortable({
    start:function(event, ui){
        pre = ui.item.index();
    },
    stop: function(event, ui) {
        lst = $(this).attr('id');
        post = ui.item.index();
        other = (lst == 'list1') ? 'list2' : 'list1';
        //Use insertBefore if moving UP, or insertAfter if moving DOWN
        if (post > pre) {
            $('#'+other+ ' div:eq(' +pre+ ')').insertAfter('#'+other+ ' div:eq(' +post+ ')');
        }else{
            $('#'+other+ ' div:eq(' +pre+ ')').insertBefore('#'+other+ ' div:eq(' +post+ ')');
        }
    }
}).disableSelection();

Пояснение:

  1. Когда вы перетаскиваете элемент, первое, что происходит, - это функция start:. Там мы берем текущую позицию индекса элемента и сохраняем ее как pre

  2. Когда элемент отбрасывается, выполняется функция stop:. Здесь мы хотим получить:
    а. Какой список мы сортируем
    б. НОВАЯ позиция индекса (теперь у нас есть позиция START и позиция STOP)
    c. Название списка другое

  3. ЕСЛИ post (НОВАЯ позиция индекса) больше, чем pre (ИСХОДНАЯ позиция):
    а. Мы перемещаем элемент ВНИЗ, поэтому ...
    б. Когда мы программно перемещаем элемент в другом списке, мы должны использовать insertAfter
    ИНАЧЕ
    а. Мы перемещаем элемент вверх по списку, поэтому
    б. Мы должны использовать метод insertBefore при перемещении элемента в другой список.

  4. Внутри оператора if значения переменных сообщают jQuery, какой элемент переместить и куда его поместить. Это может помочь увидеть код БЕЗ переменных. Итак, в качестве примера, если я перемещу первый элемент в List1 в конец списка, вот что мы хотим, чтобы jQuery сделал с другим списком:

$('#list2 div:eq(0)').insertAfter('#list2 div:eq(4)');

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

8
cssyphus 18 Дек 2013 в 22:49

Это решение работает в режиме реального времени при перетаскивании:

var currentIndex;
$(function() {
    $( ".list" ).sortable({
        start: function(event, ui) { 
            currentIndex = ui.helper.index();
        },
        change: function( event, ui ) { 
            var indexCount = ui.item.parent().find('div:not(.ui-sortable-helper)');
            var sortClass = '.'+ui.item.attr('class').split(' ')[0];
            var parent = $('.list').not(ui.item.parent());
            if(currentIndex > ui.placeholder.index()){
                parent.find('div').eq(indexCount.index(ui.placeholder)).before(parent.find(sortClass));
            }
            else
                parent.find('div').eq(indexCount.index(ui.placeholder)).after(parent.find(sortClass));
            currentIndex = ui.placeholder.index();
        }
    });
    $( ".list" ).disableSelection();
});

http://jsfiddle.net/trevordowdle/EXk7T/2/

2
Trevor 18 Дек 2013 в 22:34