2016-08-11 1 views
0

Ich bin mit übergeordneten Elemente und Unterelemente auf eine sortierbare Liste arbeiten. Der Benutzer sollte in der Lage sein, Objekte zwischen beiden zu verschieben und auch die übergeordneten Elemente einschließlich ihrer Unterelemente zu verschieben.JQuery sortierbar verbundenen Listen AJAX-Aufruf

ich herausgefunden, wie dies zu tun mit einer angeschlossenen sortierbare Liste:

https://jsfiddle.net/ron_s/fovah76v/1/

Um dies zu erreichen, habe ich nicht die ID der Liste verwenden:

$('#id_of_the_list').sortable({ ... }) 

aber eine Allgemein .Sortable-Klasse:

$('.sortable').sortable({ ... }) 

Mein Problem ist jetzt, dass die AJA X-Aufruf erfasst nur die IDs der übergeordneten Elemente, nicht die untergeordneten Elemente.

<script type="text/javascript"> 
$(document).ready(function() { 
$('.sortable').sortable({ 
    connectWith: 'ul.sortable', 
    update: function() { 
    $.ajax({ 
     type: 'post', data: $('.sortable').sortable('serialize'), dataType: 'script', 
     complete: function (request) { 
     $('.sortable'); 
     }, url: '/tasks/sort_goal_task' 
    }) 
    } 
    }); 
}); 
</script> 

Ich denke, es ein ziemlich ähnliches Problem ist here, aber ich konnte nicht diesen Code funktioniert.

Vielen Dank für jede Hilfe, Ron

+0

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

+0

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

Antwort

0

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"); 
    } 
    } 
}); 
+0

Hallo Twisty, vielen Dank für Ihre Antwort! Der CSS-Teil war in der Tat mehr als ich brauchte (die Liste ist Teil einer voll gestylten Anwendung, ich habe sie nur entfernt, um die Frage klarer zu machen), aber Ihre "fullSerial" -Funktion war genau das, wonach ich suchte. Der Benutzer sollte in der Lage sein, Unteraufgaben in Aufgaben umzuwandeln, also schneide ich den entsprechenden Teil in $ (". Parent") aus. Als nett zu haben: Könntest du dir eine Möglichkeit vorstellen, wie man eine Eltern-Kind-Liste auf ein anderes Kind ziehen kann, weil das schwer zu parsen ist? Nochmals vielen Dank dafür! Ron – Ron

+0

Ich werde sehen, was getan werden kann. Im 'receive' kann überprüft werden, ob das Objekt die Klasse 'Eltern' hat und 'Abbrechen'. Dies sollte die Sortierung wiederherstellen. – Twisty

+0

@Ron Siehe Aktualisierung. – Twisty