Das Verwaltungstool ist nur für bestimmte, priviligierte Benutzer zugänglich. Deshalb können für dessen Benutzung auch weitergehende Anforderungen an den Web-Browser gestellt werden, d.h. es werden HTML-Frames und Client-JavaScript verwendet, um eine komfortablere Benutzeroberfläche und bessere Interaktionen zu ermöglichen. Als Referenzbrowser wird der Netscape Navigator 3.0 für Windows 95/NT verwendet.
Neben den im Pflichtenheft verlangten Funktionen müssen durch die besprochene Behandlung von Städten diese ebenfalls gepflegt werden können, d.h. man muß neue Städte anlegen können sowie Städte ändern und löschen können. Für diesen Prototyp habe ich auf zusätzliche Verwaltungsfunktionen für die Länder verzichtet, da ich hier keinen großen Pflegebedarf sah. Ggf. können Ergänzungen oder Änderungen direkt in der Datenbank vorgenommen werden.
3.5.1 Themenwahl - drei Frames und globale Funktionen
Ein zentrales Problem für die meisten Verwaltungsfunktionen ist die Auswahl eines Themas aus dem Themenkatalog, z.B. bei der Erfassung eines neuen Hyperlinks oder dem Löschen eines Themas. Eine simple, eindimensionale Auswahl in Form einer Liste oder eines Popup-Menüs ist hier unzureichend:
Um eine einfache Themenauswahl und einen vollständigen Überblick über den gesamten Themenkatalog zu gewährleisten, sollen die Themen zur Auswahl in einer Baumstruktur dargestellt werden (vgl. Abbildung 19). Da diese Darstellung bei entsprechender Datenbankgröße recht platzraubend ist, ist eine sinnvolle Integration in ein Formular mit mehreren Feldern nicht möglich. Aus diesem Grund habe ich mich dazu entschieden, diesen "Themenbaum" in einem separaten Frame darzustellen, was zu der in Abbildung 18 dargestellten Aufteilung der Benutzeroberfläche in drei Frames geführt hat.
Abbildung 18: Benutzeroberfläche des Verwaltungstools mit drei Frames
Die Einstiegsseite des Verwaltungstools (home.html) enthält diese Frameset-Definition und benennt die einzelnen Frames, so daß sie unter diesen Namen in JavaScript adressierbar sind:
Name | Erste Seite | Funktion des Frames |
app | verwaltung.html | enthält globale JavaScript-Funktionen, die von jeder HTML-Seite in den anderen Frames aufgerufen werden können |
links | menue.html | Hauptframe, in dem alle Formulare geladen werden |
rechts | leer.html | stellt besondere Auswahlen (Themenbaum, Hyperlinks oder Städte) zum Ausfüllen der Formulare im linken Frame dar |
Tabelle 8: Die Frames des Verwaltungstools und ihre Funktionen
Da es für JavaScript auf Clientseite - im Gegensatz zu serverseitigem JavaScript - keine Möglichkeit gibt, globale Funktionen oder Objekte in einer externen Datei für mehrere HTML-Seiten zur Verfügung zu stellen, habe ich den app-Frame ("Applikations-Frame") für diesen Zweck eingeführt, der eine HTML-Seite mit globalen Definitionen läd und beibehält. Ohne die Verwendung von Frames gäbe es keine Möglichkeit, den beschriebenen Mißstand zu umgehen, und diese Funktionen müßten in jede HTML-Seite, wo sie benötigt werden, kopiert werden.
3.5.2 Gleichzeitiges Laden von zwei Frames - JavaScript-Events
Durch diese Aufteilung der Frames entsteht die Notwendigkeit, mit einem URL in zwei Frames gleichzeitig neue HTML-Seiten laden zu müssen. Da dies nicht möglich ist, habe ich auf eine weitere Funktionalität von JavaScript zurückgegriffen: Events. Die meisten Events (und dazugehörigen Event Handler) stehen im Zusammenhang mit HTML-Formularen zur Verfügung. Eine Auflistung kann z.B. in [L4], S. 778ff. gefunden werden.
Der Event Load wird beim Laden einer HTML-Seite ausgelöst. Im Body-Tag der HTML-Seite kann dem zugehörigen Eventhandler onLoad eine JavaScript-Funktion zugeordnet werden, die beim Auftreten des Events ausgeführt wird. D.h. z.B. für die Auswahl des Menüpunktes "Neues Thema anlegen", daß ein einfacher Link im gleichen Frame (links) die Seite neuthema.html aufruft, die folgenden Body-Tag enthält:
<body onLoad="parent.rechts.location='themenbaum.html?quer=false'">
parent referenziert in einem Frame den diesen definierenden Frameset, rechts ist ein anderer Frame dieses Framesets und location gibt den URL an, der in diesen Frame geladen werden soll. Damit wird mit dem Laden der Seite neuthema.html im links-Frame automatisch auch die Seite themenbaum.html im rechts-Frame geladen.
Abbildung 19: Formular "Neues Thema anlegen" mit "Themenbaum" im rechten Frame
3.5.3 Clientseitige Formularvalidierung mit JavaScript
Das folgende Listing ist der HTML-Code für das in Abbildung 19 im linken Frame dargestellte Formular für die Erfassung eines neun Themas (neuthema.html), an dessen Beispiel der Einsatz von JavaScript für die Clientseitige Validierung von Formulareingaben gezeigt werden soll. Die fett-kursiv gedruckten Kommentare dienen der Erläuterung im Kontext dieses Abschnittes und sind nicht im tatsächlichen Sourcecode vorhanden. Zusammen mit diesen Kommentaren sollte das Listing einen hilfreichen Einblick in die C/C++ ähnliche Syntax von JavaScript sowie in eine typische Anwendug von Clientside JavaScript zur Formularvalidierung geben.
<html> //
Kennzeichnung von Clientside JavaScript <!-- //
Auskommentierung des JS-Codes für function pruefen(formular) { // Array aus
anderem Frame,enthält alle gültigen Themen-IDs (dazu im nächsten Abschnitt mehr) var bez =
formular.bezeichnung.value; // typische
Referenzierung vonWerten aus Formularelementen // *** Bezeichnung
nicht leer? // schickt die geprüften Daten nun ab return
true; //
Laden des Themenbaums im rechten Frame<p align="center"><font
size="4"><b> // Statt eines
Submit-Buttons, der üblicherweise zum Abschicken der Formulardaten verwendet wird, wird über einen normalen Button mit dem onClick-Eventhandler die Validierungsfunktion aufgerufen. Der Parameter this.form referenziert das Formularobjekt, von dem der Button (this = der Button selbst) ein Teil ist. <input
type=reset value="Zurücksetzen"></td> |
Listing 2: Formularvalidierung in neuthema.html |
3.5.3 Darstellung des Themenbaums - das "database"-Objekt
Das in diesem Abschnitt abgedruckte Listing stellt zwar den Themenbaum wie in Abbildung 19 gezeigt dar, entspricht aber nicht dem Originalsource, da der Einfachheit halber ein Teil entfernt wurde, der erst im nächsten Abschnitt besprochen werden soll.
Hier soll der typische Einsatz von Serverside JavaScript mit Benutzung des request-Objektes und dem Zugriff auf die Datenbank demonstriert werden, sowie die Struktur der Datenbanktabelle themen weiter erläutert werden.
Das database-Objekt von LiveWire handhabt den Zugriff auf die Datenbank. Es bietet Methoden zum Verbindungsauf- und abbau und für die Transaktionenverwaltung sowie zum Error Messaging. Daten aus einem SQL-SELECT werden im cursor-Objekt verwaltet, welches - wie im Listing ersichtlich - den SQL-Select-Befehl in einem String als Parameter erhält. Die Ergebnisdaten sind über Attribute mit den Feldnamen der Datenbanktabellen aus dem Select-Befehl zugänglich. Die next()-Methode bewegt den Cursor in die nächste Reihe der Ergebnistabelle und liefert false, falls das Ende der Tabelle erreicht ist. Mit der database.execute()-Methode können beliebige vom Datenbankserver unterstützten SQL-Befehle sowie Stored Procedure-Aufrufe an diesen abgesetzt werden, die keinen Cursor als Ergebnis liefern ("passthrough SQL").
In Abschnitt 3.5.2 wurde der Aufruf dieser Seite in der Anwendung bereits gezeigt. In einem "normalen" Hyperlink könnte er auch folgendermaßen aussehen:
<a href="themenbaum.html?quer=true">Themenbaum</a>
Der Parameter quer gibt an, ob die Querverweise ebenfalls auswählbar, d.h. klickbar sein sollen, oder nicht. Bei der Neuanlage eines Themas dient der Themenbaum beispielsweise zur Auswahl des Oberthemas, dem das neue Thema untergeordnet werden soll. Hierfür sind Querverweise nicht erlaubt, weshalb sie nicht klickbar sein dürfen. In anderen Formularen dagegen können sowohl Originalthemen als auch Querverweise gewählt werden. Durch die Einführung dieses Parameters kann diese Seite für beide Fälle verwendet werden.
In der aufgerufenen Seite steht der Parameter als Attribut des durch den Aufruf erzeugten request-Objektes zur Verfügung, dessen Attribute wie die aller Objekte des Object Frameworks (vgl. Abschnitt 3.3.3) vom Datentyp string sind.
<html> <head> <title>Linkdatenbank - Themenbaum</title> <SERVER> // Request-Variable (String) als Boolean auswerten if (request.quer.toUpperCase() == "TRUE") quer = true; else quer = false; // [ *** fehlender Code: siehe in Listing 4 *** ] // Thementabelle für Darstellung des Themenbaumes auslesen themen = database.cursor("SELECT DISTINCT tid, qid, name, einzug, sortierung FROM themen ORDER BY sortierung"); </SERVER> </head> <body bgcolor="#FFFFFF"> <p align="center"><font size="4"><b>Thema auswählen</b></font></p> <pre> <SERVER> while (themen.next()) { for (var j = 0; j < themen.einzug; j++) write(' '); if (themen.tid != themen.qid && !quer) write(themen.name + '\n'); else write('<a href="javascript:parent.app.insertThema(' + themen.tid + ',\'' + escape(themen.name) + '\')">' + themen.name + '</a>\n'); } themen.close(); </SERVER> </pre> </body> </html> |
Listing 3: Einsatz von Serverseitigem JavaScript |
Der SQL-Befehl Select sortiert die Themen durch die "ORDER BY sortierung"-Klausel bereits korrekt, die While-Schleife durchläuft die Themen sequentiell. Der write-Befehl schreibt direkt "an Ort und Stelle" in die HTML-Seite. Die for-Schleife erzeugt den korrekten Einzug in der Themenhierarchie. Da der innerhalb der <SERVER></SERVER>-Tags erzeugte HTML-Code durch <pre></pre>-Tags eingeschlossen ist, wird der Text unformatiert und unverändert dargestellt, und ein Zeilenumbruch im Source (\n) auch als solcher registriert, im Gegensatz zu "normalem" HTML, wo der Zeilenumbruch durch das <br>-Tag erzeugt wird.
Die if-Abfrage kann anhand des Vergleiches tid==qid feststellen, ob es sich bei dem aktuellen Datensatz um ein Originalthema oder einen Querverweis handelt (vgl. Tabelle 4). Nur im zweiten Fall und wenn Querverweise nicht klickbar sein sollen, wird lediglich der Themenname ausgegeben. Andernfalls wird beispielsweise für das Thema mit der ID 169 und dem Titel "Vereinte Nationen" folgende Textzeile in den HTML-Source geschrieben:
<a href="javascript:parent.app.insertThema(169,'Vereinte+Nationen')">Vereinte Nationen</a>
JavaScript kann sowohl einfache () als auch doppelte Anführungszeichen (") für die Begrenzung von Stringausdrücken verwenden. Falls das wie in diesem Beispiel noch nicht genügt, kann außerdem das den Ausdruck begrenzende Zeichen durch Vorstellen eines Backslashs (\) in diesem Ausdruck ebenfalls ausgegeben werden.
Die erzeugte Zeile sorgt dafür, daß beim
Klicken auf den Text die im app-Frame gespeicherte
JS-Funktion insertThema() mit den angegebenen Parametern
ausgeführt wird, die wiederum dafür sorgt, daß die Parameter
an richtiger Stelle in das Formular im linken Frame eingesetzt
werden. Somit ist das bereits ein erstes Beispiel dafür, wie
Daten von Serverseitigem an Clientseitiges JavaScript übergeben
werden können. Die Funktionsweise der angesprochenen Funktion
ist dem Sourcecode der HTML-Seite
verwaltung.html im Anhang Anhang B: zu entnehmen.
3.5.5 Datenaustausch zwischen Server- und Clientside JavaScript
Listing 4 zeigt das in Listing 3 fehlende Stück Sourcecode zur Vervollständigung der Datei themenbaum.html.
// Erstellung eines Clientside JavaScriptes mit einem Themen-Array // zur Eingabevalidierung (gültige ID, Unterthema bei Löschung) if (quer) themenids = database.cursor("SELECT DISTINCT tid, refid FROM themen"); else themenids = database.cursor("SELECT DISTINCT tid, refid FROM themen WHERE qid=tid"); var i = 0; write('<script language="javascript"><!--\n'); write('themenliste = new Array();\n'); write('function thema(tid, refid) {\n'); write(' this.tid = tid;\n'); write(' this.refid = refid;\n}\n'); while (themenids.next()) write("themenliste[" + (i++) +"] = new thema(" + themenids[0] + ", " + themenids[1] + ");\n"); write('//--></script>\n'); |
Listing 4: Erzeugung eines Clientside-JavaScripts mit serverseitigem JavaScript |
Dieser Sourceextrakt erzeugt auf dem Server das in Listing 5 abgedruckte Clientside-JavaScript, welches wiederum ein Array definiert und mit Daten aus der Datenbank initialisiert wird. Das Array dient der Clientseitigen Überprüfung von Themen-IDs, die der Benutzer i.d.R. aus dem Themenbaum auswählt, aber auch manuell einfügen kann (vgl. Listing 2). Das Array enthält je nach übergebenem quer-Parameter auch Querverweise oder nur Originalthemen.
<script language="javascript"><!-- themenliste = new Array(); function thema(tid, refid) { // Deklaration des Thema-Objektes durch this.tid = tid; Definition seines Konstruktors this.refid = refid; } themenliste[0] = new thema(1, 0); themenliste[1] = new thema(155, 171); themenliste[2] = new thema(156, 171); themenliste[3] = new thema(157, 171); themenliste[4] = new thema(158, 171); themenliste[5] = new thema(159, 171); themenliste[6] = new thema(160, 171); themenliste[7] = new thema(161, 171); themenliste[8] = new thema(163, 172); themenliste[9] = new thema(164, 172); themenliste[10] = new thema(165, 172); themenliste[11] = new thema(166, 172); themenliste[12] = new thema(167, 172); themenliste[13] = new thema(168, 172); themenliste[14] = new thema(169, 172); themenliste[15] = new thema(170, 172); themenliste[16] = new thema(171, 0); themenliste[17] = new thema(172, 0); themenliste[18] = new thema(173, 163); themenliste[19] = new thema(174, 163); themenliste[20] = new thema(175, 163); themenliste[21] = new thema(178, 1); themenliste[22] = new thema(179, 155); themenliste[23] = new thema(180, 179); themenliste[24] = new thema(182, 179); themenliste[25] = new thema(183, 1); themenliste[26] = new thema(185, 1); themenliste[27] = new thema(192, 182); themenliste[28] = new thema(193, 185); //--></script> |
Listing
5: Beispiel für das in
themenbaum.html auf dem Server erzeugte
Clientside-JavaScript, wie es in der an den Web-Browser gelieferten Version von themenbaum.html erscheint |
In diesem Fall wird das komplette Clientside-JavaScript durch Serverseitiges JavaScript unter Einbeziehung von Serverdaten aus der Datenbank erzeugt. Theoretisch wäre auch der umgekehrte Fall denkbar: Das Clientside-JavaScript wird in den Source der HTML-Seite geschrieben, und nur die von Serverseite benötigten Parameter werden an entsprechender Stelle durch <SERVER></SERVER>-Tags innerhalb der <script></script>-Tags eingefügt.
Dies habe ich auch versucht, aber LiveWire erkennt die <SERVER></SERVER>-Tags innerhalb eines Clientside-JavaScripts nicht, so daß diese uninterpretiert zum Browser ausgeliefert werden und dort Fehlermeldungen verursachen.
Aus der LiveWire-Dokumentation ist eine solche Einschränkung nicht zu entnehmen. Möglicherweise wird dieser Fehler in einer neueren Version von LiveWire behoben, oder zumindest als Einschränkung dokumentiert.
3.5.6 Datenbankzugriff mit LiveWire - neues Thema einfügen
Alle Formulare rufen zur Verarbeitung ihrer aufgenommenen Daten die selbe Seite auf: erfolg.html. Hier werden alle schreibenden Datenbankoperationen (Insert, Update, Delete) der Anwendung durchgeführt. Um eine gewisse Übersichtlichkeit zu gewährleisten, wurden im folgend abgedruckten Sourcecode dieser HTML-Seite die Teile herausgenommen, die sich auf die Verarbeitung der Daten aus anderen Formularen beziehen und an dieser Stelle uninteressant sind.
Identifiziert wird das Formular, welches die Seite aufgerufen hat, anhand eines in jedem Formular vorhandenen Hidden-Input-Tags namens form.
<html> <head> <title>Linkdatenbank - Verwaltung</title> </head> <body bgcolor="#FFFFFF" onLoad="parent.rechts.location='leer.html'"> <p align="center"><font size="4"><b> Linkdatenbank - Verwaltung</b></font></p> <SERVER> // *** Server-Objekt sperren und DB-Transaktion starten *** server.lock(); database.beginTransaction(); // *** Neues Thema oder neuen Querverweis anlegen *** if (request.form == "neuquer" || request.form == "neuthema") { // Neue Themen-ID ermitteln project.lastTID = parseInt(project.lastTID) + 1; var newTID = parseInt(project.lastTID); // Bei Originalthema qid=tid setzen if (parseInt(request.qid) == 0) request.qid = newTID; database.execute("INSERT INTO themen (tid, refid, qid, name) VALUES (" + newTID + ", " + request.refid + ", " + request.qid + ", '" + request.bezeichnung + "')"); // Themen-Felder Ueberschrift, Sortierung und Einzug berechnen setvalues(request.refid, request.bezeichnung); database.execute("UPDATE themen SET ueberschrift='" + request.ueberschrift + "', sortierung='" + request.sortierung + "', einzug=" + request.einzug + " WHERE tid=" + newTID); } // [ *** hier fehlt Code *** ] // *** Datenbankmeldung auswerten if (database.majorErrorCode() == 0) { // DB-Aktion erfolgreich // [ *** hier fehlt Code *** ] // Erfolgsmeldung ausgeben write('<p align=center><font size=4>Ihr Auftrag wurde erfolgreich durchgeführt!</font></p>'); // Transaktion abschließen database.commitTransaction(); } else { // DB meldet Fehler // Fehlermeldung des DB-Servers ausgeben write('<font size=4><p align=center>Ihr Auftrag konnte nicht durchgeführt werden!</p>\n<p align=center>Die Datenbank meldet folgenden Fehler:</p>\n<b><p align=center>'); write(database.majorErrorMessage()); write('</p>\n<p align=center>'); write(database.minorErrorMessage()); write('</p></b></font>\n'); // Transaktion rückgängig machen database.rollbackTransaction(); } // *** Server-Objekt wieder freigeben *** server.unlock(); </SERVER> <center> <table width=300 border=0 cellpadding=10> <tr> <td width=50% align=center> <form> <b><input type=button value="Auswahlmenü" onClick="top.location='home.html'"></b> </form> <td> <td width=50% align=center> <form> <b><input type=button value="Zurück" onClick="history.back();history.back();"></b> </form> <td> </tr> </table> </center> </body> </html> |
Listing 6: Ausschnitt aus erfolg.html |
Zunächst wird das server-Objekt exklusiv gesperrt, um Konflikte mit anderen Clients beim Inkrementieren der anwendungsspezifischen project-Attribute (lastTID, lastHLID und lastSTID) zu vermeiden. Aus Sicht des Verwaltungstools wäre schon das Sperren des project-Objektes ausreichend, um Konflikte mit anderen Instanzen der Verwaltungsapplikation zu vermeiden. Da auf dem Server allerdings eine zweite LiveWire-Anwendung läuft (die Benutzeranwendung für den Zugriff auf die Hyperlinkdatenbank), die auf die selbe Datenbank zugreift, wie das Verwaltungstool, ist es notwendig, das server-Objekt zu sperren.
Da teilweise mehrere Datenbankoperationen zur Ausführung eines Auftrages notwendig sind, wird außerdem eine explizite Datenbanktransaktion gestartet.
Die für ein neues Thema notwendige Themen-ID wird aus der im project-Objekt gespeicherten Variable lastTID ausgelesen, die zuvor inkrementiert wird. Mittels der database.execute()-Methode wird ein neuer Themen-Datensatz mit den Formularwerten der Datenbank hinzugefügt. Anschließend werden die Datenbankfelder ueberschrift, sortierung und einzug mit der in der JavaScript-Datei setvalues.js gespeicherten globalen Funktion setvalues() berechnet (Besprechung dieser Funktion im nächsten Abschnitt) und durch eine zweite Operation (Update) ebenfalls in der Datenbank gespeichert.
Nach Abschluß aller Datenbankoperationen werden eventuell aufgetretene Fehlermeldungen des Datenbankservers mittels der Methode database.majorErrorCode() ausgelesen. Im Erfolgsfall wird die Transaktion mit commitTransaction() abgeschlossen und eine Erfolgsmeldung ausgegeben. Andernfalls werden alle Datenbankoperationen mit rollbackTransaction() rückgängig gemacht und die vom DB-Server gelieferten Fehlermeldungen ausgegeben.
3.5.7 Serverside JavaScript statt Stored Procedures
Die JavaScript-Funktion setvalues() erledigt die entscheidende Aufgabe, die ansich rekursive Struktur des Themenkataloges durch einfache Select-Anweisungen auslesen zu können, indem die Inhalte der Datenbankfelder ueberschrift, sortierung und einzug für neue oder geänderte Themendatensätze berechnet werden.
function setvalues (id, themenname) { var einzug = 0; var sorti = ""; var ueber = ""; while (parseInt(id) != 0) { thema = database.cursor("SELECT tid, refid, name FROM themen WHERE tid=" + id); thema.next(); einzug += 1; sorti = thema.name + " : " + sorti; ueber = "<a href=links.html?id=" + thema.tid + ">" + thema.name + "</a> : " + ueber; id = thema.refid; } request.einzug = einzug; request.sortierung = sorti + themenname; request.ueberschrift = ueber; } |
Listing 7: Datenbankfeldberechnungen mit JavaScript-Funktion |
Da JavaScript keine rekursiven Funktionsaufrufe erlaubt, wird stattdessen eine While-Schleife verwendet. Die Funktion benötigt als Übergabeparameter die Referenz-ID und den Namen des Themas, für das die Werte berechnet werden sollen. In der While-Schleife wird nun das unmittelbare Oberthema aus der Datenbank selektiert ("...WHERE neuesThema.tid=altesThema.refid"), die benötigten Felder ausgelesen und die zu berechnenden Variablen fortgeschrieben, bevor die While-Schleife den nächsten Durchlauf, nun mit der Referenz-ID des eben selektierten Oberthemas, startet. Abbruchbedingung der While-Schleife ist, daß die ID für das nächste Thema = 0 ist, was bedeutet, daß im letzten Durchlauf ein Thema mit Referenz-ID = 0 bearbeitet wurde, also ein Thema der obersten Ebene (vgl. Tabelle 4: Datenbanktabelle "Themen").
Zur Verdeutlichung der erzeugten Werte zeigt Tabelle 9 einen Ausschnitt aus der Datenbanktabelle Themen mit folgenden drei vollständigen Einträgen: Organisationen ist ein Thema der obersten Ebene, welches u.a. das Unterthema Verbände und Vereine hat, welches wiederum ein Unterthema BUND besitzt.
Feldname | Wert |
tid | 172 |
refid | 0 |
qid | 172 |
name | Organisationen |
ueberschrift | |
sortierung | Organisationen |
einzug | 0 |
tid | 163 |
refid | 172 |
qid | 163 |
name | Verbände und Vereine |
ueberschrift | <a href=links.html?id=172>Organisationen</a> : |
sortierung | Organisationen : Verbände und Vereine |
einzug | 1 |
tid | 173 |
refid | 163 |
qid | 173 |
name | BUND |
ueberschrift | <a href=links.html?id=172>Organisationen</a> : <a href=links.html?id=163>Verbände und Vereine</a> : |
sortierung | Organisationen : Verbände und Vereine : BUND |
einzug | 2 |
Tabelle 9: Beispielhafter Auszug aus Datenbanktabelle "Themen"
Eigentlich sind solche Berechnungen dafür prädestiniert, sie mit Stored Procedures durchzuführen, d.h. mit Prozeduren, die in der Datenbank gespeichert werden und in einer Datenbankspezifischen Programmiersprache (in Oracle z.B. PL/SQL) erstellt werden. Mit der LiveWire-Methode database.execute() können solche Prozeduren problemlos aufgerufen werden. Der große Nachteil liegt darin, daß die Web-Datenbank-Anwendung durch Verwendung von Stored Procedures nicht mehr unabhängig von der verwendeten Datenbank ist. Bei einem Wechsel auf eine andere Datenbank müssen diese Stored Procedures komplett neu programmiert werden.
Mit JavaScript dagegen ist es möglich, solche Aufgaben ebenfalls Datenbankunabhängig erledigen zu können.
3.5.8 Anwendungsüberblick
Am Beispiel der Erfassung eines neuen Themas wurden nun die wichtigsten angewandten Techniken des Verwaltungstools dargestellt. Die Auswahl der Städte zum Löschen und Ändern erfolgt wie die der Themen durch eine Liste im rechten Frame. Für die Auswahl der Hyperlinks kann der Benutzer im rechten Frame wie in der Hyperlinkdatenbank durch den Themenkatalog navigieren und schließlich den gewünschten Linkeintrag durch anklicken in das linke Formular übernehmen.
In Anhang A werden alle Funktionalitäten des Verwaltungstools durch Bildschirmausdrucke illustriert und sollen so einen Eindruck von der Anwendung vermitteln.