3.6.1 Datenbankkonnektivität mit LiveWire
LiveWire stellt wahlweise zwei Möglichkeiten zur Datenbankkonnektivität zur Verfügung:
Der "Standard Approach" vereinfacht die Programmierung, da nur einmal (sinnvollerweise in der Initialisierungsseite, vgl. Installation von LiveWire-Applikationen in Abschnitt 3.7.3) eine Datenbankverbindung etabliert werden muß und alle Clients sich die selbe Datenbank und die gleichen Benutzerrechte teilen. Außerdem ist es für LiveWire nur unter dieser Verbindungsart möglich, mehrere Datenbankverbindungen parallel zu öffnen, was bei vielen gleichzeitig zugreifenden Clients (typische Situation für eine stark frequentierte Anwendung wie die Hyperlinkdatenbank) deutliche Performancevorteile bringt.
Beim "Serial Approach" muß auf jeder HTML-Seite, die eine Datenbankverbindung benötigt, diese neu aufgebaut und anschließend wieder geschlossen werden und das project-Objekt jeweils für diesen Zweck gesperrt werden. Dafür kann nach diesem Ansatz jeder Client individuelle Benutzerrechte erhalten und unterschiedliche Datenbanken benutzen.
Um die Vorteile des "Standard Approach" nutzen zu können und trotzdem den Zugriff auf die Verwaltungsfunktionen beschränken zu können, habe ich die Anwendung in zwei getrennte LiveWire-Applikationen geteilt, die lediglich die gleiche Datenbank benutzen. Somit können beide Anwendung nach dem "Standard Approach" erstellt werden, und die Verwaltungsapplikation wird über die Web-Server-Zugriffsrechte für nicht autorisierte User gesperrt.
3.6.2 Links.html - die zentrale Hyperlinkdatenbank-Seite
Diese HTML-Seite stellt praktisch die vollständige Benutzeroberfläche zur Navigation durch den Themenkatalog und das Erreichen der Hyperlinkeinträge dar. Sie wird mit einer Themen-ID als Parameter aufgerufen und stellt die folgenden drei Elemente wie in Abbildung 15 illustriert dar:
Im folgenden Listing der Seite links.html kann man nun die Vorteile der gewählten Datenbankstruktur sehen: Für alle drei Elemente sind sämtliche Daten jeweils durch eine einfache Select-Anweisung auf jeweils nur eine einzige Tabelle ohne Joins verfügbar.
Insbesondere wird jetzt klar, warum in der Datenbanktabelle Themen (vgl. Tabelle 4) die Konvention qid=tid für Originalthemen gilt: Dadurch kann die für den Hyperlink benötigte ID zum Aufruf eines Unterthemas oder Querverweises für beide Typen aus dem gleichen Datenbankfeld (qid) ausgelesen werden. Die Alternative wäre gewesen, qid für Originalthemen auf Null zu setzen, und jeweils anhand einer IF-Abfrage entweder das Feld tid oder qid zu verwenden.
<html> <head> <title>Linkdatenbank</title> <server> // Überschrift selektieren ueberschrift = database.cursor("SELECT name, ueberschrift FROM Themen WHERE tid=" + request.id); // Unterthemen selektieren themen = database.cursor("SELECT qid, name FROM Themen WHERE refid=" + request.id + " ORDER BY name"); anzahl = database.cursor("SELECT COUNT(*) AS themen FROM Themen WHERE refid=" + request.id); // Links zu diesem Thema selektieren links = database.cursor("SELECT url, name, sprache, beschreibung FROM Links WHERE thema=" + request.id + " ORDER BY name"); </server> </head> <BODY BGCOLOR="#FFFFFF" LINK="#0000FF" ALINK="#FF0000"> <p align=center><b><font size=6 color="#0000AA">A</font><font size=5 color="#0000AA">LTERNATIV</font><font size=5 color="#00B900">EN</font> <font size=6 color="#0000AA">S</font><font size=5 color="#0000AA">UCHEN</font></b> <br><font size=-1> <a href="formular.html">Formularrecherche & Stichwortsuche</a> | Top Ten</a> | Neuen Link hinzufügen</a> | Hilfe</a> </font></p> <br> <p><b><a href="home.html">Homepage</a> : <SERVER> ueberschrift.next(); if (ueberschrift.ueberschrift != null) write(ueberschrift.ueberschrift, " "); write(ueberschrift.name); ueberschrift.close(); </SERVER></b></p> <table border=0 cellpadding=10><tr><td valign="top" width="50%"><ul> <SERVER> anzahl.next(); var anzhalbe = Math.round(anzahl.themen/2); var i = 0; if (anzahl.themen < 6) while (themen.next()) write("<li> <a href=links.html?id=", themen.qid, ">", themen.name, "</a>\n"); else { while (themen.next()) { write("<li> <a href=links.html?id=", themen.qid, ">", themen.name, "</a>\n"); if (++i == anzhalbe) write('</ul></td><td valign="top" width="50%"><ul>\n'); } } themen.close(); anzahl.close(); </SERVER> </ul></td></tr></table> <SERVER> displayLinks (links); </SERVER> </body> </html> |
Listing 8: links.html - die zentrale Hyperlinkdatenbank-Seite |
Die Unterthemen werden, sofern es mindestens sechs Stück sind, zweispaltig aufgelistet, um den Bildschirmplatz besser auszunutzen. Die Hyperlinkeinträge werden mit der folgend abgedruckten globalen Funktion displayLinks() dargestellt, die auch von den übrigen Linkdarstellenden Seiten verwendet wird.
// Parameter links muß database.cursor-Objekt sein // mit den DB-Spalten url, name, beschreibung function displayLinks (links) { var anzahl=0; write('<table border=0 cellpadding=10><tr><td><ul>\n'); while (links.next()) { anzahl++; write('<li> <a href="', links.url, '">', links.name, '</a>'); write(' <img src="images/sprache', links.sprache, '.gif"><br>\n'); if (links.beschreibung != null) write(links.beschreibung, '\n'); } links.close(); write('</ul></td></tr></table>\n'); if (anzahl==0) return false; else return true; } |
Listing 9: In Datei "displayLinks.js" gespeicherte Funktion zur Darstellung einer Hyperlinkliste |
Durch die Wertezuordnung der Sprachen zu Zweierpotenzen (deutsch=1, englisch=2, sonstiges=4) ist auch in diesem Fall eine eindeutige Auswertung der Datenbankwerte ohne zusätzliche (zeitaufwendige) Bedingungsabfragen möglich, indem für die sieben möglichen Kombinationen jeweils passende Logos entworfen wurden (vgl. Tabelle 10).
Wert | Sprache(n) | Symbol | Dateiname |
1 | deutsch | sprache1.gif | |
2 | englisch | ![]() |
sprache2.gif |
3 | deutsch + englisch | ![]() |
sprache3.gif |
4 | sonstiges | ![]() |
sprache4.gif |
5 | deutsch + sonstiges | ![]() |
sprache5.gif |
6 | englisch + sonstiges | ![]() |
sprache6.gif |
7 | deutsch + englisch + sonstiges | ![]() |
sprache7.gif |
Tabelle 10: Auswertung des Datenbankfeldes "Sprache"
Der Return-Wert der Funktion displayLinks() wird in der Seite links.html nicht ausgewertet.
Eine simple Einstiegsseite für die
Hyperlinkdatenbank kann durch Aufruf des URLs links.html?id=0
zwar ebenfalls bereitgestellt
werden, um aber einen breiteren Einstieg und mehr
Gestaltungsmöglichkeiten zu haben sowie andere
Abfragemöglichkeiten einbinden zu können, ist es sinnvoll, die
Homepage (home.html) als separate Seite zu gestalten.
Ich habe zu diesem Zweck neben den Themen der obersten Ebene jeweils alle direkten Unterthemen aufgeführt, so daß man auf den ersten Blick einen besseren Eindruck von dem in der Datenbank enthaltenen Themenspektrum erhält. Selbstverständlich müssen Änderungen im Themenkatalog, die diese Themen betreffen, in der Homepage manuell nachgebessert werden. Abbildung 20 zeigt die Homepage des Prototypen, die neben den Themenlinks auf die Seite links.html auch die Verweise auf die in den folgenden Abschnitten besprochenen zusätzlichen Abfragen beinhaltet.
Abbildung 20: Die Homepage der Hyperlinkdatenbank
3.6.3 Die Grünen Seiten
Für die "Grünen Seiten", das ökologische Branchenbuch, gibt es das Thema der obersten Ebene "Unternehmen". Darunter werden alle Branchen als normale Unterthemen erfaßt, sowie die Unternehmen selbst als Hyperlinkeinträge mit Ihren Firmennamen als Titel, so daß für die Branchenorientierte Suche wiederum die Seite links.html verwendet werden kann. Dabei bleibt es sogar offen, ob man Branchenbuchüblich eine eindimensionale Branchenliste verwenden will, oder das Branchenbuch wie die übrigen Themenbereiche hierarchisch aufbaut.
Für eine alphabetische Auflistung aller Unternehmen des Branchenbuches gibt es eine eigene Seite (firmen.html). Sie enthält folgende SQL-Abfrage:
links = database.cursor("SELECT links.* FROM links,
themen WHERE
(links.thema=themen.tid AND themen.sortierung LIKE
'Unternehmen%')
ORDER BY links.name");
Für diese Abfrage ist es notwendig, daß das Oberthema für die Unternehmen tatsächlich "Unternehmen" lautet. Dafür ist es aber auch hier durch die Anwendung der LIKE-Klausel auf das Themen-Feld sortierung wiederum möglich, mit einer einzigen SQL-Abfrage alle Daten zu erhalten. Wenn man die Abfrage über die Themen-ID machen würde, müßte bei einem hierarchischen Branchenbuch wiederum für jeden Datensatz zunächst durch mehrere rekursiv aufgerufene SQL-Anfragen festgestellt werden, ob für den betreffenden Link das Thema der obersten Ebene das der Unternehmen ist, was einen bedeutend höheren Aufwand darstellt.
Abbildung 21: Alphabetisch sortierte Unternehmensliste mit firmen.html
3.6.4 Regionales
Für die Suche nach regionalen Gesichtspunkten steht sowohl eine Selektion nach Städten als auch nach einem variablen Postleitzahlenbereich zur Verfügung. Für ersteres wird zunächst eine Liste aller Städte erzeugt, für die es mindestens einen Hyperlinkeintrag gibt (vgl. Abbildung 22). Diese Vorselektion erspart es dem Benutzer, erst eine Stadt auszuwählen und eine neue HTML-Seite zu laden, um dann zu erfahren, daß es keine Einträge gibt. Die Städteliste wird mit der Seite staedte.html erzeugt, die dazu folgende SQL-Anfrage enthält:
staedte = database.cursor("
SELECT DISTINCT staedte.*, laender.lkz FROM staedte, laender, links WHERE staedte.stid = links.stadt AND staedte.land = laender.lid ORDER BY staedte.land, staedte.name, staedte.region");
Abbildung 22: Liste aller Städte mit mindestens einem Eintrag (staedte.html)
Die einzelnen Zeilen dieser Liste werden in einer Schleife mit folgendem Befehl erzeugt, der den Aufruf einer weiteren Seite (stadtlinks.html) deutlich macht, auf der alle Linkeinträge aus dieser Stadt aufgelistet werden:
write ("<li> <a
href=stadtlinks.html?id=", staedte.stid, ">",
staedte.lkz, " -
",
staedte.name, " (",
staedte.region, ")</a>\n");
In stadtlinks.html werden nun alle Links selektiert, die im stadt-Feld den Übergabeparameter (Stadt-ID) enthalten:
links = database.cursor("SELECT url, name, sprache,
beschreibung
FROM Links WHERE stadt=" + request.id + " ORDER BY
name");
Abbildung 23: Alle Einträge einer Stadt (stadtlinks.html)
Die Selektion nach PLZ-Bereich wurde mit der in
Listing 10 abgedruckten Seite linksplz.html realisiert,
die beim ersten Aufruf keinen Parameter übergeben bekommt
(dadurch request.von == null
).
Sie enthält ein Miniformular zur Eingabe der Werte von
und bis zur Bestimmung des gewünschten PLZ-Bereiches.
Eine Anfrage ruft die selbe Seite wiederum auf, nun allerdings
mit gesetzten Parametern von und bis. Zunächst
werden die Parameter auf Gültigkeit geprüft. Dies geschieht in
diesem Fall auf Serverseite, um die geforderte Kompatibilität
der Anwendung zu nicht JavaScript-fähigen Browsern zu
gewährleisten.
Wenn die Parameter korrekt sind, werden die entsprechenden Linkeinträge selektiert und über die displayLinks()-Funktion dargestellt, andernfalls erscheint an deren Stelle eine Fehlermeldung für den Benutzer.
Abbildung 24: Ergebnis einer Selektion nach PLZ-Bereich (linksplz.html)
In jedem Fall wird auch das Formular für die Bereichseingabe wieder angezeigt, und die Eingabefelder mit den zuvor gemachten Eingaben vorbelegt. Einerseits sieht der Benutzer zusätzlich zur Ergebnisliste von Links auch die Eingabewerte, andererseits kann im Fehlerfall der ungültige Wert direkt erkannt und korrigiert werden. Außerdem kann ggf. sofort eine neue Selektion gestartet werden, ohne erst wieder eine zusätzliche Seite laden zu müssen.
<html> <head> <title>Linkdatenbank - Auswahl nach PLZ-Bereich</title> <server> var von=parseInt(request.von); var bis=parseInt(request.bis); var fehler=false; if (request.von == null) { // Erster Aufruf von Homepage request.von = ""; request.bis = ""; } else { // Links selektieren // Auf Serverseite Gültigkeit der Parameter (von, bis) prüfen if (von==0 || bis==0) fehler = true; else { // Links in diesem PLZ-Bereich selektieren, links = database.cursor("SELECT DISTINCT links.hlid, links.url, links.name, links.sprache, links.beschreibung FROM links, staedte WHERE links.stadt=staedte.stid AND staedte.region BETWEEN " + von + " AND " + bis + " AND staedte.region<>0 ORDER BY links.name"); } } </server> </head> <BODY BGCOLOR="#FFFFFF" LINK="#0000FF" ALINK="#FF0000"> <p align=center><b><font size=6 color="#0000AA">A</font><font size=5 color="#0000AA">LTERNATIV</font><font size=5 color="#00B900">EN</font> <font size=6 color="#0000AA">S</font><font size=5 color="#0000AA">UCHEN</font></b> <br><font size=-1> <a href="formular.html">Formularrecherche & Stichwortsuche</a> | Top Ten</a> | Neuen Link hinzufügen</a> | Hilfe</a> </font></p> <br> <p><b><a href="home.html">Homepage</a> : Regionales : Postleitzahlenbereich</b></p> <form action="linksplz.html" method="POST"> Bitte wählen Sie den Postleitzahlenbereich (die ersten zwei Ziffern)<br>aus, für den Sie sich interessieren:<br> <SERVER> write('von <input type=input name=von value="' + request.von + '" size=2 maxlength=2>'); write(' bis <input type=input name=bis value="' + request.bis + '" size=2 maxlength=2>'); </SERVER> <input type=submit value="Anfrage starten"> </form> <SERVER> if (fehler) write('<p><b><i>Sie haben ungültige Werte eingegeben. Für den PLZ-Bereich sind nur Werte zwischen 01 und 99 gültig!<br>Bitte korrigieren Sie Ihre Eingaben und wiederholen die Anfrage.</i></b></p>'); else displayLinks (links); </SERVER> </body> </html> |
Listing 10: linksplz.html |
3.6.5 Formularrecherche & Stichwortsuche
Die Formularrecherche ist wie die Selektion
nach PLZ-Bereich mit einer einzigen Seite (formular.html)
realisiert, die sich für die Ausführung einer Recherche
wiederum selbst aufruft. Der erste Aufruf erfolgt ohne
Übergabeparameter und wird in der Seite anhand des Testes request.sb==null
festgestellt, da sb sonst den
Suchbegriff als Parameter enthält.
Abbildung 25: Leeres Formular nach erstem Aufruf der Formularrecherche
Beim ersten Aufruf der Seite erscheint lediglich das Formular, so vorbelegt, das eine Anfrage ohne weitere Änderungen alle Kategorien und Hyperlinkeinträge in der Datenbank finden würde. Abbildung 25 zeigt die möglichen Selektionskriterien. Nach dem Suchbegriff wird sowohl in den Kategorienamen, als auch in den Hyperlinks gesucht (Felder name, beschreibung und url). Mit den übrigen Feldern (hell unterlegt) kann die Suche optional weiter eingeschränkt werden.
Alternativ kann auch nur der hell unterlegte Formularteil verwendet werden, um gezielt nach bestimmten Kriterien zu selektieren, z.B. nach "internationalen Unternehmen (außerhalb D, AU und CH) mit deutschsprachigen Inhalten auf ihrer Web-Site". In diesem Fall bleibt der Suchbegriff leer und es werden nur Linkeinträge, aber keine Kategorien angezeigt.
Bei der Landesselektion ist für Deutschland eine zusätzliche Beschränkung auf einen in Zehnerschritten wählbaren PLZ-Bereich möglich. In den Kategorien kann nach den Themen der obersten Ebene selektiert werden.
Wird nun eine Anfrage gestartet, muß als erstes der String für die SQL-Anfrage anhand der übergebenen Parameter zusammengebaut werden. Nach Groß- und Kleinschreibung soll bei der Stringsuche nicht unterschieden werden, so daß alle an einer LIKE-Klausel beteiligten Strings zuvor in Großbuchstaben gewandelt werden. Hierzu war eine kleine Fehlerkorrektur der in JavaScript eingebauten toUpperCase()-Methode des Stringobjektes nötig, da diese keine deutschen Umlaute erkennt und diese unverändert läßt. Die global definierte Funktion toUpperCaseDt() behebt diesen Fehler.
Nach Durchführung der SQL-Abfrage werden zunächst die Ergebnisse ausgegeben und anschließend wieder das Formular. Abbildung 26 zeigt eine beispielhafte Ergebnisseite.
Abbildung 26: Ergebnis einer Formularrecherche
Anhand der Vorbelegung der Checkboxen im Formular sieht man eine zweite Möglichkeit, neben den <SERVER>-Tags, Serverseitiges JavaScript in die HTML-Seite zu integrieren:
<input type="checkbox"
name="landau" `isChecked(request.landau)`>
Innerhalb eines HTML-Tags können sowohl Attribute (z.B. TYPE) als auch Attribut-Werte (z.B. "checkbox") durch Serverside JavaScript-Ausdrücke ersetzt werden, indem sie in sog. "Backquotes" (Accent von oben links nach unten rechts) eingeschlossen werden, wobei LiveWire Attributwerte automatisch in doppelte Anführungszeichen setzt. Es muß keine explizite write-Anweisung verwendet werden. In diesem Fall liefert die Funktion isChecked() entweder das Attribut checked oder einen Leerstring.
Folgend ist der vollständige Sourcecode der HTML-Seite formular.html abgedruckt:
<html> <head> <title>Linkdatenbank - Formularrecherche</title> <server> var sb=""; if (request.sb!=null) { sb="'%'"; if (request.sb != "") sb = "'%" + toUpperCaseDt(request.sb) + "%'"; // Kategorien-SELECT-String zusammenbauen var selectkat = ""; var anzahl = 0; if (request.katinfos == "on") { selectkat += "themen.sortierung LIKE 'Themen%'"; anzahl++; } if (request.katorgas == "on") { if (anzahl++ > 0) selectkat += " OR "; selectkat += "themen.sortierung LIKE 'Organisationen%'"; } if (request.katinfos == "on") { if (anzahl++ > 0) selectkat += " OR "; selectkat += "themen.sortierung LIKE 'Unternehmen%'"; } if (anzahl == 3) // In allen Kategorien suchen selectkat = ""; else selectkat = " AND (" + selectkat + ")"; // Land/Region-SELECT-String zusammenbauen var selectland = ""; if (request.landd == "on") { selectland += "(staedte.land=1 AND staedte.region BETWEEN " + request.von + " AND " + request.bis + ")"; } if (request.landau == "on") { if (anzahl++ > 0) selectland += " OR "; selectland += "staedte.land=2"; } if (request.landch == "on") { if (anzahl++ > 0) selectland += " OR "; selectland += "staedte.land=3"; } if (request.landint == "on") { if (anzahl++ > 0) selectland += " OR "; selectland += "staedte.land>3"; } selectland = " AND (" + selectland + ")"; // Sprache-SELECT-String zusammenbauen var selectsprache = ""; anzahl = 0; if (request.spd == "on") { selectsprache += "1, 3, 5, 7"; anzahl++; } if (request.spe == "on") { if (anzahl++ > 0) selectsprache += ", "; selectsprache+= "2, 3, 6, 7"; anzahl++; } if (request.sps == "on") { if (anzahl++ > 0) selectsprache += ", "; selectsprache += "4, 5, 6, 7"; anzahl++; } if (anzahl == 3) // In allen Sprachen suchen selectsprache = ""; else selectsprache = " AND links.sprache in (" + selectsprache + ")"; themen = database.cursor("SELECT themen.* FROM themen WHERE UPPER(themen.name) LIKE " + sb + selectkat); links = database.cursor("SELECT links.hlid, links.url, links.name, links.sprache, links.beschreibung FROM links, staedte, themen WHERE links.thema=themen.tid AND links.stadt=staedte.stid AND (UPPER(links.name) LIKE " + sb + " OR UPPER(links.url) LIKE " + sb + " OR UPPER(links.beschreibung) LIKE " + sb + ")" + selectland + selectsprache + selectkat + " ORDER BY links.name"); // sb für Formularvorbelegung wieder auf Eingabewert setzen sb = request.sb; } </server> </head> <BODY BGCOLOR="#FFFFFF" LINK="#0000FF" ALINK="#FF0000"> <p align=center><b><font size=6 color="#0000AA">A</font><font size=5 color="#0000AA">LTERNATIV</font><font size=5 color="#00B900">EN</font> <font size=6 color="#0000AA">S</font><font size=5 color="#0000AA">UCHEN</font></b> <br><font size=-1> Formularrecherche & Stichwortsuche</a> | Top Ten</a> | Neuen Link hinzufügen</a> | Hilfe</a> </font></p> <br> <p><b><a href="home.html">Homepage</a> : Formularrecherche</b></p> <!-- SUCHERGEBNISSE --> <SERVER> if (request.sb != null) { if (request.sb != "") { // Wenn Suchstring leer, keine Kategorien anzeigen write('<br><font size=+1><b>Gefundene Kategorien:</b></font>') write('<table border=0 cellpadding=10><tr><td><ul>\n'); anzahl=0; while (themen.next()) { write("<li> <a href=links.html?id=", themen.qid, ">", themen.sortierung, "</a>\n"); anzahl++; } themen.close(); write('</ul></td></tr></table>'); if (anzahl==0) write("keine Kategorieen gefunden<br>\n"); } write('<br><font size=+1><b>Gefundene Einträge:</b></font>'); if (!displayLinks(links)) write("keine Einträge gefunden<br>\n"); } </SERVER> <hr> <!-- FORMULAR --> <table border=0 cellspacing=7 cellpadding=3> <form action="formular.html" method="POST"> <tr> <td valign=baseline><b>Suchbegriff</b></td> <td bgcolor="#00B900" width=400><input type=text name=sb value=`sb` size=30 maxlength=50></td> <td width=150><font size=-1><i>Nach Sites und Kategorien suchen.</i></font></td> </tr> <tr> <td valign=baseline><b>Land</b></td> <td bgcolor="#CCDDBC"> <input type=checkbox name=landd `isChecked(request.landd)`> Deutschland <b>PLZ-Bereich</b> von <select name=von> <SERVER> for (i=0; i<10; i++) { write('<option value=', i*10); if ((i==0 && request.sb==null) || (request.von!=null && parseInt(request.von)==(i*10))) write(' selected'); write('>', i, '0\n'); } write('</select> bis <select name=bis>\n'); for (i=1; i<=10; i++) { write('<option value=', i*10-1); if ((i==10 && request.sb==null) || (request.bis!=null && parseInt(request.bis))==i*10-1) write(' selected'); write('>', i-1, '9\n'); } </SERVER> </select><br> <input type=checkbox name=landau `isChecked(request.landau)`> Österreich <input type=checkbox name=landch `isChecked(request.landch)`> Schweiz <input type=checkbox name=landint `isChecked(request.landint)`> International</td> <td rowspan=3 valign=top width=150><font size=-1><i> PLZ-Bereich gilt nur für Deutschland.<br> Lassen Sie den hellgrünen Bereich unverändert, wenn Sie ohne weitere Einschränkungen nach einem Begriff suchen. Wenn kein Suchstring angegeben wird, werden nur Sites und keine Kategorien angezeigt.</i></font></td> </tr> <tr> <td valign=baseline><b>Sprache</b></td> <td bgcolor="#CCDDBC"> <input type=checkbox name=spd `isChecked(request.spd)`> deutsch <input type=checkbox name=spe `isChecked(request.spe)`> englisch <input type=checkbox name=sps `isChecked(request.sps)`> sonstiges</td> </tr> <tr> <td valign=baseline><b>Kategorien</b></td> <td bgcolor="#CCDDBC"> <input type=checkbox name=katinfos `isChecked(request.katinfos)`> Themen, Informationen und Datenquellen<br> <input type=checkbox name=katorgas `isChecked(request.katorgas)`> Organisationen<br> <input type=checkbox name=katfirmen `isChecked(request.katfirmen)`> Unternehmen<br></td> </tr> <tr> <td></td> <td><input type=submit value="Anfrage starten"></td> </tr> </form> </table> </body> </html> |
Listing 11: formular.html |