Tutorial: Drag-and-Drop mit Scriptaculous – Teil 2: Droppables

Nachdem wir uns in Teil 1 des Tutorials mit der Draggable Klasse beschäftigt haben, wenden wir uns heute seinem Bruder der Droppables Klasse zu. Mit ihr können wir auf ein aufgenommenes Element reagieren. Eine typische Anwendung sind Einkaufkörbe auf Online-Shops. Ich möchte daher einen einfachen Einkaufswagen demonstieren.

Der Quellcode für dieses Beispiel

Zuerst einmal wieder der Quellcode für dieses Beispiel. Ich werde wie auch schon im ersten Teil des Tutorials die wichtigen Zeilen etwas genauer erklären. Die Zeilen 1-34 enthalten das grundlegende Gerüst der HTML-Seite sowie die Stylesheets, auf die ich nicht näher eingehen möchte:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="de-DE">
<head>
	<head>
		<title>Drag-and-Drop Part 2</title>
		<script type="text/javascript" src="prototype.js"></script>
		<script type="text/javascript" src="scriptaculous.js"></script>
		<style type="text/css">
			.item {
				padding: 40px;
				border: 1px solid #000;
				cursor: move;
				display: inline-block;
				margin-right: 20px;
			}
			.blue {
				background-color: #39c;
			}
			.green {
				background-color: #292;				
			}
			div#shopping_cart {
				width: 180px;
				height: 180px;
				background: #fff;
				border: 5px solid #ccc;
			}
			div#shopping_cart.hover {
				border: 5px dashed #aaa;
			}
		</style>
	</head>
	<body>
		<h1>Drag-and-Drop</h1>
		<div id="blue_box" title="Blaue Box" class="item blue"></div>
		<div id="green_box" title="Grüne Box" class="item green"></div>
		<div id="shopping_cart">
			<ul id="items_in_cart"></ul>
		</div>
		<script type="text/javascript">
			new Draggable('blue_box', {
				revert: true
			});
			new Draggable('green_box', {
				revert: true
			});
			Droppables.add('shopping_cart', {
				onDrop: addItem,
				hoverclass: 'hover'
			});
			function addItem(dragged, dropped, event){
				var itemCount = $('items_in_cart').select('li[id="item' + 
									dragged.id + '"] span').first();
				if(itemCount == undefined){
					$('items_in_cart').insert({
						bottom: '<li id="item' + dragged.id + 
								'"><span>1</span>x ' + dragged.title + '</li>'
					});
				} else {
					itemCount.update(parseInt(itemCount.innerHTML) + 1);
				}	
			}
		</script>
	</body>
</html>

In den Zeilen 35-39 sind zwei einfache „Artikel“ aufgeführt (in unserem Fall einfache farbige DIVs) sowie der „Warenkorb“, der eine leere unsortierte Liste enthält. In diese fügen wir dann per Drag-and-Drop die Waren ein. Sehen wir uns nun aber den interessanten Teil des Quellcodes an, das JavaScript. Die Zeilen 41-46 sollten aus dem ersten Teil des Tutorials bekannt sein. Wir erzeugen hier zwei Draggables wobei wir die Option reset auf true setzen, damit die Artikel beim „loslassen“ wieder auf ihre ursrpüngliche Position zurückkehren. Nun aber zum neuen Teil der Droppables-Klasse:

Droppables.add('shopping_cart', {
	onDrop: addItem,
	hoverclass: 'hover'
});

Wichtig ist hier, dass wir keine Instanz der Klasse durch das Schlüsselwort new erzeugen. Es existiert vielmehr schon eine Instanz, der wir mit der add() Funktion eine neue „Drop-Zone“ hinzufügen. Es ist also möglich mehrere Bereiche einer Website für die Reaktion auf Draggables zu verwenden. Es wäre z.B. möglich einen „Papierkorb“ einzurichten, mit dem man einenen bereits hinzugefügten Artikel wieder aus der Liste entfernen kann bzw. dessen Anzahl verringern.

Der add() Funktion können auch mehrere Optionen übergeben werden, welche das sind könnt ihr in der API zu Droppables nachlesen. Ich verwende hier die hoverClass Option, die der „Drop-Zone“ eine Klasse zu weist, wenn der Benutzer mit einem Draggable darüber steht. Zusätzliche gebe ich eine Callback-Funktion für das onDrop Event an. Wie ihr der Funktion addItem() entnehmen könnte, bekommt die onDrop() Funktion eine Referenz auf das aufgenommene Elemente sowie auf die „Drop-Zone“ und das Event selbst übergeben. In der Funktion selbst fügen wir den Artikel an die Liste an und setzen die Anzahl auf 1, sofern er noch nicht enthalten ist. Wenn er enthalten ist erhöhen wir dir Anzahl um 1.

Das Beispiel

Das oben beschriebene Beispiel sieht dann wie folgt aus (es darf aber gerne unter Verwendung von Bildern anstelle von DIVs und mehr CSS noch ansprechender gestaltet werden):

  • Warenkorb

Wie ihr also sehen könnt ist es sehr einfach ein Element für die Interaktion mit Draggables zu verwenden. Was ihr dabei mit den Elementen macht ist eurer Fantasie überlassen. Die Möglichkeiten sind schier unbegrenzt. Ich möchte euch also dazu animieren einfach einmal mit der Funktion zu experimentieren.

Das war es dann auch schon wieder mit diesem Teil des Tutorials. Im nächsten Teil sehen wir uns einen sehr speziellen Fall von Drag-and-Drop an und zwar mit dem Sortieren von Elementen. Wie einfach so etwas möglich ist und wie leicht sich die Sortierreihenfolge auslesen lässt, das erwartet euch in Teil 3 des Tutorials. Für welche Einsatzzwecke habt ihr bisher Draggables und Droppables genutzt? Über einen Kommentar dazu würde ich mich wie immer sehr freuen.

Veröffentlicht von

Bernhard ist fest angestellter Webentwickler, entwickelt in seiner Freizeit Plugins, schreibt in seinem Blog über WordPress und andere Themen, treibt sich gerne bei den WP Meetups in Berlin und Potsdam herum und läuft nach Feierabend den ein oder anderen Halbmarathon.

4 Kommentare » Schreibe einen Kommentar

  1. Moin moin,
    super Tutorial…
    Man kann natürlich der Prinzip für andere Sachen benutzen, wie z.B. ein Art Korb um Mysql-Abfragen zusammen zu stellen wegen DB-Auswertungen.
    Meine Frage ist, wie kann ich die Werten/Artikeln im Warenkorb dann auflisten und weitersenden für Bearbeitung?
    Als newbie in Sache Scriptaculous bin ich da etwas überfordert.
    Danke im Voraus

    • Dazu solltest du in der Funktion addItem() die Werte entweder direkt per AJAX an den Server schicken und dort dann in der Session des Benutzers speichern, oder aber die Werte lokal in eine JSON String speichern, den du dann beim Klick auf „Weiter zur Bestellung“ oder ähnliches übergibst. Die Variante per AJAX ist aber auf jeden Fall die bessere und einfachere. Sieh dir dazu einfach mal die Klasse Ajax.Request von Prototype an. Falls du noch weitere Fragen hast, kannst du gerne nochmal einen Kommentar hinterlassen.

      • tja, bin anscheinend nicht in der Lage ….
        ich muss weiter probieren oder auf web 1.0 zurückschalten 🙂
        Danke

        • Was genau funktioniert denn nicht? Wie hast du es probiert? Wenn du etwas Quellcode z.B. bei http://jsbin.com/ postest oder uns eine Seite zum debuggen zeigst, können wir dir vielleicht weiterhelfen.

Schreibe einen Kommentar

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