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

时间:2016-07-09 09:38:08

标签: javascript jquery drag-and-drop jquery-nestable

我的列表允许将子项移出父项,我想更改它。

enter image description here

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

我认为代码太长了,所以这里的嵌套列表与我使用nestableList from Luna theme类似,这里是脚本jquery.nestable.js

3 个答案:

答案 0 :(得分:4)

注意1 在阅读本答案之前参考other答案,它非常有用,对我帮助很大。 注意2 正如那个答案所说,original library的作者,那个图书馆完全死了。但是有人负责继续开发这个图书馆,这里是new library 注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>

<强>的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');
        }
    }]
});

答案 1 :(得分:3)

In the example you provided, the jQuery plugin used is Nestable from dbushell. Do you have any control over the plugin you'll end up using ? The project is completely dead and has not been updated for 2 years.

It could be wise to maybe check for a solution still maintained and proposing your feature which is pretty much a 'protectRoot' feature that many libraries have nowadays.

If you have no control over the plugin, this feature at the moment is not implemented and will probably never be.

If you have control over the plugin but still want to use this one, a solution could be to use a fork (there are many since the project is dead) still maintained and having this feature.

Another solution would be to cherry pick yourself code you're interested in from the many pull requests submitted to the project but that will never be merged.

For example, this pull request add new callbacks instead of the only one available at the moment: beforeDragStart, dragStart, dragMove, beforeDragEnd, dragEnd, etc. These new callbacks provides many arguments like the item you're currently moving, where it was before you started dragging it, and the destination. Based on these new informations and especially the destination, you could cancel the drag if the destination a root node.

$('.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.
});

Another pull request that could suits your needs is this one. It provides callback to reject specific drag event, you could for example reject a drag event if the item being dragged becomes a root element.

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

        return $(this).parent().hasClass("rootList");
      }
    }
  ]
});

答案 2 :(得分:2)

我无法找到一个包含所有可嵌套拉取请求和嵌套本身的好解决方案。我遇到了jQuery-UI可排序的this扩展。这里有财产protectRoot。这非常有效。示例代码:

<强> HTML

<ol class="sortable">
    <li><div>Some content</div></li>
    <li>
        <div>Some content</div>
        <ol>
            <li><div>Some sub-item content</div></li>
            <li><div>Some sub-item content</div></li>
        </ol>
    </li>
    <li><div>Some content</div></li>
</ol>

<强>的Javascript

$('.sortable').nestedSortable({
    handle: 'div',
    items: 'li',
    toleranceElement: '> div',
    protectRoot: true,
    maxLevels: 2
});