防止JqueryUI中的列表项丢弃可排序

时间:2012-08-02 12:27:34

标签: jquery jquery-ui drag-and-drop jquery-ui-sortable

我有两个列表#sortable1#sortable 2,它们是可连接的排序,如example所示。

您可以将列表项从sortable1拖放到sortable 2。但是,如果可排序1 中的项目包含“数字”类,我想阻止 Sortable2 的下拉,从而制作拖动的项目退回 sortable 1

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

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

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

8 个答案:

答案 0 :(得分:27)

对于将来阅读此内容的人,正如briansol在对已接受答案的评论中提到的那样,它会引发错误

Uncaught TypeError: Cannot read property 'removeChild' of null

文档特别说

  

cancel()

     

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

在其他活动期间取消排序是不可靠的,因此最好使用receiveMj Azani中显示的answer事件,或使用stop事件,如下所示:

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

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

Demo

答案 1 :(得分:18)

您可以结合使用beforeStopsortable('cancel')方法来验证要移动的项目。在this example中,在删除项目时,我通过以下方式检查项目是否有效:

  1. 检查项目是否具有班级number
  2. 检查列表项是否已在list2
  3. 中删除

    这是我想要的稍微硬编码,所以你可以做的是检查被删除项目的父对this,以检查列表是否不同。这意味着您可能在numberlist1中拥有list2项,但它们不可互换。

    jsFiddle Example

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

答案 2 :(得分:13)

尝试this example

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

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

答案 3 :(得分:1)

经过几次实验后,我发现到目前为止最简单的方法是使用remove事件,当你试图将一个项目放入一个新的sortable(以前可以作为一个目标使用)时,它基本上只会触发connectWith)。

只需将此添加到您的可排序电话:

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

答案 4 :(得分:0)

如果您不需要能够使用课程"数字"来拖动项目。完全可以,您还可以将整个拖放功能限制为不具有该类"数字":

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

您可以在此处试用:http://jsfiddle.net/60gwjsgb/1/

答案 5 :(得分:0)

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

试试这个。

答案 6 :(得分:0)

如果a)仅只有这两个列表,并且b)不在乎您的“数字”实际上是被拖动然后回落,则可以简单地防止它被此拖动:

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

答案 7 :(得分:0)

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

    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;
        }
    }