Dies könnte eine Art von komplexer Antwort sein und nicht genau das, was Sie suchen, oder mehr als.
Teil des ersten Problems war, dass es sehr schwer ist, die verschachtelten Listen zu erreichen. Da sie in ihnen keine Artikel haben und im Wesentlichen auf ul
mit 0 für height
machen. Ich würde vorschlagen, dass Sie block
sie mit mindestens etwas Höhe machen.
Ich entfernte auch die Auffüllung und fügte sie manuell in li
zurück, um die räumliche Beziehung zwischen Aufgabe und Unteraufgabe zu geben. Ich fing an, Liste mit mehr Klassen, parent
und child
zu trennen, damit ich wissen konnte, mit wem ich anredete und arbeitete.
Diese parent
und child
Beziehung bietet sich im Wesentlichen zwei sortierbare Listen, die zufällig verschachtelt werden. Also habe ich Optionen für beide $(".parent").sortable()
und $(".child").sortable()
in einem Versuch, sie zu organisieren. Dies könnte uns auch die Fähigkeit geben, sortierbare Elemente zu akzeptieren oder abzulehnen (basierend auf der Art der Aufgabe, an der sie sich befinden oder wo sie entstanden ist).
Dies ist in keiner Weise perfekt, ich fand viele kleine seltsame Fehler hier und da, aber das Kernelement ist die Fähigkeit, Aufgaben und Unteraufgaben zu sortieren und eine Unteraufgabe auf eine andere Aufgabe zu ziehen.
Arbeitsbeispiel Bisher: 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>
Wenn Sie die Demos zu überprüfen, werden Sie feststellen, sie sind weitgehend alle ul
und li
Stil Listen. Ja, Sie können andere Dinge verwenden, aber es ist weitgehend einfacher, jedes Listenelement als das zu behandeln, was es ist, das Objektelement in der Liste, und seine Attribute für Daten und IDs usw. anzupassen.
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
}
ich hier nur einige Dinge präzisiert nicht viel ändern. Ich fügte auch Grenzen hinzu, um dem Benutzer eine visuelle Warteschlange oder ein Bewusstsein für die Gruppierungen und ihre Beziehungen zu geben.
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");
});
});
Durch Tests fand ich, dass die serialize
Methode nicht gut mit verschachtelten sortierbare Listen spielt. Also habe ich eine Funktion erstellt, um ein Objekt von Aufgaben mit einem Array von Unteraufgaben als Element jeder Aufgabe zu erstellen. Ich vermute, die Verwendung von JSON.serialize()
könnte Ihnen etwas bringen, das Sie weitergeben können, aber Sie können immer die fullSerial
manipulieren, um eine serialisierte Zeichenfolge vom Objekt anstelle des Objekts selbst zurückzugeben.
Sie können die zwei Sorables sehen. Da es aus Ihrem OP nicht klar war, ob Sie Unteraufgaben zu Aufgaben machen möchten oder nicht, wird versucht, solche Aktivitäten zu verhindern. Ich habe versucht, den gleichen Code in receive
und es sollte die Sortierung wiederherstellen ... aber auch nicht. Auch wenn Sie schlau genug sind, können Sie eine ganze Aufgabe und ihre Unteraufgaben in eine Unteraufgabenposition ziehen.
Um tiefere Tests durchführen zu können, habe ich eine Methode hinzugefügt, um ein Element im laufenden Betrieb hinzuzufügen und Unteraufgaben dynamisch zu generieren/zu entfernen.
Ich hoffe, dass hilft. Wie ich schon sagte, könnte es mehr sein, als Sie brauchen, aber Ihre Frage führt zu einer komplexen Antwort. Auch ohne die hinzugefügten Elemente.
UPDATE
Beispiel Aufgabe zu verhindern, dass in Sub-Task gezogen wird: 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");
}
}
});
Willkommen Überlauf zu stapeln. Die Update-Funktion übergibt 'event' und' ui' an den Callback. Es ist nicht klar, was Sie mit den Daten machen wollen ... aber ich vermute, dass das 'ui'-Attribut hilfreich sein wird. – Twisty
Betrachtet man das ein bisschen mehr, denke ich, dass die "div" und extra "ul" Dinge wegwerfen. Möchten Sie die Aufgaben und die Unteraufgaben sortieren? Oder sortiere die Unteraufgaben einfach in Aufgaben? – Twisty