jQuery可排序 - 在2个连接列表之间移动项目并保持计数

3

我有两个列表,每个列表都有六个项目,它们使用.connectedSortable类相连接。当我在这两个列表之间移动一个项目时,该项目将被添加到目标列表,并从源列表中删除。因此,现在我们拥有一个包含5个项目的列表和一个包含7个项目的列表。如何使每个列表保持6个项目,并仅将目标列表中顶部的项目移动到第一个列表中(自动按与其为一个列表时相同的顺序重新排列)?

<ul class="connectedSortable">
    <li class="ui-state-default">Item 1</li>
    <li class="ui-state-default">Item 2</li>
    <li class="ui-state-default">Item 3</li>
    <li class="ui-state-default">Item 4</li>
    <li class="ui-state-default">Item 5</li>
    <li class="ui-state-default">Item 6</li>
</ul>

<ul class="connectedSortable">
    <li class="ui-state-highlight">Item 1</li>
    <li class="ui-state-highlight">Item 2</li>
    <li class="ui-state-highlight">Item 3</li>
    <li class="ui-state-highlight">Item 4</li>
    <li class="ui-state-highlight">Item 5</li>
    <li class="ui-state-default">Item 6</li>
</ul>

$( ".connectedSortable" ).sortable({
    connectWith: ".connectedSortable"
}).disableSelection();

澄清一下:列表的数量可能是2个或更多。但我想要的是每个列表固定的6个项目,并且正确地自动重新排列,就像单个列表一样。例如,如果您将列表1中的项目3移动到列表2中的项目4后面,那么结果应该是这样的:

<ul class="connectedSortable">
    <li class="ui-state-default">Item 1</li>
    <li class="ui-state-default">Item 2</li>
    <li class="ui-state-default">Item 4</li>
    <li class="ui-state-default">Item 5</li>
    <li class="ui-state-default">Item 6</li>
    <li class="ui-state-default">Item 1</li>
</ul>

<ul class="connectedSortable">
    <li class="ui-state-highlight">Item 2</li>
    <li class="ui-state-highlight">Item 3</li>
    <li class="ui-state-highlight">Item 4</li>
    <li class="ui-state-highlight">Item 3</li>
    <li class="ui-state-highlight">Item 5</li>
    <li class="ui-state-default">Item 6</li>
</ul>

jsFiddle


你能详细解释一下你想要的是什么吗?如果你将“项目3”从源列表拖到目标列表,你希望在这两个列表中都看到什么出现? - mccannf
@mccannf 刚刚澄清了问题。 - Wonka
1个回答

3
您可以使用receive选项来实现这一点。以下代码假定有许多带有id="ulX"<ul>元素,其中X是从1开始的整数序列:
$(function() {
    $( ".connectedSortable" ).sortable({
        connectWith: ".connectedSortable",
        receive: function (event, ui) {
             var targetul = $(ui.item).parent().attr("id");
             var targetno = parseInt(targetul.split("ul")[1]);
             var sourceul = $(ui.sender).attr("id");
             var sourceno = parseInt(sourceul.split("ul")[1]);

             if (sourceno > targetno)
                 rippleUp(targetno, sourceno);
             else
                 rippleDown(targetno, sourceno);

        }
    }).disableSelection();
});


function rippleUp(start, end) {
    for (var i=start;i<end;i++) {
         $("#ul"+i+" > li").last().prependTo("#ul"+(i+1));
    }
}

function rippleDown(start, end) {
    for (var i=start;i>end;i--) {
         $("#ul"+i+" > li").first().appendTo("#ul"+(i-1));
    }
}

嗯...拖动几个项目后,它似乎无法正常工作(使用顶部的奇怪项目是可以的,因为它应该有6个项目)。例如,在上述情况下,将第3个项目移回到list1中的位置后,顺序会混乱。从那时起,一切都会混乱。如果还有第三个以上的列表,则代码无法处理它(添加/删除项目,忽略6个项目的限制)。这是一个fiddle:http://jsfiddle.net/5RjV5/7/。 - Wonka
@Wonka - 抱歉没有看到要求使用3个以上的列表。我已经进行了编辑,现在支持ui.sender。不过,就您的问题而言,它似乎已经可以工作了。您所说的“顺序混乱”是什么意思?如果您将任何项目从一个列表拖到另一个列表中,则目标列表中的第一个项目会附加到源列表中,对吗?您是否还有将项目拖回其原始列表的其他要求? - mccannf
嗯...尝试将列表3中的项目3拖到项目3下的列表2中,这应该会导致列表2中的项目5成为列表3中的第一个li,但它没有按预期工作。相反,它将列表2中的项目1移动到列表3的最后位置。我昨晚想出了这个完美的解决方案,但它只支持3个列表。我正在寻找像你的解决方案一样可以处理x个列表的方法:http://jsfiddle.net/5RjV5/8/ - Wonka
啊,现在我明白你想做什么了。更新了代码。将适用于任意数量的<ul>元素。 - mccannf

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