防止 JqueryUI 可排序中列表项的删除

问题描述 投票:0回答:8

我有两个列表

#sortable1
#sortable 2
,它们是连接的可排序项,如本示例所示。

您可以将列表项从

sortable1
拖放到
sortable 2
。但是,如果 sortable 1 中的项目包含“number”类,我想 prevent 放在 Sortable2 上,从而使拖动的项目落回到 sortable 1 中。

我在 sortable2 上使用了以下内容:

receive: function (event, ui) {
            if ($(ui.item).hasClass("number")) {
                $(ui.item).remove();
            }

但它会从两个表中完全删除列表项。任何帮助将不胜感激。

jquery jquery-ui drag-and-drop jquery-ui-sortable
8个回答
31
投票

对于将来阅读本文的任何人,正如briansol在已接受答案的评论中提到的那样,它会抛出错误

Uncaught TypeError: Cannot read property 'removeChild' of null

文档特别说明了

cancel()

取消当前可排序的更改并将其恢复到当前排序开始之前的状态。在 stopreceive 回调函数中很有用。

在其他事件期间取消排序是不可靠的,所以最好使用

receive
事件(如Mj Azanianswer所示)或使用
stop
事件,如下所示:

$('#list1').sortable({
  connectWith: 'ul',
  stop: function(ev, ui) {
    if(ui.item.hasClass("number"))
      $(this).sortable("cancel");
   }
}); 

$('#list2').sortable({
   connectWith: 'ul',
});  

演示


19
投票

您可以结合使用

stop
sortable('cancel')
方法来验证正在移动的项目。在这个例子中,当一个项目被丢弃时,我通过以下方式检查该项目是否有效:

  1. 检查该项目是否具有类别
    number
  2. 检查列表项是否已放入
    list2

这比我想要的要硬编码一些,所以您可以做的就是对照

this
检查掉落项目的父项,以检查列表是否不同。这意味着您可能在
number
list1
中拥有
list2
的项目,但它们不可互换。

jsFiddle 示例

$(function() {
    $('ul').sortable({
        connectWith: 'ul',
        stop: function(ev, ui) {
            if ($(ui.item).hasClass('number') && $(ui.placeholder).parent()[0] != this) {
                $(this).sortable('cancel');
            }
        }
    });        
});​

14
投票

尝试这个例子

$('#list1').sortable({
    connectWith: 'ul'
});    
    
$('#list2').sortable({
    connectWith: 'ul',
    receive: function(ev, ui) {
        if(ui.item.hasClass("number"))
          ui.sender.sortable("cancel");
    }
});    

1
投票

经过几次实验,我发现迄今为止最简单的方法是使用删除事件,该事件实际上仅在您尝试将项目放入新的可排序项时才会触发(之前使用 connectWith 作为目标) .

只需将其添加到您的可排序调用中即可:

remove:function(e,ui) {
    if(ui.item.hasClass('your_restricted_classname')) return false;
},

0
投票

如果您根本不需要拖动“number”类的项目,您还可以将整个拖放功能限制为不具有“number”类的项目:

$("#sortable1, #sortable2").sortable({
    connectWith: ".connectedSortable",
    items: "li:not(.number)"
});

您可以在这里尝试一下:http://jsfiddle.net/60gwjsgb/1/


0
投票
beforeStop: function(ev, ui) {
                if ($(ui.item).hasClass('number') && 
                    $(ui.placeholder).parent()[0] != this) {
                    $(this).sortable('cancel');
                }
            }

试试这个。


0
投票

如果a)你只有这两个列表,b)你不关心你的“数字”实际上被拖动然后又放回去,你可以简单地防止它被拖动:

 sort: function(event, ui) {
if(ui.item.hasClass('number')) return false;
}

0
投票

这是我的 2 美分。 如果您不希望允许在连接列表之一中进行排序,则可以在触发 start 时将其从实例对象的容器中删除,这样排序根本不会发生,并且如果您需要恢复排序之后,您可以再次重新创建可排序功能或在容器数组中添加回已删除的元素。它看起来像这样:

    start: function(e, ui){
        if(ui.item.hasClass('uniqToSortableItem')){
            var instance = $(this).sortable( "instance" );
            var newContainers = [];
            instance.containers.forEach((el)=> {
                if(!el.element.hasClass('sortableToDisable')){
                    newContainers.push(el);
                } 
            });
            // in case you need to save initial array just attach it to ui.helper
            ui.helper.initialContainersArray = instance.containers;
            instance.containers = newContainers;
        }
    },
    stop: function(e, ui){
        // returning containers array to previous state if necessary
        if(ui.helper.initialContainersArray){
            $(this).sortable( "instance" ).containers = ui.helper.initialContainersArray;
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.