Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 <<   zurück
JavaScript und AJAX von Christian Wenz
Das umfassende Handbuch
Buch: JavaScript und AJAX

JavaScript und AJAX
839 S., mit DVD, 39,90 Euro
Galileo Computing
ISBN 3-89842-859-1
gp Kapitel 32 Warenkorb
  gp 32.1 Datenstruktur
  gp 32.2 Mit unsichtbaren Frames arbeiten
    gp 32.2.1 Warenkorb füllen
    gp 32.2.2 Artikel anzeigen
    gp 32.2.3 Warenkorb ändern
  gp 32.3 Mit Cookies arbeiten
    gp 32.3.1 Warenkorb füllen
    gp 32.3.2 Artikel anzeigen
    gp 32.3.3 Warenkorb ändern
  gp 32.4 Über die URL
    gp 32.4.1 Den Warenkorb füllen
    gp 32.4.2 Artikel anzeigen
    gp 32.4.3 Den Warenkorb ändern
  gp 32.5 Fazit


Galileo Computing

32.3 Mit Cookies arbeiten  downtop

Wenn Sie nicht mit Frames arbeiten können oder wollen, besteht eine Alternative darin, auf Cookies zurückzugreifen.

Mit Cookies sind Sie etwas flexibler als mit Frames, da Sie mit Cookies das Problem mit dem Öffnen von Links in einem neuen Fenster einfach umgehen können.

Das Hauptproblem besteht darin, sich ein Muster zum Speichern der Cookies zu überlegen. In Kapitel 12 wurden zwei Funktionen entwickelt, die an dieser Stelle sehr nützlich sein können:

gp  schreiben_collection()
gp  lesen_collection()

Mit den beiden Funktionen (die in der Datei cookies.js liegen) können Sie ein assoziatives Array schreiben, das wiederum in einem Cookie abgespeichert werden kann. So benötigen Sie nur einen einzigen Cookie, um den kompletten Warenkorb zu behalten.

Als Namen beziehungsweise Schlüssel im assoziativen Array verwenden wir die Bestellnummern, als Wert die jeweiligen Anzahlen.


Galileo Computing

32.3.1 Warenkorb füllen  downtop

Die Funktion zum Füllen des Warenkorbs ist um einiges kürzer als die Funktion aus dem vorigen Abschnitt. Es gibt nämlich ein paar Unterschiede, die im Folgenden erläutert werden:

gp  Die Daten werden mit den beiden zuvor genannten Funktionen aus der Datei cookies.js in einem Cookie gespeichert.
gp  Die Frame-Abfragen sind nicht mehr nötig, ebenfalls muss nicht mehr direkt auf die Daten aus artikel.js zugegriffen werden. Das geschieht an anderer Stelle.

Zunächst betrachten wir, wie man von einem Artikel eine bestimmte Stückzahl zusätzlich in den Warenkorb legt:

function warenkorb_hinzufuegen_cookies(nr, stueck) {
   var anzahl = lesen_collection(nr);
   anzahl = parseInt(anzahl); // in Integer umwandeln
   if (isNaN(anzahl)) {
      anzahl = 0;
   }
   anzahl += stueck;
   schreiben_collection(nr, anzahl);
}

Aus dem Cookie wird die aktuelle Anzahl ausgelesen und in einen Integerwert umgewandelt. Dann wird die neue Anzahl hinzuaddiert und der Wert wieder zurückgeschrieben.

Ganz ähnlich ist die Funktion aufgebaut, die einem Element im Warenkorb eine ganz bestimmte Stückzahl zuweist:

function warenkorb_editieren_cookies(nr, stueck) {
   schreiben_collection(nr, stueck);
}

Dank der Vorarbeiten in Kapitel 12 besteht die Funktion, die zuvor noch recht umfangreich war, aus nur noch einer Codezeile.


Galileo Computing

32.3.2 Artikel anzeigen  downtop

Um alle Artikel anzuzeigen, werden wieder drei verschiedene Dateien erstellt:

gp  eine Seite, auf der alle Kategorien angezeigt werden: katego-rien_cookies.html
gp  eine Seite, auf der alle Artikel innerhalb einer Kategorie angezeigt werden: artikel_gesamt_cookies.html
gp  eine Seite, auf der ein Artikel in aller Ausführlichkeit angezeigt wird: artikel_einzeln_cookies.html

Der Hauptunterschied zu der zuvor entwickelten Lösung auf Frames-Basis ist, dass die Artikel und Kategorien auf der aktuellen Seite in JavaScript-Variablen zur Verfügung stehen, da die Datei artikel.js direkt eingebunden ist.

Ansonsten ist der Code sehr ähnlich. Die Kategorien werden aus den JavaScript-Variablen ausgelesen und in einer Schleife ausgegeben. Die Kategorienamen werden zudem mit der Datei artikel_gesamt_cookies. html verlinkt. Die Datei warenkorb.js muss wegen der in artikel.js verwendeten Konstruktorfunktionen ebenfalls eingebunden werden:

<html>
<head>
<title>Online-Shop</title>
<script type="text/javascript" src="warenkorb.js"></script>
<script type="text/javascript" src="artikel.js"></script>
</head>
<body>
<h1>Willkommen im Online-Buch-Shop</h1>
<p>Bitte w&auml;hlen Sie eine Kategorie!
<ul>
<script type="text/javascript"><!--
for (var i=0; i<kategorie.length; i++) {
   document.write("<li\>");
   document.write("<a href=\"artikel_gesamt_cookies.html?");
   document.write(escape(kategorie[i].name));
   document.write("\"\>");
   document.write(kategorie[i].name);
   document.write("</a\></li\>");
}
//--></script>
</ul>
</p>
</body>
</html>

In der Datei artikel_gesamt_cookies.html werden alle Artikel aus einer Kategorie ausgegeben. Auch hier gibt es kaum einen Unterschied zur Datei artikel_gesamt_frames.html; lediglich der Zugriff auf die Daten aus artikel.js ändert sich, und die Frame-Referenz entfällt:

<html>
<head>
<title>Online-Shop</title>
<script type="text/javascript" src="warenkorb.js"></script>
<script type="text/javascript" src="artikel.js"></script>
</head>
<body>
<h1>Willkommen im Online-Buch-Shop</h1>
<p>Bitte w&auml;hlen Sie einen Artikel!
<ul>
<script type="text/javascript"><!--
if (location.search.length > 1) {
   var name = location.search.substring(1,
      location.search.length);
   name = unescape(name);
   for (var i=0; i<kategorie.length; i++) {
      if (kategorie[i].name == name) {
         for (var j=0; j<kategorie[i].artikel.length; j++) {
            var a = kategorie[i].artikel[j];
            document.write("<li\>");
            document.write("<a href=\
              "artikel_einzeln_cookies.html?");
            document.write(escape(a.nr));
            document.write("\"\>");
            document.write(a.name);
            document.write("</a\></li\>");
         }
      }
   }
}
//--></script>
</ul>
</p>
<p><a href="kategorien_cookies.html">Zur&uuml;ck zur
  &Uuml;bersicht</a></p>
<p><a href="warenkorb_cookies.html">Bestellung
  aufgeben</a></p>
</body>
</html>

Auf der Seite artikel_einzeln_cookies.html muss dann der einzelne Artikel angezeigt werden und – auf Knopfdruck – zum Warenkorb hinzugefügt werden. Auch dazu verwenden wir wieder eine Hilfsfunktion namens hinzu(), die ein wenig anders aussieht als zuvor. Sie ahnen es bereits: Alle Frame-Referenzen sind verschwunden.

function hinzu(f, nr) {
   if (f.elements["anzahl" + nr]) {
      var anzahl = f.elements["anzahl" + nr].value;
      anzahl = parseInt(anzahl); //Umwandlung in Int
      if (isNaN(anzahl)) {
         anzahl = 0;
      }
      warenkorb_hinzufuegen_cookies(nr, anzahl);
      alert("Artikel hinzugefügt!");
   }
}

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 32.6     Ein (mehr oder weniger) kryptischer Cookie repräsentiert den Warenkorb.

Der Rest der Seite sieht so wie oben aus, wenn man von Frame-Verweisen einmal absieht. Ebenso wird der (nicht mehr vorhandene) Übersichtsframe nicht mehr neu geladen, da diese Anweisung ins Leere führen würde:

<html>
<head>
<title>Online-Shop</title>
<script type="text/javascript" src="warenkorb.js"></script>
<script type="text/javascript" src="artikel.js"></script>
<script type="text/javascript" src="cookies.js"></script>
</head>
<body>
<h1>Willkommen im Online-Buch-Shop</h1>
<p>Bitte geben Sie die St&uuml;ckzahl an!
<script type="text/javascript"><!--
function kategoriename(nr) {
   for (var i=0; i<kategorie.length; i++) {
      for (var j=0; j<kategorie[i].artikel.length; j++) {
         if (kategorie[i].artikel[j].nr == nr) {
            return kategorie[i].name;
         }
      }
   }
   return "";
}

function hinzu(f, nr) {
   if (f.elements["anzahl" + nr]) {
      var anzahl = f.elements["anzahl" + nr].value;
      anzahl = parseInt(anzahl); //Umwandlung in Int
      if (isNaN(anzahl)) {
         anzahl = 0;
      }
      _warenkorb_hinzufuegen_cookies(nr, anzahl);
      alert("Artikel hinzugefügt!");
   }
}

document.write("<ul\>");

if (location.search.length > 1) {
   var nr = location.search.substring(1,
      location.search.length);
   nr = unescape(nr);
   var name = kategoriename(nr);
   for (var i=0; i<kategorie.length; i++)  {
      if (kategorie[i].name == name) {
         for (var j=0; j<kategorie[i].artikel.length; j++) {
            if (kategorie[i].artikel[j].nr == nr) {
               var a = kategorie[i].artikel[j];
               document.write("<h2\>" + a.name + "</h2\>");
               document.write("<b\>" + a.kurz + "</b\>");
               document.write("<img src=\"" + a.grafik + "\"\>");
               document.write("<br\>" + a.lang + "<br\>");
               document.write("<form\>");
               document.write("<input type=\"text\" ");
               document.write("name=\"anzahl" + nr + "\" ");
               document.write("size=\"2\" value=\"1\" /\> ");
               document.write(name + " ");
               document.write(a.preis + "&euro; "); // Preis in €

               document.write("<input type=\"button\" value=\"In 
                 den Warenkorb\" ");
               document.write("onclick=\
                 "javascript:hinzu(this.form, '" + 
                 nr + "')\" /\><br /\>");
               document.write("</form\>");
            }
         }
      }
   }
   document.write("</ul\><a href=\"artikel_gesamt_cookies.html?");
   document.write(escape(name));
   document.write("\"\>");
   document.write("Zurück zu Kategorie " + name +"</a\>");
} else {
   document.write("</ul\>");
}
//--></script>
</p>
<p><a href="warenkorb_cookies.html">Bestellung
  aufgeben</a></p>
</body>
</html>

Mit relativ wenig Aufwand haben Sie die Artikelseiten des Frame-Warenkorbs in eine Lösung ohne Frames umgeschrieben, die auf Cookie-Basis arbeitet.


Galileo Computing

32.3.3 Warenkorb ändern  toptop

Jetzt fehlt nur noch eine Datei: der Warenkorb. Dieser wird mit der zuvor erläuterten Taktik umgeschrieben:

gp  Die Datei artikel.js wird eingebunden, ebenso die Dateien warenkorb.js und cookies.js.
gp  Alle Frame-Referenzen werden entfernt.

Dass das Ganze so einfach funktioniert, liegt an der Routine zum Auslesen der Stückzahlen aus dem Cookie:

var anzahl = lesen_collection(nr);
anzahl = parseInt(anzahl); // in Integer umwandeln
if (isNaN(anzahl)) {
   anzahl = 0;
}

Auch, wenn zu einem Artikel keine Daten in dem Cookie gespeichert sind, wird die korrekte Anzahl ermittelt, in diesem Fall 0.

Werfen wir noch einen Blick auf die Aufgabenverteilung: Wir müssen hier zweigleisig fahren:

gp  Die Artikelnummern werden aus den Variablen in der Datei artikel.js ermittelt.
gp  Die zugehörigen Stückzahlen kommen aus dem Cookie bzw. der Cookie-Collection (mit kräftiger Mithilfe der Funktionen in der Datei cookies.js).

Ansonsten sind keine weiteren Änderungen nötig. Aus diesem Grund finden Sie im Folgenden sofort das komplette Listing:

<html>
<head>
<title>Online-Shop</title>
<script type="text/javascript" src="warenkorb.js"></script>
<script type="text/javascript" src="artikel.js"></script>
<script type="text/javascript" src="cookies.js"></script>
</head>
<body>
<h1>Warenkorb</h1>
<form method="post" action="skript.php">
<script type="text/javascript"><!--
function update(f) {
   for (var i=0; i<f.elements.length; i++) {
      if (f.elements[i].type == "text" &&
         f.elements[i].name.substring(0, 6) == "anzahl") {
         var nr = f.elements[i].name.substring(6,
                  f.elements[i].name.length);
         var anzahl = f.elements[i].value;
         anzahl = parseInt(anzahl);
         if (isNaN(anzahl)) {
             anzahl = 0;
         }
         warenkorb_editieren_cookies(nr, anzahl);
      }
   }
   location.reload();
}
document.write("<table border=\"1\" cellpadding=\"2\"\>");

var summe = 0;
for (var i=0; i<kategorie.length; i++) {
   for (var j=0; j<kategorie[i].artikel.length; j++) {
      var a = kategorie[i].artikel[j];
      var anzahl = lesen_collection(a.nr);
      if (anzahl>0) {
         document.write("<tr\><td\>");
         document.write("<input type=\"text\" ");
         document.write("name=\"anzahl" + a.nr + "\" ");
         document.write("size=\"2\" ");
         document.write("value=\"" + anzahl + "\" /\> ");
         document.write("</td\><td\>");
         document.write("<i\>" + a.nr + "</i\> ");
         document.write("</td\><td\>");
         document.write("<b\>" + a.name + "</b\> ");
         document.write("</td\><td\>");
         document.write((anzahl * a.preis) + " &euro; ");
         document.write("</tr\>");
         summe += anzahl * a.preis;
      }
   }
}

document.write("</table\>");
//--></script>
<br />
<input type="button" onclick="update(this.form)"
  value="Aktualisieren" />
<input type="submit" value="Bestellung aufgeben" />
</form>
<a href="kategorien_cookies.html">Zur&uuml;ck zur
&Uuml;bersicht</a></body>
</html>

Der Warenkorb funktioniert nun vollständig ohne Frames, aber mit Cookies. Sie müssen die Vor- und Nachteile hier sorgfältig abwägen. Auf jeden Fall sollten Sie überprüfen, ob der Browser des Benutzers Cookies unterstützt oder nicht. Das geht in zwei Schritten (natürlich wieder unter Verwendung von Features aus Kapitel 12). Zunächst benötigen Sie eine Funktion, die einen Cookie löscht, indem ein Ablaufdatum in der Vergangenheit gesetzt wird:

function cookie_loeschen()   {
   var anzParameter = cookie_loeschen.arguments.length;
   var parameter = cookie_loeschen.arguments;
   // 1. Cookie-Name
   var name = parameter[0];
   // 2. Domain
   var domain = (anzParameter >= 2) ? parameter[1] : null;
   // 3. Pfad
   var path = (anzParameter >= 3) ? parameter[2] : null;
   if (path != null) {
      path = escape(path); // Sonderzeichen umwandeln
   }
   // 4. Sicherheitsstufe
   var secure = (anzParameter >= 4) ? parameter[3] : null;
   // Haltbarkeitsdatum
   var expires = new Date(1977, 0, 1, 0, 0, 1);
   // Aufruf von cookie_setzen
   cookie_setzen(name, "", expires, domain, path, secure);
}

Damit lässt sich die Funktion cookie_support() erstellen. Sie setzt erst ein Cookie, prüft, ob es erfolgreich gesetzt werden konnte, und löscht es dann wieder.

function cookie_support()   {
   cookie_setzen("testcookie", "ok");
   if (cookie_lesen("testcookie") == "ok") {
      cookie_loeschen("testcookie");
      return true;
   } else {
      return false;
   }
}

Sie sollten dann auf der Hauptseite Ihres Angebots eine Abfrage nach folgendem Muster integrieren:

if (!cookie_support()) {
   location.href = "keine-cookies.html";
}

Auf der Seite keine-cookies.html können Sie dann einen entsprechenden Hinweis anbringen und die Benutzer darauf hinweisen, dass sie die Cookie-Unterstützung ihrer Browser aktivieren müssen.

 <<   zurück
  
  Zum Katalog
Zum Katalog: JavaScript und AJAX
JavaScript und AJAX
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: JavaScript und AJAX - Das Video-Training






 JavaScript und AJAX -
 Das Video-Training


Zum Katalog: Webseiten programmieren und gestalten






 Webseiten
 programmieren
 und gestalten


Zum Katalog: XHTML, HTML und CSS






 XHTML, HTML und CSS


Zum Katalog: CSS-Praxis






 CSS-Praxis


Zum Katalog: AJAX






 AJAX


Zum Katalog: PHP 5 und MySQL 5






 PHP 5 und MySQL 5


Zum Katalog: TYPO3 4.0






 TYPO3 4.0


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de