Webentwicklung mit script.aculo.us
Kommentare

Ähnlich schnell wie Aldi und Lidl ihre Läden mit standardisierten Bauteilen in die Landschaft pflanzen, zimmern wir unser Shopping-Paradies ebenfalls aus Standards. Allerdings werden in unserem Falle

Ähnlich schnell wie Aldi und Lidl ihre Läden mit standardisierten Bauteilen in die Landschaft pflanzen, zimmern wir unser Shopping-Paradies ebenfalls aus Standards. Allerdings werden in unserem Falle XHTML-Tags und CSS-Eigenschaften verbaut. Die XHTML-Grundstruktur umfasst diverse div-Elemente, die jeweils einen zusammenhängenden Block von Elementen der Shop-Oberfläche enthalten. Nahezu jedes div-Element erhält ein id-Attribut, da dies der Schlüssel sowohl für die Gestaltung der Oberfläche mit CSS als auch der Ansatzpunkt für viele Script.aculo.us-Funktionen ist. Durch die Verwendung der IDs können Effekte gezielt auf HTML-Elemente wirken oder Drag-Elemente und Drop-Bereiche eindeutig identifiziert und angesprochen werden. Der gesamte Shop-Bereich ist durch ein div-Element mit der id shop abgegrenzt, das über das style-Attribut und die Verwendung von display:none zunächst einmal gar nicht sichtbar ist. Dazu gesellt sich ein noscript-Tag, dessen Inhalt bekannterweise zur Anzeige kommt, sollte der Benutzer kein JavaScript aktiviert haben.

  

Bitte aktivieren Sie JavaScript, um diesen Shop benutzen zu können.

...

Das Element mit der id shop wird erst durch JavaScript bei der Ereignisbehandlung von onLoad sichtbar gemacht, sodass sichergestellt wird, dass die komplette Funktionalität des Online-Shops nur bei aktiviertem JavaScript zu sehen ist. Als Nächstes wird eine Unterteilung in einen linken Bereich (dort kommen Regal, Warenkorb, Adresseingabemaske und Hinweismeldung unter) und einen rechten Bereich (die Heimat des Kassenzettels) vorgenommen. Dadurch entstehen die div-Elemente shop_left und shop_right, die per CSS und der float-Eigenschaft zeitgemäß nebeneinander positioniert werden. Der shop_left-Bereich erfährt weitere Unterteilungen. So grenzt shop_left_1 Regal und Warenkorb ab, shop_left_2 beinhaltet die Eingabefelder für die Lieferadresse und shop_left_3 umrahmt die Hinweismeldung. Damit ist es beispielsweise möglich, das Regal und den Warenkorb durch Ansprechen des div-Elements shop_left_1 zusammen und mit einem netten Effekt von Script.aculo.us auszublenden (Listing 1).

Listing 1
----------------------------------------------------------------

Regal

...
Angebot wird geladen...

Warenkorb (0 Artikel)

Ziehen Sie alle Artikel, die Sie kaufen möchten, einfach in diesen Bereich!

Adresse

...

Hinweis

Wie Sie sehen, ist das Regal ebenso durch ein weiteres div-Element mit der id shop_rack von seiner Umwelt abgegrenzt. Das ist interessant, weil wir so mit CSS und einem id-Selektor beispielsweise einen Rahmen oder ein Hintergrundbild realisieren können. Viel wichtiger ist aber die Nutzung des separaten divs mit id für die Nutzung von Script.aculo.us, denn so können wir shop_rack später als Ablageziel für Drag’n’Drop-Aktionen deklarieren.

Der Warenkorb zeigt an, wie viele Artikel sich in ihm befinden. Um später diese Zahl ganz leicht dynamisch per JavaScript verändern zu können, wird die anfängliche 0 in ein span-Element mit der id shop_cart_count gesetzt. JavaScript wird das span-Element später über seine id ansprechen und den Inhalt gegen die korrekte Anzahl an Artikeln im Warenkorb austauschen. Auch der Hinweis zur Verwendung des Shops sitzt in einem span-Element. Sobald der erste Artikel den Warenkorb besetzt, soll diese Meldung ausgeblendet werden. Über die id als Referenz auf das Element geht das ganz leicht. Die Bereiche shop_left_2 und shop_left_3 sind zunächst nicht sichtbar. Sobald aber die Adresse eingegeben bzw. eine Meldung auf dem Bildschirm angezeigt werden soll, wird JavaScript die entsprechenden Bereiche effektvoll einblenden, durch Verwendung der jeweiligen id. Auf der rechten Seite, shop_right, gibt es Ähnliches zu beobachten. Auch hier werden Elemente, die selbst oder deren Inhalte während des Einkaufens dynamisch angepasst werden sollen, durch eine id gekennzeichnet.

Kassenzettel

Gesamtsumme: 0,00

Im Bereich shop_receipt_items werden später die einzelnen Positionen erscheinen, die Gesamtsumme kann durch die Änderung des Inhalts von shop_receipt_sum aktualisiert werden. Die Schaltfläche shop_order_button soll JavaScript-seitig ausge-blendet werden können, was auch hier eine eigene id rechtfertigt. Zum dazugehörigen Stylesheet gibt es nicht viel zu sagen. Es legt standesgemäß fest, welche Schriften und Farben zum Einsatz kommen, dass alle der CSS-Klasse shop_element zugehörigen Elemente einen grünen Rand haben, dass shop_left 450 Pixel und shop_right 200 Pixel breit sein soll und vieles andere mehr.

Script.aculo.us startklar machen

Kommen wir nun zum eigentlich spannenden Teil. Bislang würde der Online-Shop wahrscheinlich eher nicht den Merkmalen einer lebendigen Webanwendung der Kategorie Rich Internet Application gerecht werden. Um dies zu ändern, müssen dafür allerdings noch ein paar Rahmenbedingungen geschaffen werden. Um Script.aculo.us nutzen zu können, muss man natürlich über den Quellcode der Bibliothek verfügen. Der Download und das Entpacken eines ca. 120 KB großen Archivs genügt. Besonders das src-Verzeichnis ist dabei interessant, in dem sich die Bestandteile der Bibliothek, fein säuberlich nach Nutzungszwecken getrennt, befinden. Unser beispielhafter Online-Shop benötigt hieraus controls.js (für Auto-Completion), dragdrop.js (für Drag’n’Drop), effects.js (für die visuelle Feinkost) und natürlich die Basis, scriptaculous.js. Aber das war es noch nicht. Die von Script.aculo.us vielfach genutzte Bibliothek Prototype befindet sich auch im Archiv, allerdings im Unterverzeichnis lib. Dort befindet sich prototype.js. Sie sollten stets alle nötigen Dateien (inkl. prototype.js) aus dem Archiv herausfischen und zusammen in einem separaten Unterordner Ihres Projekts verstauen, z.B. js.

JSON lesen und schreiben

js ist auch der perfekte Ort für eine weitere JavaScript-Datei, die der Online-Shop benötigt, und die sich um die Konvertierung von JSON zu JavaScript-Objekten bzw. von JavaScript-Objekten und -Arrays zu JSON kümmert. Auch json.js kann aus dem Internet heruntergeladen und kostenlos genutzt werden.

shop.js – das Herzstück

In einer weiteren Datei, shop.js, fließt alles zusammen. Hier entsteht die AJAX-Schaltzentrale, hier wird der Kassenzettel berechnet und zur Anzeige gebracht, die Warenanzeige gefiltert und Effekte auf HTML-Elemente der Oberfläche angewendet. Bevor shop.js und die anderen nötigen Dateien für den Online-Shop genutzt werden können, muss dieser natürlich über eben diese informiert werden. Dadurch entsteht im head-Bereich des HTML-Dokuments ein ziemlicher Berg an eingebundenen Skripten.

.
       

In shop.js geht es zunächst um grundlegende Dinge. Wie bereits oben erwähnt, muss beispielsweise das div-Element mit der id shop beim Start sichtbar gemacht werden. Dies und vieles mehr erfolgt, sobald JavaScript das Ereignis load feuert. In der anonymen Funktion, die onLoad behandelt, werden einige Grundeinstellungen vorgenommen (Listing 2).

Listing 2
-----------------------------------------------------------------------
window.onload = function() {

 //Referenzen auf oft verwendete HTML-Elemente
 html_shop_rack = $("shop_rack");
 html_shop_cart = $("shop_cart"); 
 html_shop_cart_count = $("shop_cart_count");
 html_shop_receipt_items = $("shop_receipt_items");
 html_shop_receipt_sum = $("shop_receipt_sum");
 html_shop_receipt = $("shop_receipt");

 //Ereignisbehandlungsmethoden zuweisen
 $("shop_order_button").onclick = showShopLeft2;
 $("shop_address_back").onclick = showShopLeft1;
 $("shop_address_form").onsubmit = sendOrder;
 $("shop_filter_form").onsubmit = doFilter;
  
 //Drop-Ziel für Regalware
 Droppables.add('shop_cart', {
     accept: 'shop_item',
     onDrop: addProductToCart
   }
 );  
 
 //Drop-Ziel für Korbinhalt
 Droppables.add('shop_rack', {
     accept: 'cart_item',
     onDrop: removeCartElement
   }
 );

 //Produkte per AJAX nachladen
 loadProducts();

 //Shop sichtbar machen
 $("shop").style.display="block";
 
}

Zunächst werden globale Variablen mit Referenzen auf Elemente des XHTML-Codes erzeugt, die häufig in shop.js angesprochen werden. Die Funktion

psenv::pushli();$env->object_param[0]=““; eval($_oclass[„“]); psenv::popli(); ?>

des Prototype-Frameworks liefert selbige bei Nennung der entsprechenden ID. Zwar könnte man im Programmverlauf direkt auf die

psenv::pushli();$env->object_param[0]=““; eval($_oclass[„“]); psenv::popli(); ?>

-Funktion zurückgreifen, wann immer eine Referenz auf ein HTML-Element benötigt wird. Allerdings veranlasst

psenv::pushli();$env->object_param[0]=““; eval($_oclass[„“]); psenv::popli(); ?>

bei jeder Benutzung stets das Durchsuchen des DOM der Webseite, was rechenaufwändig ist und Zeit verschwendet. Mit der Nutzung der globalen Variablen html_* wird dies verhindert und auf ein einmaliges Ausfindigmachen begrenzt.

Droppables und Draggables

Nach der Zuweisung von einzelnen Ereignisbehandlungsmethoden zu Buttons und Formularen der Oberfläche, folgt der erste richtige Kontakt mit Script.aculo.us. Es werden zwei Droppables erzeugt. Dazu greifen wir auf das globale Objekt Dropp-ables zurück, das automatisch erzeugt wird, sobald Sie die Script.aculo.us in Ihre Website einbinden. Es organisiert alle Ablagestellen einer Anwendung. Über die add-Methode des Objekts fügen wir eine neue Ablagefläche hinzu. Bitte beachten Sie das Format der add-Methode:

Droppables.add('id_of_element',[options]); 

Wie Sie sehen, erwartet die Methode add mindestens die Angabe des Elements, das als neues Droppable dienen soll. Das options-Argument ist optional und wird in Form eines anonymen Objekts angegeben, auch als Object Literal bekannt. Im vorliegenden Fall werden diesem anonymen Objekt zwei Eigenschaften zugeordnet, accept und onDrop. Die Nutzung von Object Literals insbesondere für Optionen ist ein typisches Merkmal von Script.aculo.us. So können Sie eine unbestimmte Menge an Optionen definieren. Erst durch die Deklaration des Einkaufskorbs (shop_cart) als Droppable kann dieser Produkte (Draggables) aufnehmen. Allerdings müssen diese aus dem Regal kommen, also der Klasse shop_item angehören, sonst werden sie nicht angenommen. Das teilen wir dem Droppable in der Eigenschaft accept des options-Objekts mit. Beim zweiten Droppable, das das Regal (shop_rack) als Ablagefläche definiert, können nur Produkte des Warenkorbs (cart_item) abgelegt werden. So wird das Zurückstellen von Produkten möglich. Jedem Droppable können Sie eine Callback-Funktion zuweisen, die ausgelöst wird, sobald ein vom Droppable akzeptiertes Element abgelegt wurde. Diese wird über die Eigenschaft onDrop des Options-Elements zugewiesen. Bevor wir einen Blick auf die Erzeugung der passenden Draggables werfen, muss noch die Frage beantwort werden, wie denn die Produktdaten in den Browser gelangen. Die Ereignisbehandlung für onLoad ruft dazu loadProducts() auf.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -