Tutorial: JQuery UI Sortable – Elemente zusammenführen

Dieses Tutorial beschäftigt sich mit dem Sortable Widget von JQuery UI. Mit dessen Hilfe sich recht simpel sortierbare Listen in Javascript erstellen lassen.

Warum dieses Tutorial?

Die Standardfunktionalität von JQuery UI Sortable ist sehr unspektakulär, aber reicht für viele Anwendungsfälle aus. Es macht, was es soll – es ermöglicht das Sortieren von DOM-Knoten. Jedoch gibt es auch Bereiche, in denen das Ändern der Reihenfolge allein nicht ausreicht. Das Paradebeispiel dazu wäre eine Art Datei-Manager, wie z.B. der Windows Explorer oder unter Ubuntu Nautilus. Hier lassen sich Dateien in Verzeichnissen gruppieren. Dadurch kann ein Listenelement eine Datei oder ein Ordner sein. Allgemein gesagt, wird eine Funktionalität benötigt, um Elemente zusammenzuführen (engl. mergen), ob gleicher oder verschiedener Art. Da die Lösung dafür nicht gerade trivial ist, ist dieses Tutorial entstanden.

Voraussetzungen

Vorbetrachtung & Vorbereitung

JQuery UI Sortable bietet dem Benutzer vielfältige Einstellungsmöglichkeiten und Einhängepunkte, um in den Sortierungsprozess einzugreifen. Die für dieses Tutorial wichtigsten davon im Überblick.

Option:

  • helperoriginal (Standard – das Element selbst wird genutzt), clone (für das Sortieren wird ein Klon erstellt)

Event:

  • stop – nach dem Beenden des Sortierens

Bevor es richtig losgeht, stellt sich die folgende Frage.

Was für eine Liste liegt vor?

Es lassen sich mit Sortable sowohl horizontale, als auch vertikale Listen abbilden, wobei eine vertikale Liste auch zu einer Art Gitter umbrechen kann.

vertikal

vertikale Liste

horizontale Liste

horizontale Liste

Liste als Gitter

Liste als Gitter

Für das Sortieren benutzt JQuery UI verschiedene DOM-Elemente, auf die man in den verschiedenen Events zugreifen kann. Dies kann über folgende Objekte erfolgen.

  • ui - Object, welches nachfolgende beinhaltet + aktuelle Position
  • ui.item - aktuelle Listenelement
  • ui.helper - falls die Option helper auf clone gesetzt wurde
  • ui.placeholder - Sortierplatzhalter

Als nächsten Schritt muss beachtet werden, dass ein Element immer auf beide benachbarten Elemente gezogen werden kann.

Vertikal - Vorgänger

Vertikal – Vorgänger

Vertikal - Nachfolger

Vertikal – Nachfolger

Horizontal - Vorgänger

Horizontal – Vorgänger

Horizontal - Nachfolger

Horizontal – Nachfolger

Gitter - Vorgänger

Gitter – Vorgänger

Gitter - Nachfolger

Gitter – Nachfolger

Somit ist die Hauptschwierigkeit die richtige Position des aktiven Elements zu bestimmen und dann zu entscheiden, ob einfach sortiert werden soll oder Elemente zusammengeführt werden müssen und wenn ja, welche.

Die weiter oben vorgestellten Objekte besitzen jeweils Schlüssel oder Funktionen, um die Positionen der dazugehörigen DOM-Elemente zu bestimmen.

UI Objekte

UI Objekte

Die Positionskoordinaten der zugehörigen DOM-Knoten können wie folgt bestimmt werden:

  • ui.position – Objekt
  • ui.item.position() – Funktion
  • ui.helper.position() – Funktion
  • ui.placeholder.position() - Funktion

Noch eine kurze Erklärung, warum für dieses Tutorial nur das stop Event relevant ist. Dazu kann sich das Verhalten der Objekte und deren Positionen in verschiedenen Events betrachtet werden:

start (ein Element wird zum Sortieren aktiviert/angefasst, Sortiervorgang gestartet)

  • ui.position - existiert zu Beginn nicht bzw. hält Daten des zuletzt sortierten Elements
  • ui.item.position() - Option helper != ‘clone’, dann Position des Elements in der Liste
  • ui.helper.position() - Option helper != ‘clone’, dann ist ui.helper = ui.item, sonst hält er die aktuelle Positionskoordinaten des zu bewegenden Elements
  • ui.placeholder - der Sortierplatzhalter und dessen Position

change (Positionsänderung des Elements -> Platzhalter verschoben)

  • ui.position - aktuelle Position des zu bewegenden Elements
  • ui.item.position() - Option helper != ‘clone’, aktuelle Position des zu bewegenden Elements
  • ui.helper.position() - Option helper != ‘clone’, dann ist ui.helper = ui.item, sonst hält er die aktuelle Positionskoordinaten des zu bewegenden Elements
  • ui.placeholder - der Sortierplatzhalter und dessen Position

beforeStop (Element wurde gerade fallengelassen)

  • ui.position - letzte Position des zu bewegten Elements
  • ui.item.position() - Position des Sortierplatzhalters
  • ui.helper.position() - Option helper != ‘clone’, dann Position des Sortierplatzhalters, sonst letzte Position des zu bewegten Elements
  • ui.placeholder.position() - Position des nächsten Elements

stop (alle Berechnungen abgeschlossen – Sortierungsvorgang beendet)

  • ui.position - letzte Position des zu bewegten Elements
  • ui.item.position() - einsortierte Position des Elements
  • ui.helper - existiert nicht mehr
  • ui.placeholder.position() - zurückgesetzt

Im stop Event haben wir die nötigen Werte, um unsere Berechnungen durchzuführen.

Umsetzung

Zunächst wird eine kleine HTML-Datei, die alle nötigen Skripte, die DOM-Struktur und ein wenig CSS enthält.

Vertikale Liste

Zunächst wird eine Funktion definiert, die ausgeführt werden soll, wenn das stop Event ausgelöst wird. Diese erhält standardmäßg zwei Parameter – das Event selbst (event) und das ui Objekt (ui).

Über ui lässt sich das ui.item, ui.item.position(), ui.position und sogar die Position in der Liste über ui.item.index() bestimmen.

Bei einer vertikalen Liste ist zusätzlich die Höhe eines Listenelements sehr wichtig, welche durch ui.item.outerHeight() bestimmt werden kann. Des Weiteren sollte ein Toleranzfaktor benutzt werden, damit man nicht genau über das Ziel fahren muss.

Die Berechnungen im Überblick:

  1. Elementhöhe bestimmen = ui.item.outerHeight()
  2. Toleranzfaktor setzen = z.B. 0.3
  3. Index des sortierten Elements = ui.item.index();
  4. Überprüfen, ob Element mehr über Nachfolger / Vorgänger fallen gelassen wurde = ui.position.top – ui.item.position().top
  5. potentielles Ziel – Vorgänger / Nachfolger (falls vorhanden) = ui.item.prev() oder ui.item.next()
  6. ZielWert, wo über potentiellem Ziel Element fallen gelassen wurde) = Math.abs(ui.position.top – target.position().top)
  7. Überprüfen, ob der bestimmte Wert im Toleranzbereich liegt = ZielWert <= Toleranzfaktor * Elementhöhe

Der dokumentierte Quellcode:

Horizontale Liste

Das Vorgehen hier ist ähnlich, wie bei der vertikalen Liste. Statt Elementhöhe und der top Position, müssen die Elementbreite und left Position betrachtet werden. Daraus resultiert unten stehender Quellcode.

Gitter

Dieser Anwendungsfall basiert auf der horizontalen Liste, jedoch muss hier beachtet werden, dass das Element auch von der Höhe im Toleranzbereich liegt, denn sonst könnte es zu unerwünschten Effekten führen.

Tipp

JQuery UI’s Draggable Elemente lassen sich mit Sortable Listen verknüpfen. Genau nach dem gleichen Prinzip kann man ein Draggable Element mit einem Sortable Element zusammenführen. Durch das Sortable receive Event, kann gut unterschieden werden, ob ein neues Elemente in die Liste hinzugefügt wurde.

Wir freuen uns über eine Bewertung, um ein Feedback zu erhalten:

Durchschnittlich 4.2 Sterne aus 6 Meinungen.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">