Nestable list - 禁止将子项移出父元素

Den*_*lew 9 javascript jquery drag-and-drop jquery-nestable

我的列表允许从子项移出子项,我想更改它.

在此输入图像描述

如您所见,应允许将子项从父项内部移动到另一项父项,但不应允许在子项之外移动子项.

我认为代码太长了,所以这里是可嵌套列表,类似于我使用Luna主题nestableList,这里是脚本jquery.nestable.js

Hak*_*tık 5

Note 1在阅读这个答案之前参考另一个答案,它真的很有用,对我帮助很大。 注意 2正如那个答案所说,以及原始库的作者,那个库已经完全死了。但是有人负责继续开发这个库,这里是新库
注 3即使新库不支持拒绝规则,你仍然必须使用库的拉取请求。

我遇到了与提问者完全相同的情况(这也是我到达这里的原因)。这是我解决问题的方法(我希望这会对其他人有所帮助)

回答

HTML

<div class="dd" id="nestable-example">
    <ol class="dd-list">

        <li class="dd-item" data-id="0" data-type="root">
            <div class="dd-handle">Root 0</div>
            <ol class="dd-list">
                <li class="dd-item" data-id="1" data-type="child">
                    <div class="dd-handle">Child 1</div>
                </li>
                <li class="dd-item" data-id="2" data-type="child">
                    <div class="dd-handle">Child 2</div>
                </li>
                <li class="dd-item" data-id="3" data-type="child">
                    <div class="dd-handle">Child 2</div>
                </li>
            </ol>
        </li>

        <li class="dd-item" data-id="4" data-type="root">
            <div class="dd-handle">Root 4</div>
            <ol class="dd-list">
                <li class="dd-item" data-id="5" data-type="child">
                    <div class="dd-handle">Child 5</div>
                </li>
                <li class="dd-item" data-id="6" data-type="child">
                    <div class="dd-handle">Child 6</div>
                </li>
            </ol>
        </li>

    </ol>
</div>
Run Code Online (Sandbox Code Playgroud)

JavaScript

$('#nestable-example').nestable({
    group: 'categories', // you can change this name as you like
    maxDepth: 2,   // this is important if you have the same case of the question
    reject: [{
        rule: function () {
            // The this object refers to dragRootEl i.e. the dragged element.
            // The drag action is cancelled if this function returns true
            var ils = $(this).find('>ol.dd-list > li.dd-item');
            for (var i = 0; i < ils.length; i++) {
                var datatype = $(ils[i]).data('type');
                if (datatype === 'child')
                    return true;
            }
            return false;
        },
        action: function (nestable) {
            // This optional function defines what to do when such a rule applies. The this object still refers to the dragged element,
            // and nestable is, well, the nestable root element
            alert('Can not move this item to the root');
        }
    }]
});
Run Code Online (Sandbox Code Playgroud)


HiD*_*Deo 4

在您提供的示例中,使用的 jQuery 插件是来自 dbushell 的 Nestable。您对最终使用的插件有控制权吗?该项目已经彻底死了,已经2年没有更新了。

明智的做法是检查仍然维护的解决方案并提出您的功能,这几乎是当今许多库都具有的“protectRoot”功能。

如果您无法控制该插件,则此功能目前尚未实现,并且可能永远不会实现。

如果您可以控制该插件但仍然想使用这个插件,一种解决方案可能是使用仍然维护并具有此功能的分叉(由于该项目已终止,有很多分叉)。

另一个解决方案是从提交给项目的许多拉取请求中挑选您感兴趣的代码,但这些代码永远不会被合并。

例如,此拉取请求添加了新的回调,而不是目前唯一可用的回调:beforeDragStartdragStartdragMovebeforeDragEnddragEnd等。这些新回调提供了许多参数,例如您当前正在移动的项目,以及您开始拖动它之前的位置,和目的地。根据这些新信息,尤其是目的地,如果目的地是根节点,您可以取消拖动。

$('.dd').nestable({})
.on('dragMove', function(event, item, source, destination) {
    // item: item we're moving.
    // source: original source of the item.
    // destination: new position of the item.
});
Run Code Online (Sandbox Code Playgroud)

另一种可以满足您需求的拉取请求是这个。它提供回调来拒绝特定的拖动事件,例如,如果被拖动的项目成为根元素,您可以拒绝拖动事件。

$('.dd').nestable({
  reject: [
    {
      rule: function() { 
        // $(this) refers to the dragged element. 
        // Return TRUE to cancel the drag action.

        return $(this).parent().hasClass("rootList");
      }
    }
  ]
});
Run Code Online (Sandbox Code Playgroud)