这可能是一种复杂的答案,而不是正是你要找的人,或不止。初次发行
部分原因是,它是非常难以达到的嵌套列表。由于他们有他们没有的项目,基本上呈现给ul
与0 height
。我建议你制作block
至少有一些高度。
我还除去填充和手动在li
添加回给任务和子任务之间的空间关系。我开始有更多的类,parent
和child
分开列表,这样我可以知道我的风格,并与工作。
这个parent
和child
关系有助于本质上2个可排序列表,这恰好是嵌套的。所以我为$(".parent").sortable()
和$(".child").sortable()
创建了选项,试图帮助组织它们。这也可以使我们有能力接受或拒绝(取消)可分类物品,这些物品可以根据它们是哪一类型的任务或它们的起源地。
这绝非完美,我发现很多在这里和那里有点古怪的bug,但核心元素进行排序任务和子任务,并拖动一个子课题负责人到另一个任务的能力。
工作实例迄今:https://jsfiddle.net/Twisty/sv9qdpLb/
HTML
<div id="container">
<h2>Tasks</h2>
<ul id="list" class="parent sortable">
<li id="t1" class="task" data-id="l1">
Task 1 <span class="add-subTask-button ui-icon ui-icon-plus"></span>
<ul class="child sortable"></ul>
</li>
<li id="t2" class="task" data-id="l2">
Task 2 <span class="add-subTask-button ui-icon ui-icon-plus"></span>
<ul class="child sortable">
<li id="t2_1" class="subTask" data-id="l2-1">
Sub Task 1 <span class="remove-subTask-button ui-icon ui-icon-minus"></span>
</li>
<li id="t2_2" class="subTask" data-id="l2-2">
Sub Task 2 <span class="remove-subTask-button ui-icon ui-icon-minus"></span>
</li>
</ul>
</li>
<li id="t3" class="task" data-id="l3">
Task 3 <span class="add-subTask-button ui-icon ui-icon-plus"></span>
<ul class="child sortable"></ul>
</li>
</ul>
</div>
如果您查看演示,你会看到他们在很大程度上是所有ul
和li
风格列表。是的,你可以使用其他的东西,但是把每个列表项目当作它们,列表中的对象项目,以及调整它的数据和标识符的属性等,很容易。
CSS
#container {
width: 600px;
margin: 30px auto;
}
ul.parent {
font-size: 18px;
width: 200px;
margin: 0;
padding: 0;
}
ul.parent li {
list-style: none;
margin-bottom: 2px;
padding-left: 3px;
border: 1px solid #999;
border-radius: 6px;
position: relative;
}
ul.parent li span.ui-icon {
position: absolute;
top: .25em;
right: 2px;
left: auto;
cursor: pointer;
}
ul.child {
display: block;
font-size: 14px;
padding-left: 30px;
min-height: 1em;
}
ul.child li {
list-style: none;
border: 1px solid #bbb;
margin-bottom: 1px;
}
.placeholder {
background: yellow;
height: 1em;
}
.handle {
background: orange;
width: 20px;
height: 20px;
float: left;
margin: 0 5px 10px 5px;
}
.container {
overflow: hidden
}
我这里没有发生很大的变化只是做一些事情更具体。我还添加了边框,以便为用户提供视觉排队或对分组及其关系的了解。
jQuery的
$(document).ready(function() {
// Make tasks sortable
function fullSerial() {
var par = {};
$.each($("#list").sortable("toArray"), function(key, val) {
par[val] = $("#" + val + " .child").sortable("toArray");
});
return par;
}
$(".parent").sortable({
placeholder: 'placeholder',
connectWith: ".sortable",
over: function(e, ui) {
if (ui.item.hasClass("subTask")) {
$(".parent").sortable("cancel");
}
}
});
$(".child").sortable({
placeholder: 'placeholder',
accept: ".child",
connectWith: ".sortable",
}).disableSelection();
$(".sortable").on("sortupdate", function() {
//console.log($(".sortable").sortable("serialize"));
console.log(fullSerial());
});
$(".add-subTask-button").click(function() {
var task = $(this).parent();
var taskName = prompt("Enter Sub Task Name.");
var newId = task.attr("id") + "_" + (task.find("ul.child li").length + 1);
var subTask = $("<li>", {
id: newId,
class: "subTask",
"data-id": newId
}).html(taskName + "<span class='remove-subTask-button ui-icon ui-icon-minus'></span>");
task.find(".child").append(subTask).sortable("refresh");
});
$(".remove-subTask-button").click(function() {
var subTask = $(this).parent();
var ulElem = subTask.parent();
subTask.remove();
ulElem.sortable("refresh");
});
});
通过测试,我发现serialize
方法不使用嵌套排序列表打好。所以我创建了一个函数来构建一个任务对象,其中包含一系列子任务作为每个任务的元素。我怀疑使用JSON.serialize()
可能会让你传递一些东西,但是你总是可以操作fullSerial
从对象而不是对象本身返回一个序列化的字符串。
你可以看到两个排序。由于您的操作系统不清楚您是否允许将子任务设置为任务,因此有人试图阻止此类操作。我尝试了receive
中的相同代码,它应该恢复排序...但是都没有。另外,如果您足够狡猾,您可以拖动整个任务,并将其子任务拖入子任务位置。
为了能够执行更深入的测试,我添加了一种即时添加项目并动态生成/删除子任务的方法。
我希望有帮助。正如我刚才所说,这可能比你需要的多,但你的问题导致了一个复杂的答案。即使没有添加的元素。
UPDATE
防止任务从被拖入子任务的示例:https://jsfiddle.net/Twisty/sv9qdpLb/4/
$(".child").sortable({
placeholder: 'placeholder',
connectWith: ".sortable",
receive: function(e, ui) {
if (ui.item.hasClass("task")) {
ui.sender.sortable("cancel");
}
}
});
欢迎堆栈溢出。更新函数将'event'和'ui'传递给回调函数。目前还不清楚你想用数据做什么......但我怀疑'ui'属性会有帮助。 – Twisty
再看看这个,我认为'div'和extra' ul'正在抛弃它。你想排序任务和子任务吗?或者只是将子任务排序为任务? – Twisty