Drag and Drop mit AjaxSchiebung

DeveloperIT-ProjekteSoftware

Vom Desktop ins Web

Drag and Drop mit Ajax

Die Popularität von Drag and Drop kommt nicht von ungefähr. Die Verwendung der Maus als Eingabegerät ist eine äußerst effektive Möglichkeit, Daten zwischen einzelnen Elementen einer Anwendung auszutauschen. Aus diesem Grund wird Drag and Drop von nahezu jedem Betriebssystem oder grafischen Bedienoberfläche unterstützt. Im Webbereich konnte sich Drag and Drop noch nicht durchsetzen, obwohl es auch hier sehr viele sinnvolle Anwendungsmöglichkeiten gibt. Der Grund ist der Aufwand, der getrieben werden muss, um eine Drag-and-Drop-Funktion zu entwickeln, die auf den gängigen Browsern zuverlässig funktioniert.

Glücklicherweise entstehen momentan im Webbereich einige sehr gute Frameworks, die dem Entwickler von webbasierten Anwendungen fertig einsetzbare Lösungen zur Verfügung stellen, die ohne zusätzlichen Aufwand auf den gängigen Browsern funktionieren.

Javascript-Framework

Drag and Drop mit Ajax

Für die Beispiele dieses Artikels wird das Framework Scriptaculous (script.aculo.us) eingesetzt, das unter einer Open-Source-Lizenz zur Verfügung steht. Es besteht aus einer Sammlung von Javascript-Klassen für unterschiedlichste Anwendungsfälle.

Neben Drag and Drop, dem Schwerpunkt dieses Artikels, bietet es auch Klassen für Animationseffekte wie das Ein- und Ausblenden und das Vergrößern oder Verkleinern von Elementen. Das Schöne an der Scriptaculous-Anwendung ist, dass Sie nur die Teile des Frameworks nutzen können, die Sie wirklich benötigen. So sind Sie für die Verwendung von Ajax nicht unbedingt auf eine Implementierung angewiesen, die das Framework mitbringt, sondern können dafür auch Bibliotheken Ihrer Wahl einsetzen. Andere Frameworks sind hier weniger flexibel. Gerade diese Flexibilität macht Scriptaculous besonders interessant. Wie im ersten Teil der Ajax-Artikelserie kommt als Ajax-Framework Ajason (www.sourceforge.net/projects/ajason) zum Einsatz.

Drag and Drop im Einsatz

Drag and Drop mit Ajax

Anwendungsbeispiele für Drag and Drop lassen sich viele finden. Es eignet sich immer dort, wo Elemente sortiert, zugeordnet oder ausgetauscht werden. Wer schon einmal eine Seite entwickelt hat, auf der die Reihenfolge von Elementen veränderbar ist, kann ein Lied davon singen, wie komplex so etwas werden kann. Das normale Vorgehen war bisher die Verwendung von Icons für die Aktionen »aufwärts verschieben« und »abwärts verschieben«. Bei einem Klick wird ein PHP-Skript aufgerufen, das die Positionsänderung in der Datenbank vermerkt und die Seite mit den geänderten Positionen neu aufbaut.

Der Nachteil liegt auf der Hand: Das ständige Neuladen der Seite macht die Sortierung von Elementen zur Qual. Aus diesem Grund gingen einige Entwickler dazu über, die Positionsänderung per Javascript vorzunehmen und den geänderten Positionszustand nur dann in die Datenbank zu speichern, wenn alle Elemente wie gewünscht platziert waren. Dieses Vorgehen ist für den Benutzer viel angenehmer zu bedienen. Allerdings stellt die Entwicklung einer solchen Funktionalität hohe Anforderungen an den Programmierer. Sowohl die dazu notwendigen Javascript-Funktionen als auch der Datenaustausch nach PHP sind aufwendige und fehleranfällige Aufgaben.

Sortierbare Listen

Drag and Drop mit Ajax

Mit aktuellen Javascript-Frameworks und Ajax stehen nun zwei Techniken zur Verfügung, mit denen die Entwicklung der beschriebenen Funktionalität zum Kinderspiel wird. Das Framework bietet mit Drag and Drop eine Möglichkeit, Elemente einfach neu anzuordnen, und mit Ajax kann anschließend der Zustand sofort im Hintergrund gespeichert werden. Ein Neuladen der Seite ist nicht mehr notwendig. Die Umsetzung ist mit Scriptaculous denkbar einfach. Um eine Liste sortierbar zu machen, genügen ein paar Zeilen Quellcode.

  • Eintrag 1
  • Eintrag 2

// <![CDATA[
Sortable.create("list",
{dropOnEmpty:true, containment:["list"], constraint:false});
// ]b>

Das ist alles, um eine Liste sortierbar zu machen. Wenn diese Seite in einem Browser geöffnet wird, ist die Liste zuerst nicht von einer normalen Auflistung zu unterscheiden. Erst wenn ein Eintrag mit der Maus verschoben wird, ist der Unterschied ersichtlich. Dieses Verhalten ist natürlich wenig intuitiv für den Benutzer, darum sollten Sie die Liste mit einigen Cascading Stylesheets (CSS) verändern, damit offensichtlicher wird, dass die Elemente verschiebbar sind. Das folgende Stylesheet verändert beispielsweise die Cursor-Form beim Überfahren eines Eintrags und hebt die Einträge besser voneinander ab.


#list li {
cursor: move;
padding:2px;
margin:3px;
list-style-image:none;
list-style-type:none;
border: 1px solid steelblue;
}

Speichern im Hintergrund

Drag and Drop mit Ajax

Bisher beschränken sich alle Änderungen auf die aktuelle Seite. Wird diese neu geladen, sind alle Änderungen hinfällig. Hier kommt Ajax ins Spiel. Mit Ajax kann der Zustand der Liste ohne Probleme an den Server übertragen werden, der sie dann beispielsweise in eine Datenbank speichert. Das Problem ist nur: Wann sollen die Daten gespeichert werden oder wie bekommt man mit, wann sich eine Liste geändert hat? Scriptaculous bietet dazu frei definierbare Event-Handler an. Das heißt, dass Sie in der Lage sind, eigene Funktionen zu hinterlegen, die aufgerufen werden, wenn verschiedene Ereignisse eintreten. Ein solches Ereignis ist onChange. Das folgende Listing zeigt eine Version der bisher verwendeten Erzeugung einer sortierbaren Liste, die um einen Event-Handler für Änderungen erweitert wurde.



// <![CDATA[
Sortable.create("list",
{dropOnEmpty:true, containment:["list"], constraint:false, onChange:function(sortable) {listChanged(sortable)}});
// ]b>

Durch onChange:function(){listChanged()} wird festgelegt, dass die Funktion listChanged aufgerufen wird, sobald sich die Liste verändert hat. Zudem bietet das Framework die Möglichkeit, Übergabeparameter zu definieren, die beim Aufruf der Event-Handler-Funktion mitgegeben werden sollen. Möglich ist hier, die Referenz auf das veränderte Element weiterzuleiten, wie dies im vorangegangen Listing angewendet wird. Andere Event-Handler übergeben teilweise andere Referenzen, beispielsweise auf die komplette sortierbare Liste.

Um die Daten zu speichern, muss der Inhalt der Liste in eine Form gebracht werden, die per Ajax übertragen werden kann. Voraussetzung dafür ist, dass jeder Eintrag in der Liste eine eindeutige ID besitzt, damit die einzelnen Einträge auch unterschieden werden können.

Scriptaculous besitzt zwar die Funktion serialize, die die Werte in ihrer Reihenfolge in der Liste ausgibt. Allerdings geschieht dies in Form einer URL-Schreibweise, die zum Beispiel so aussehen kann:


list[]=user_1&list[]=user_3
&list[]=user4

Für Ajax-Datenübertragungen ist dieses Format nicht geeignet. Hier werden die Daten vielmehr als Array benötigt, in dem die IDs der Einträge in ihrer Reihenfolge in der Liste eingetragen sind. Da Scriptaculous eine solche Funktion nicht standardmäßig bietet, muss in der Event-Handler-Funktion ein wenig Hand angelegt werden. Das nachfolgende Listing zeigt den Ausschnitt der listChanged-Funktion, der diese Umsetzung in ein Array vornimmt und mittels Ajax speichert.


function listChanged(element) {
sortable = element.parentNode;
var elements = [];
$A(sortable.childNodes).each(
function(e) {
if(e.tagName && e.tagName.toUpperCase()== 'LI')
elements.push(e.id);
});
ajax_savelist1(elements);

Das so erzeugte Array enthält alle IDs der Listeneinträge in der richtigen Reihenfolge. Dieses Array wird von der Ajax-Engine Ajason automatisch verarbeitet und steht im aufgerufenen PHP-Skript wieder als Array mit denselben Informationen zur Verfügung, um in eine Datenbank gespeichert zu werden. Der komplette Ablauf ist in dem auf der Heft-CD beigefügten Beispiel zu sehen.

Scriptaculous bietet übrigens weitere Event-Handler und Optionen. Der Blick in die Dokumentation lohnt sich also, um alle Möglichkeiten kennen zu lernen.

Datenaustausch zwischen Listen

Drag and Drop mit Ajax

Was innerhalb einer Liste funktioniert, das klappt auch zwischen mehreren. Werden statt einer sortierbaren Liste mehrere erzeugt, so ändert sich erst einmal gar nichts. Jede Liste für sich betrachtet kann mit der Maus sortiert werden. Ein Austausch zwischen den Listen ist aber nicht möglich. Dazu stellt Scriptaculous das Attribut containment bereit. In den bisherigen Listings war dort immer nur der Name der Liste selbst eingetragen. Wird hier noch die ID einer weiteren Liste eingefügt, bedeutet dies, dass die erzeugte Liste Elemente beider Listen enthalten kann. Somit ist ein problemloser Austausch zwischen den Listen möglich. Das folgende Listing zeigt die Erzeugung einer Liste, die Elemente von zwei anderen Listen aufnehmen kann.



// <![CDATA[
Sortable.create("list",
{dropOnEmpty:true, containment:["list", "list2", "list3"], constraint:false,
onChange:function(){listChanged()}});
// ]b>

Auf der CD finden Sie ein komplettes Beispiel, das den zuletzt beschriebenen Effekt zeigt.

Drag and Drop unplugged

Drag and Drop mit Ajax

Sortierbare Listen sind nur ein Beispiel dafür, wie Drag and Drop in webbasierten Anwendungen verwendet werden kann. Sie sind allerdings spezielle Anwendungsbeispiele, die sicherlich oft eingesetzt werden. Sie können aber nicht allen Anforderungen gerecht werden. Scriptaculous verwendet für die Umsetzung allgemeine Drag-and-Drop-Funktionen, die selbstverständlich auch für andere Aufgaben einsetzbar sind. Während bei sortierbaren Listen nur Elemente von HTML-Listen per Drag and Drop verschiebbar sind, können über die generische Schnittstelle nahezu alle HTML-Elemente als verschiebbares Objekt verwendet werden. Ebenso sind auch andere Elemente als eine Liste als Drop-Bereich möglich.

Die Datei demo2.php auf der Heft-CD zeigt, wie damit Textbausteine, die in div-Tags abgelegt sind, in eine Textbox eingefügt werden können. Ebenso denkbar ist eine Warenkorbfunktion, bei der Artikel mit Bildern in den Warenkorb geschoben werden können.

Fazit

Drag and Drop mit Ajax

Mit Hilfe von Scriptaculous und Ajax kann Drag and Drop auch in Web-Anwendungen Einzug halten. Viele Operationen können so um einiges einfacher und für den Benutzer intuitiver gestaltet werden. Wie bei vielen aktuellen Javascript-gesteuerten Bedienoberflächen gilt allerdings auch hier, dass Benutzer erst einmal auf die andersartige Bedienung der Web-Anwendung aufmerksam gemacht werden müssen. Im Fall von Drag and Drop rechnen die wenigsten mit einer solchen Funktionalität in einer Internet-Anwendung und versuchen ohne Hilfestellung erst gar nicht, Elemente mit der Maus zu verschieben. Ein kurzer Hinweis auf die Verschiebbarkeit genügt, um die Anwender zu ermutigen.

Die abgedruckten Listings geben nur einen Ausschnitt des Quelltextes wieder. Wer sich eingehender mit der Materie auseinander setzen möchte, kann das auf der Heft-CD hinterlegte Beispiel als Ausgangsbasis für eigene Experimente verwenden. Wenn Sie erst einmal Drag and Drop ausprobiert haben, werden Ihnen sicherlich viele Anwendungsfälle dafür in Ihren Anwendungen einfallen. Da der Artikel nur einen Einstieg in die Drag-and-Drop-Funktionen von Scriptaculous liefern kann, wird ein Blick in die Dokumentation von Scriptaculous sicher noch viele interessante Ideen und Funktionen zu Tage fördern.


Alle Listings zum Workshop finden Sie unter listings.internet-pro.de.

Lesen Sie auch :