使用Jquery UI sortable同时对两个列表进行排序

5

我有一个非常简单的问题。使用Jquery UI的sortable,我想同时对两个相同的列表进行排序。假设我有两个每个都有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>

你可能需要使用排序事件回调来更新第二个列表。离题:你上面的代码可以简化为 $('.list1, .list2').sortable().disableSelection(); - isherwood
2个回答

8
如果您使用ID来标识每个列表,并使用类来标识所有可以排序的列表,则可以使用一个例程来处理这两个列表。
请注意,在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: 函数。在此函数中,我们需要获取:
    a. 我们正在排序的列表
    b. 新的索引位置(现在我们有了起始位置和停止位置)
    c. 另一个列表的名称

  3. 如果 post(新的索引位置)大于 pre(原始位置):
    a. 我们正在向下移动项目,因此...
    b. 当我们以编程方式在另一个列表中重新定位项目时,必须使用 insertAfter
    否则
    a. 我们正在向上移动项目,因此
    b. 在将项目移动到另一个列表中时,我们必须使用 insertBefore 方法。

  4. if 语句内部,变量值告诉 jQuery 要移动哪个项目以及将其放置在哪里。可能看到没有变量的代码会更有帮助。例如,如果我将 List1 中的第一个项目移动到列表底部,这是我们希望 jQuery 在另一个列表中执行的操作:

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

希望这有所帮助。


谢谢!它在jsFiddle上肯定是有效的,但是从If语句开始,我的大脑似乎无法理解你的代码在做什么,哈哈。 - Yan Z
请提供更多的上下文和要求,以便我能够准确地翻译您所需的内容。 - cssyphus

2

当您拖动时,此解决方案可以实时工作:

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/


@YanZhao 一个展示列表拖动时变化的解决方案。很开心让它正常工作了。 - Trevor
1
做得非常好,Trevor。+1 有趣的是看到我们代码中的差异 - 我从你的代码中学到了一些技巧。这绝对是一个愉快的练习。 - cssyphus
@gibberish 谢谢,你比我快! - Trevor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接