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

Posted

技术标签:

【中文标题】防止在可排序的 JqueryUI 中删除列表项【英文标题】:Prevent drop of list item in JqueryUI sortable 【发布时间】:2012-07-31 10:09:02 【问题描述】:

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

您可以将列表项从sortable1 拖放到sortable 2。但是,如果 sortable 1 中的项目包含“数字”类,我想 防止 Sortable2 上的下降,从而使拖动的项目回到sortable 1

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

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

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

【问题讨论】:

【参考方案1】:

您可以结合使用stopsortable('cancel') 方法来验证正在移动的项目。在this example 中,当物品被丢弃时,我通过以下方式检查该物品是否有效:

    检查项目是否具有number检查列表项是否被丢弃在list2

这是我想要的稍微硬编码的代码,因此您也可以根据this 检查已删除项目的父项,以检查列表是否不同。这意味着您可能在 list1list2 中拥有 number 项,但它们不可互换。

jsFiddle Example

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

【讨论】:

使用这种方法,我似乎得到了 JS 错误。我已经更新了 jQUI 网站上可能相关的错误报告。 bugs.jqueryui.com/ticket/4904?cnum_edit=9#comment:9 cancel 仅在this other answer 中提到的stopreceive 事件中可靠 this.sortable 对我不起作用,但是当更改为 ui.sender.sortable("cancel"); id 完美运行 出现错误:未捕获的类型错误:无法读取 null 的属性“removeChild”。它破坏了可排序... @Mr.Jo 我已经更新了上面的例子,希望能解决这个错误。【参考方案2】:

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

    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;
        
    

【讨论】:

【参考方案3】:

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

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

【讨论】:

【参考方案4】:
beforeStop: function(ev, ui) 
                if ($(ui.item).hasClass('number') && 
                    $(ui.placeholder).parent()[0] != this) 
                    $(this).sortable('cancel');
                
            

试试这个。

【讨论】:

【参考方案5】:

对于将来阅读此内容的任何人,如 cmets 中的 briansol 所提到的已接受答案,它会引发错误

Uncaught TypeError: Cannot read property 'removeChild' of null

文档特别说

cancel()

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

在其他事件期间取消排序是不可靠的,所以最好使用Mj Azani的answer所示的receive事件或使用stop事件如下:

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

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

Demo

【讨论】:

【参考方案6】:

经过几次实验,我发现到目前为止,最简单的方法是使用 remove 事件,它基本上只会在您尝试将项目放入新的可排序对象时触发(之前使用连接)。

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

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

【讨论】:

【参考方案7】:

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

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

你可以在这里试试:http://jsfiddle.net/60gwjsgb/1/

【讨论】:

【参考方案8】:

试试this example

$('#list1').sortable( 连接:'ul' ); $('#list2').sortable( 连接:'ul', 接收:函数(ev,ui) 如果(ui.item.hasClass(“数字”)) ui.sender.sortable("取消"); );

【讨论】:

以上是关于防止在可排序的 JqueryUI 中删除列表项的主要内容,如果未能解决你的问题,请参考以下文章

Jquery ui - 可排序:在可排序元素中按图标“句柄”拖动

不允许在可排序列表中排序,仅使用 connectWith 将它们移动到不同的可排序列表

jQuery - 在可排序列表中操作删除的元素

禁用 jQueryUI 中嵌套可排序项的拖动冒泡

jQuery Sortables 不从列表中删除

为 jquery ui 可排序列表中的每个项目添加一个删除按钮