【问题标题】:Prevent drop of list item in JqueryUI sortable防止在可排序的 JqueryUI 中删除列表项
【发布时间】: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();
            }

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

【问题讨论】:

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


    【解决方案1】:

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

    1. 检查项目是否具有number
    2. 检查列表项是否被丢弃在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 Azanianswer所示的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("取消"); } });

                【讨论】:

                  猜你喜欢
                  • 2011-07-29
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-07-18
                  • 2012-03-20
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-07-19
                  • 1970-01-01
                  相关资源
                  最近更新 更多