我的列表允许将子项移出父项,我想更改它。
如您所见,应允许将子项从父项内部移动到另一个父项,但不应允许将子项移动到任何父项之外。
我认为代码会太长,所以这里是类似于我使用来自 Luna 主题的 nestableList 的可嵌套列表,这里是脚本jquery.nestable.js
我的列表允许将子项移出父项,我想更改它。
如您所见,应允许将子项从父项内部移动到另一个父项,但不应允许将子项移动到任何父项之外。
我认为代码会太长,所以这里是类似于我使用来自 Luna 主题的 nestableList 的可嵌套列表,这里是脚本jquery.nestable.js
注意 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>
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');
}
}]
});
在您提供的示例中,使用的 jQuery 插件是来自 dbushell 的 Nestable。您对最终将使用的插件有任何控制权吗?项目彻底死了,2年没有更新了。
检查仍然维护的解决方案并提出您的功能可能是明智的,这几乎是许多图书馆现在拥有的“protectRoot”功能。
如果您无法控制插件,则此功能目前尚未实现,并且可能永远不会实现。
如果您可以控制插件但仍想使用这个插件,一个解决方案可能是使用一个仍然维护并具有此功能的叉子(因为项目已死,所以有很多叉子)。
另一种解决方案是从提交给项目的许多拉取请求中挑选自己感兴趣的代码,但这些代码永远不会被合并。
例如,这个拉取请求添加了新的回调,而不是目前唯一可用的回调:beforeDragStart
、dragStart
、dragMove
、beforeDragEnd
、dragEnd
等。这些新的回调提供了许多参数,例如您当前正在移动的项目,在您开始拖动它之前它的位置,和目的地。根据这些新信息,尤其是目的地,如果目的地是根节点,您可以取消拖动。
$('.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.
});
另一个可以满足您需求的拉取请求是这个。它提供回调来拒绝特定的拖动事件,例如,如果被拖动的项目成为根元素,您可以拒绝拖动事件。
$('.dd').nestable({
reject: [
{
rule: function() {
// $(this) refers to the dragged element.
// Return TRUE to cancel the drag action.
return $(this).parent().hasClass("rootList");
}
}
]
});
对于所有可嵌套的拉取请求和可嵌套本身,我无法找到一个好的解决方案。我遇到了 jQuery-UI 可排序的这个扩展。在这里你有财产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
});