vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbacknächstes Kapitel


Tag 11

JavaScript und Formulare

Heute kommen wir zu einem der ältesten und interessantesten Einsatzgebiete von JavaScript: der Bearbeitung von Steuerelement- und Formulareingaben.

Die Themen heute:

11.1 Zugriff und Ereignisverarbeitung für Steuerelemente und Formulare

Wie man mit HTML Steuerelemente und Formulare definiert, haben Sie bereits in Kapitel 3 gesehen. Auch ein erstes Beispiel zur Ereignisbehandlung für Steuerelemente haben wir Ihnen dort gezeigt.

Listing 11.1: schalter.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Schalter</title>
<meta http-equiv="Content-Script-Type" content="text/javascript">
</head>

<body>
<h2>Schalter als Beispiel für ein Steuerelement</h2>

<form>
<input type="button" name="schalter1"
value="Klick mich!" onclick="alert('Treffer')">
</form>

</body>
</html>

Man sieht: die Ereignisbehandlung für Steuerelemente unterscheidet sich in keiner Weise von der Ereignisbehandlung für die anderen HTML-Tags. Alles, was wir jetzt noch wissen müssen, um Steuerelemente und Formulare sinnvoll und nutzbringend in Verbindung mit JavaScript einsetzen zu können, ist

Zugriff auf Steuerelemente

Selbstverständlich kann man auf Steuerelemente wie auf jedes andere HTML-Element zugreifen - also beispielsweise über die proprietären Objekte document.all (Internet Explorer) und document.layers (Netscape Navigator) oder über die im DOM-Standard vorgeschlagenen Methoden (getElementById(), etc.).

Einfacher ist jedoch der Zugriff über das forms-Array des document-Objekts. Voraussetzung ist natürlich, dass die Steuerelemente in <form>-Tags eingeschlossen sind - was man aber wegen des Netscape Navigators (der Steuerelemente nur in Formularen erlaubt) sowieso tun sollte. Zur Belohnung wird der Zugriff über das forms-Array von allen wichtigen Browsern unterstützt.

Die Verwendung der Array-Objekte von document dürfte Ihnen noch aus Kapitel 10 vertraut sein. Beim Laden der Webseite geht der Browser die einzelnen Formulare, die auf der Webseite definiert sind, durch und trägt sie in der Reihe ihrer Definition im HTML- Code in das Array forms ein. Danach können wir über einen nullbasierten Index auf die Formulare der Webseite zugreifen:

document.forms[0]      // Zugriff auf das erste Formular einer Webseite
document.forms[1] // Zugriff auf das zweite Formular einer Webseite

und so weiter.

Auf Formulare die einen Namen (name- oder id-Attribut) haben, kann man noch über andere Syntaxformen zugreifen - beispielsweise document.forms["FormularName"] oder document.FormularName oder einfach nur FormularName. Diese Syntaxformen werden allerdings nicht von allen Browsern gleichermaßen unterstützt.

Alle Formulare verfügen über einen Satz von Eigenschaften, die wie üblich den HTML- Attributen des <form>-Tags entsprechen und die man abfragen oder verändern kann: action, encoding, method, name, target.

document.forms[0].target = "frameUnten";

Meist benötigen wir das Formular-Objekt jedoch nur, um auf die Steuerelemente im Formular zuzugreifen. Diese können über das elements-Array des Formular-Objekts angesprochen werden.

document.forms[0].elements[0].value = "Neuer Text";  // Zugriff auf 
// 1. Element in
// 1. Formular
document.forms[0].elements[1].value = "Neuer Text"; // Zugriff auf
// 2. Element in
// 1. Formular
document.forms[1].elements[0].value = "Neuer Text"; // Zugriff auf
// 1. Element in
// 2. Formular

Das folgende Beispiel demonstriert, wie man per JavaScript-Code die Inhalte von Textelementen verändern kann.

Listing 11.2: zugriff.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Steuerelemente</title>
<meta http-equiv="Content-Script-Type" content="text/javascript">
</head>

<body>
<h2>JavaScript-Zugriff auf Steuerelemente</h2>

<form>
<table>
<tr>
<td>
<input type="text" name="text1" value="" />
</td>
</tr>
<tr>
<td>
<input type="text" name="text2" value="" />
</td>
</tr>
</table>
</form>

<script type="text/javascript">

document.forms[0].elements[0].value = "Hallo";
document.forms[0].elements[1].value = "von Ihrem JavaScript";

</script>

</body>
</html>

Abbildung 11.1:  Manipulation von Steuerelementen über Javascript

Wie man über JavaScript-Code auf Steuerelemente zugreift, haben wir nun gesehen. Jetzt müssen Sie nur noch wissen, welche Ereignisse und Eigenschaften für welche Steuerelemente definiert sind.

Ereignisbehandlung für die verschiedenen Steuerelemente

Beginnen wir gleich mit dem ersten Typ von Steuerelement.

Ein- und mehrzeiligeTextfelder

<input type="text" name="T1" value="hier eintippen" size="20" 
maxlength="40" />
<input type="password" name="P1" />
<textarea name="S1" rows="2" cols="20">Inhalt<textarea/>

Ein- und mehrzeilige Textfelder unterstützen folgende Ereignisse:

Über die Eigenschaft value können Sie den Inhalt des Steuerelements auslesen oder ändern. Die folgende Ereignisbehandlung könnte von einem Textelement zur Abfrage des Besuchernamens stammen:

<input type="text" name="name" value="Geben Sie Ihren Namen ein" 
size="20" maxlength="40" onchange="hallo(this)" />
...
function hallo(elem)
{
var str = elem.value;
elem.value = "Hallo " + elem.value;
}

Wenn Sie den Text eines mehrzeiligen Textfeldes (<textarea>) ändern, können Sie Zeilenumbrüche in Form des Sonderzeichens \n eingeben:

elem.value = "Erste Zeile \n Zweite Zeile";

Über Javascript können Sie den Inhalt eines Textfeldes auch dann ändern, wenn das Attribut readonly="readonly" gesetzt ist! Ob aber das Ändern des Textes via JavaScript ein onchange-Ereignis auslöst, hängt vom Browser ab.

Nicht ändern, aber abfragen können Sie den anfänglichen Inhalt des Steuerelements, der im HTML-Attribut value festgelegt wurde. Dieser ist in der Eigenschaft defaultValue gespeichert.

Schalter

<input type="button" name="B1" value="Schaltfläche" />

Für Schalter gibt es nur drei Ereignisse: onfocus, onblur und onclick, von denen onclick natürlich das Interessanteste ist. Wir werden weiter unten noch einige Beispiele für die Verarbeitung von onclick-Ereignissen für Schalter sehen.

Über die Eigenschaft value kann man den Titel des Schalters abfragen oder neu setzen.

<input type="button" value="Klick mich!" name="B1" 
onclick="angeklickt(this)">
...
function angeklickt(elem)
{
elem.value = "Danke!";
}

Für die beiden Schalter »Submit« und »Reset« zum Abschicken beziehungsweise Zurücksetzen des Formulars braucht man üblicherweise kein onclick-Ereignis zu definieren.

<input type="submit" name="B2" value="Abschicken" />
<input type="reset" name="B3" value="Zurücksetzen" />

Drückt der Besucher den Submit-Schalter eines Formulars, wird zuerst das onsubmit- Ereignis des Formulars ausgelöst. Wenn Sie in das Abschicken der Formulareingaben eingreifen wollen, ist dies die richtige Stelle. Setzen Sie eine Ereignisbehandlung für das onsubmit-Ereignis des Formulars auf und lassen Sie diese den Wert true zurückliefern, wenn die Formulareingaben zum Schluss an den im action-Attribut spezifizierten URL verschickt werden sollen, oder liefern Sie false zurück, wenn die Formulareingaben nicht verschickt werden sollen. Wenn Sie keine Ereignisbehandlung für onsubmit vorsehen, werden die Formulareingaben automatisch beim Klick des Submit-Schalters versendet.

Drückt der Besucher den Reset-Schalter eines Formulars, wird zuerst das onreset-Ereignis des Formulars ausgelöst und dann der Inhalt der Steuerelemente im Formular auf ihre Default-Werte zurückgesetzt. Wie im Falle des Submit-Schalters können Sie in die Ereignisbehandlung eingreifen, indem Sie eine Ereignisfunktion für das onreset-Ereignis des Formulars aufsetzen.

Mehr zum Abschicken und Zurücksetzen von Formularen gleich in Abschnitt 11.3.

Kontrollkästchen und Optionsfelder

<input type="checkbox" name="C1" checked="checked" />
<input type="radio" name="R1" value="1" checked="checked" />

Kontrollkästchen und Optionsfelder sind letztlich nichts anderes als besondere Formen von Schaltern, für die die Ereignisse onfocus, onblur und onclick unterstützt werden.

Die interessanteste Eigenschaft für diese Steuerelemente ist nicht value, sondern checked. Über diese Eigenschaft können Sie feststellen, ob der Besucher das Element gesetzt hat, oder das Steuerelement via JavaScript-Code setzen oder löschen.

<input type="checkbox" name="rot" onclick="farbe(this)" />
...
function farbe(elem)
{
if(elem.checked == true)
{
document.bgColor = "red";
}
else
{
document.bgColor = "white";
}
}

Etwas anders sieht die Programmierung mit gruppierten Optionsfeldern aus.

<form>
<table border="0" cellspacing="5">
<tr>
<td><input type="radio" name="hintergrund" value="weiss"
onclick="document.bgColor='white';" />Weiss</td>
<td><input type="radio" name="hintergrund" value="rot"
onclick="document.bgColor='red';" />Rot</td>
<td><input type="radio" name="hintergrund" value="blau"
onclick="document.bgColor='blue';" />Blau</td>
</tr>
</table>
</form>

Wenn Sie mehreren Optionsfeldern den gleichen Namen zuteilen, bilden diese eine Gruppe.

Gruppierte Optionsfelder werden immer dann eingesetzt, wenn der Besucher zwischen verschiedenen Optionen wählen soll, die sich gegenseitig ausschließen.

Das Besondere an den gruppierten Optionsfeldern ist, dass von den Optionsfeldern einer Gruppe immer nur eines ausgewählt sein kann. Außerdem kann man Optionsfelder nicht deselektieren, das heißt, wenn der Besucher auf ein Optionsfeld klickt, wird dieses auf jeden Fall gesetzt und alle andere Optionsfelder der Gruppe werden gelöscht. Dies vereinfacht die Behandlung von onclick-Ereignissen, da man nicht erst feststellen muss, ob das Optionsfeld durch den Mausklick gesetzt oder gelöscht wurde:

<input type="radio" name="hintergrund" value="rot" 
onclick="document.bgColor='red';" />

Etwas komplizierter wird es, wenn man - statt für jedes Optionsfeld eine eigene Ereignisbehandlung aufzusetzen (siehe oben) - eine JavaScript-Funktion zur Behandlung aller Optionsfelder einer Gruppe oder gar zur Behandlung der gesamten Formulareingaben schreibt. Dann stellt sich nämlich meist das Problem, wie man die einzelnen Optionsfelder einer Gruppe identifiziert. Über die Namen der Optionsfelder ist dies nicht möglich, da ja alle Optionsfelder einer Gruppe den gleichen Namen tragen. Also weicht man auf den value-Wert aus und teilt allen Optionsfeldern in einer Gruppe eigene value-Werte zu, über die man die einzelnen Optionsfelder im JavaScript-Code identifizieren kann. Dies könnte dann beispielsweise wie folgt aussehen:

Listing 11.3: Auszug aus optionen.html

<form>
<table border="0" cellspacing="5">
<tr>
<td><input type="radio" name="hintergrund" value="weiss"
onclick="farbe(this)" />Weiss</td>
<td><input type="radio" name="hintergrund" value="rot"
onclick="farbe(this)" />Rot</td>
<td><input type="radio" name="hintergrund" value="blau"
onclick="farbe(this)" />Blau</td>
</tr>
</table>
</form>

Hier werden drei Optionsfelder angeboten, über die man eine Farbe für den Hintergrund der Webseite auswählen kann. Alle drei Optionsfelder haben den gleichen Namen und verwenden die gleiche Ereignisfunktion für das onclick-Ereignis. Eindeutig identifiziert werden sie über ihre value-Werte.

In der Ereignisbehandlungsfunktion kann man den value-Werte des aktuell angeklickten Optionsfeldes abfragen und danach entscheiden, wie der Hintergrund der Webseite einzufärben ist.

Listing 11.4: Auszug aus optionen.html

<script type="text/javascript">

function farbe(elem)
{
switch(elem.value)
{
case "weiss": document.bgColor = "white"; break;
case "rot": document.bgColor = "red"; break;
case "blau": document.bgColor = "blue"; break;
}
}
</script>

Man hätte die Hintergrundfarbe natürlich auch gleich beim Aufruf der Funktion übergeben können (siehe Übung 1) doch ging es uns ja weniger um eine effiziente Implementierung als vielmehr um die Identifizierung der einzelnen Optionsfelder aus einer Gruppe. Ein weiteres Beispiel hierzu finden Sie übrigens in Kapitel 13, Übung 1.

Ereignisbehandlung für Auswahllisten

<select name="obst" size="5" multiple="multiple">
<option>Bananen</option>
<option selected="selected">Äpfel</option>
<option selected="selected">Orangen</option>
<option>Kirschen</option>
<option>Kiwis</option>
<option>Stachelbeeren</option>
<option>Pfirsiche</option>
</select>

Bei der Programmierung mit Auswahllisten geht es meist darum,

Dazu muss man wissen, wie man auf die einzelnen Optionen einer Auswahlliste zugreifen kann. Vermutlich ahnen Sie es schon. Richtig, für jedes Auswahllisten-Objekt gibt es wieder ein Array, das in diesem Falle options heißt, über das man auf die einzelnen Optionen zugreifen kann.

Wie geht man also vor, wenn man ermitteln möchte, welche Optionen der Besucher in einer Auswahlliste ausgewählt hat?

Ausgewählte Optionen herausfiltern

Erlaubt die Auswahlliste nur die Auswahl eines einzigen Elements kann man den Index dieses Elements direkt der Eigenschaft selectedIndex des Auswahllistenobjekts entnehmen:

var ausgewaehlt = document.forms[n].elements[m].selectedIndex;1

Erlaubt die Auswahlliste allerdings wie in obigem Beispiel die Auswahl mehrerer Elemente, liefert selectedIndex nur den Index des ersten ausgewählten Elements. Meist programmiert man für Auswahllisten mit Mehrfachauswahl daher eine Schleife, in der man die einzelnen Optionen durchgeht und nachschaut, welche der Optionen ausgewählt sind (options[]-Eigenschaft selected).

Listing 11.5: auswahl.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Auswahllisten</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">

function auswahl()
{
var auswahl = document.forms[0].elements[0];

for(i = 0; i < auswahl.options.length; i++)
if(auswahl.options[i].selected == true)
alert(auswahl.options[i].text);
}

</script>
</head>

<body>
<h2>Auswahllisten</h2>
<table border="0" width="100%" cellspacing="5">
<form>
<tr>
<td>
<select name="obst" size="5" multiple="multiple">
<option>Bananen</option>
<option selected="selected">Äpfel</option>
<option selected="selected">Orangen</option>
<option>Kirschen</option>
<option>Kiwis</option>
<option>Stachelbeeren</option>
<option>Pfirsiche</option>
</select>
</td>
</tr>
<tr>
<td>
<input type="button" value="Anzeigen" onclick="auswahl()"/>
</td>
</tr>
</form>
</table>

</body>
</html>

Dieses Beispiel ist so konstruiert, dass der Besucher erst in Ruhe seine Auswahl treffen kann und danach den Anzeigen-Schalter anklickt. Als Antwort auf das onclick-Ereignis des Schalters werden dann die Titel der ausgewählten Optionen (text-Eigenschaft) nacheinander mittels alert() ausgegeben.

Statt die Auswertung der ausgewählten Elemente mit dem Klicken eines eigenen Schalters zu verbinden, hätte man auch das onblur-Ereignis der Auswahlliste abfangen können.

Wie kann man die im HTML-Code vorgegebene Auswahl wiederherstellen?

Ob für eine Option das HTML-Attribut selected gesetzt ist oder nicht, kann man am Wert der options[]-Eigenschaft defaultSelected ablesen. Mit diesem Wissen ist es nicht mehr schwer, die Ereignisfunktion angeklickt aus Listing 11.5 so umzuschreiben, dass beim Klick auf den Schalter die Auswahl des Benutzers verworfen und die HTML-Auswahl wieder hergestellt wird.

function angeklickt()
{
var auswahl = document.forms[0].elements[0];

for(i = 0; i < auswahl.options.length; i++)
if(auswahl.options[i].defaultSelected == true)
auswahl.options[i].selected = true;
else
auswahl.options[i].selected = false;
}

Wie kann man Optionen löschen?

Um eine Option zu löschen, braucht man nur das entsprechende Array-Element auf null zu setzen.

function loeschen()
{
var auswahl = document.forms[0].elements[0];

// markierte Optionen löschen
for(i = 0; i < auswahl.options.length; i++)
if(auswahl.options[i].selected == true)
auswahl.options[i] = null;
}

Wie kann man neue Optionen einfügen?

Um eine Option neu einzufügen, erzeugt man ein neues Objekt der Klasse Option und weist dieses Objekt einem Element im options-Array zu. Je nachdem wie man den Index für options[] wählt, kann man ein neues Element hinten anhängen oder ein bestehendes Element ersetzen.

function einfuegen()
{
var auswahl = document.forms[0].elements[0];

// Titel für neue Option abfragen
var titel = prompt("Wie soll die neue Option heißen?");

// Option ans Ende der Liste anhängen
var neu = new Option(titel);
auswahl.options[auswahl.length] = neu;
}

11.2 Benutzeroberflächen

Auch wenn wir unsere Steuerelemente aus Rücksicht auf den Navigator-Browser immer in <form>-Tags kleiden, muss man diese »Formulare« nicht unbedingt zur Übertragung von Benutzereingaben an den Webserver nutzen. Man kann sie auch zum Aufbau grafischer Benutzeroberflächen verwenden. Das Tolle dabei ist, dass die gesamte Funktionalität hinter den Oberflächenelementen mit JavaScript realisiert werden kann.

Als praktisches Beispiel für den Einsatz von Steuerelementen zum Aufbau grafischer Oberflächenelemente stellen wir Ihnen hier einen kleinen einarmigen Banditen vor.

Abbildung 11.2:  JavaScript-unterstützte grafische Benutzeroberfläche

Listing 11.6: bandit.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Einarmiger Bandit</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">

var getroffen = true;
var bilder = new Array(2);
bilder[0] = new Image();
bilder[0].src = "glueck.gif";
bilder[1] = new Image();
bilder[1].src = "pech.gif";

function treffer()
{
with (document.forms[0])
{
if (elements[0].value == elements[1].value &&
elements[1].value == elements[2].value)
{
getroffen = true;
document.images[0].src = bilder[0].src;
}
}
}

function zufall()
{
if(getroffen == true)
{
getroffen = false;
document.images[0].src = bilder[1].src;
}
for(var count = 0; count <= 2; count++)
{
var zufallszahl = Math.random() * 4;
// Umwandlung der Gleitkommazahl in eine Ganzzahl
// Wegen dem Navigator müssen wir Werte < 1 gesondert
// behandeln
if (zufallszahl > 1)
zufallszahl = parseInt(zufallszahl);
else
zufallszahl = 0;
var zufallszahl = parseInt(Math.random() * 4);
document.forms[0].elements[count].value = zufallszahl;
}

treffer();
}

</script>
</head>

<body>

<h1>Der einarmige Bandit</h1>

<p>Sie haben gewonnen, wenn in allen drei Feldern
die gleiche Zahl angezeigt wird.</p>

<form>
<table width="600" height="350" border="0" cellspacing="5"
cellpadding="5"
style="background-image: url('hintergrund.gif');
margin-left:5em">
<tr>
<td width="200" align="center"><input type="text" name="T1"
¬size="15" readonly="readonly" /></td>
<td width="200" align="center"><img src="glueck.gif" alt="smiley"
¬width="150" height="120" /></td>
<td width="200" align="center"><input type="text" name="T3"
¬size="15" readonly="readonly" /></td>
</tr>
<tr>
<td>&nbsp;</td>
<td width="200" align="center"><input type="text" name="T2"
¬size="15" readonly="readonly" /></td>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td width="200" height="150" align="center" valign="bottom"><input
¬type="button" value="Abschicken" name="B1"
¬onclick="zufall()"></td>
<td>&nbsp;</td>
</tr>
</table>
</form>

</body>
</html>

Jedes Mal, wenn der Spieler auf den Abschicken-Schalter klickt, wird die Funktion zufall() aufgerufen. Diese prüft, ob das letzte Spiel gewonnen worden ist. Wenn ja (getroffen gleich true), setzt sie die Boolesche Variable getroffen auf false zurück und lädt das Pech-Smiley. Dann zieht sie drei neue Zufallszahlen und gibt diese in die Textfelder der grafischen Oberfläche aus. Zum Schluss ruft sie die Funktion treffer(), die feststellen soll, ob das aktuelle Spiel gewonnen wurde.

Die Funktion treffer() prüft, ob alle drei Textfelder den gleichen Wert enthalten, wenn ja wird die Boolesche Variable getroffen auf false gesetzt und das Glücks-Smiley angezeigt.

11.3 Formulareingaben

Ein typisches Einsatzgebiet für JavaScript in Verbindung mit »echten« Formularen ist die Vollständigkeitsprüfung und gegebenenfalls die Verifizierung der Formulareingaben.

Vollständigkeitsprüfung von Formularen

Formulare, die dazu dienen, Daten vom Browser an den Server der Webseite zurückzuschicken, weisen gegenüber den »Schein«-Formularen zur Gestaltung von grafischen Oberflächen drei Besonderheiten auf:

Drückt der Besucher den Abschicken-Schalter eines Formulars, wird zuerst das onsubmit- Ereignis des Formulars ausgelöst. Ist keine Ereignisbehandlungsfunktion für dieses Ereignis eingerichtet, fährt der Browser damit fort, dass er die Daten an den im action- Attribut spezifizierten URL schickt.

Das Problem dabei ist, dass viele Websurfer die Formulare aus Faulheit, Desinteresse oder zur Wahrung Ihrer Privatsphäre zuerst einmal nur sehr unvollständig ausfüllen. Nun kann man dies natürlich in dem Programm, das die Formulardaten auf Seiten des Webservers entgegen nimmt, feststellen und eine entsprechende Aufforderung, das Formular doch bitte vollständig auszufüllen, zurückschicken. Wegen der Übertragung der Daten über das Netz ist dieses Verfahren jedoch sehr zeitaufwendig und unökonomisch. Effizienter ist es meist, die Vollständigkeit eines Formulars mit Hilfe von JavaScript bereits auf der Clientseite zu überprüfen.

Dazu müssen Sie eine Ereignisbehandlungsfunktion für das onsubmit-Ereignis des Formulars aufsetzen. In dieser prüfen Sie, ob alle relevanten Felder des Formulars ausgefüllt wurden. Wenn ja, liefert die Funktion true zurück. Wurde dagegen auch nur ein wichtiges Feld ausgelassen, wird die Funktion mit der Rückgabe von false beendet. Den Rückgabewert dieser Funktion erklärt man dann zum Rückgabewert von onsubmit:

onsubmit="return ereignisFunktion()"

Dies ist wichtig, da nur so der Browser erkennen kann, ob die Formulardaten nach Ausführung der Funktion gesendet (onsubmit = true) oder verworfen werden sollen (onsubmit = false).

Schauen Sie sich einmal Abbildung 11.3 an.

Abbildung 11.3:  Umfrage-Formular

Der Code, der dieses Formular erzeugt, sieht wie folgt aus.

Listing 11.7: Auszug aus formular1.html

<body> 
<h1>Sind Sie für den internetfreien Sonntag?</h1>

<form method="post" action="http://server.com/cgi-bin/progamm.pl"
onsubmit="return vollstaendig()">
<table border="0" width="500" cellspacing="5" cellpadding="5">
<tr>
<td width="150" align="right">Ihr Name<sup>*</sup></td>
<td width="350" colspan="4"><input type="text" name="T1"
size="30" /></td>
</tr>
<tr>
<td width="150" align="right">Ihr Vorname<sup>*</sup></td>
<td width="350" colspan="4"><input type="text" name="T2"
size="30" /></td>
</tr>
<tr>
<td width="150" align="right"><sup>*</sup></td>
<td width="30"><input type="radio" value="pro" name="R1" /></td>
<td width="30">Pro</td>
<td width="30"><input type="radio" value="kontra"
name="R1" /></td>
<td width="260">Kontra</td>
</tr>
<tr>
<td width="150" align="right" valign="top">Ihre Meinung</td>
<td width="350" colspan="4"><textarea name="T3" rows="5"
cols="40"></textarea></td>
</tr>
<tr>
<td width="150">&nbsp;</td>
<td width="350" colspan="4"><input type="submit" name="senden"
value="Abschicken" /></td>
</tr>
</table>
</form>

<p style="font-size: 0.8em">Angaben mit Sternchen<sup>*</sup> sind obligatorisch.</p>

</body>

Interessant ist an diesem Code für uns im Moment nur der Abschicken-Schalter (type="submit")2 am Ende der Tabelle und die Deklaration des <form>-Tags mit den Angaben des Ziel-URLs und der onsubmit-Ereignisbehandlung.

Tritt das onsubmit-Ereignis ein, wird die Funktion vollstaendig() aufgerufen, die prüfen soll, ob alle wichtigen Felder des Formulars ausgefüllt wurden. Wie dies geht, zeigt das folgende Listing.

Listing 11.8: Auszug aus formular1.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Vollständigkeitsprüfung</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />


<script type="text/javascript">

function vollstaendig()
{
var korrekt = true;

if (document.forms[0].elements[0].value == "")
korrekt = false;

if (document.forms[0].elements[1].value == "")
korrekt = false;

if ( !(document.forms[0].elements[2].checked ||
document.forms[0].elements[3].checked))
korrekt = false;

if (korrekt)
return true;
else
{
alert("Bitte füllen Sie das Formular vollständig aus!");
return false;
}
}


</script>
</head>
...

Die Funktion geht die (wichtigen) Formularfelder einfach der Reihe nach durch. Bei den Textfeldern prüft die Funktion, ob die Felder einen Inhalt (value) haben, bei den Optionsfeldern prüft die Funktion, ob eines der Optionsfelder der Gruppe gesetzt wurde. Das letzte Formularfeld, das mehrzeilige Eingabefeld, wird nicht überprüft, da es keine essentiellen Daten enthält.

Trifft die Funktion dabei auf ein Feld, das nicht bearbeitet wurde, setzt sie die mit true initialisierte Boolesche Variable korrekt auf false.

Zum Schluss liest die Funktion am Wert von korrekt ab, ob alle wichtigen Formularfelder bearbeitet wurden. Wenn ja (korrekt hat immer noch den Anfangswert true), liefert die Funktion als Ergebnis true zurück. Ansonsten gibt sie eine Fehlermeldung aus und liefert false zurück.

Testen Sie doch einmal Formular und Javascript-Funktion in Ihrem Browser und beobachten Sie, wie der Browser bei vollständig ausgefülltem Formular versucht, den Webserver aus dem action-Attribut zu finden, während er bei nicht korrekt ausgefülltem Formular nichts tut.

Verifizierung von Formulareingaben

Für einfache Anwendungen dürfte es vollkommen genügen, wenn Sie mit JavaScript die Vollständigkeit der Eingaben prüfen. Gelegentlich wird man aber noch etwas weitergehen, und - soweit dies möglich ist - die Korrektheit der Eingaben prüfen.

Bleiben wir doch der Einfachheit halber bei dem Formular aus Abbildung 11.3. Nehmen wir an, Sie sind es leid, dass Besucher Ihrer Website statt vernünftiger Namen und Kommentare Buchstabensalat der Form sdf*Ä' oder ssdg in die Formularfelder eingeben. Nehmen wir weiter an, Sie wissen um die Gefährlichkeit von Server Side Includes3 und wollen verhindern, dass Server Side Includes als Formulareingaben getarnt auf Ihrem Server landen. Dann müssen Sie die Formulareingaben nicht nur auf Vollständigkeit prüfen, sondern auch verifizieren, dass die eingegebenen Daten korrekt sind.

Nun, die Daten tatsächlich auf Korrektheit zu prüfen, ist in Realität natürlich kaum möglich. Wenn ein Besucher Ihrer Website statt seines eigenen Namens, den seines Nachbarn eingibt, können Sie nichts dagegen machen. Man kann sich aber bestimmte Restriktionen überlegen, die korrekte Daten erfüllen müssen, und diese dann mit Hilfe von JavaScript-Code überprüfen. So testet das nachfolgende Skript, ob die Eingaben in den Textfeldern außer Buchstaben und dem Leerzeichen noch andere Zeichen enthalten. Falls ja, wird die Eingabe verworfen und der Besucher wird aufgefordert, das Formular neu auszufüllen. Die Beschränkung der Eingaben auf Buchstaben und Leerzeichen ist natürlich etwas grob (Phantasienamen wie ssdg werden immer noch akzeptiert), während Kommentare mit Kommas oder Bindestrichen verworfen werden, aber Namen wie sdf*Ä' werden als falsch entlarvt und Server Side Includes (die in die Zeichenfolgen <!-- und --> gehüllt sind) werden ebenfalls ausgesiebt.4

Listing 11.9: Auszug aus formular2.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>

<title>Vollständigkeitsprüfung</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">

function nurBuchstaben(str)
{
var code;

str = str.toLowerCase();
for(var i = 0; i < str.length; i++)
{
code = str.charCodeAt(i);

if( (code < 97 || code > 122) && !(code == 32) )
return false;
}

return true;
}


function vollstaendig()
{
var korrekt = true;

if (document.forms[0].elements[0].value == "")
korrekt = false;

if (document.forms[0].elements[1].value == "")
korrekt = false;

if ( !(document.forms[0].elements[2].checked ||
document.forms[0].elements[3].checked))
korrekt = false;

// Verifizierung der Daten
if (korrekt)
{
korrekt = nurBuchstaben(document.forms[0].elements[0].value);
}
if (korrekt)
{
korrekt = nurBuchstaben(document.forms[0].elements[1].value);
}
if (korrekt)
{
korrekt = nurBuchstaben(document.forms[0].elements[4].value);
}

// Wert zurückliefern
if (korrekt)
return true;
else
{
alert("Bitte füllen Sie das Formular vollständig und richtig aus!");
return false;
}
}

</script>
</head>
... // Formular wie in formular1.html

Beginnen wir mit der Funktion vollstaendig(). In deren mittlerem Abschnitt wurden drei if-Anweisungen eingefügt, die prüfen sollen, welche Eingaben in den drei Textfeldern andere Zeichen außer Buchstaben und Leerzeichen enthalten. Die if-Anweisungen rufen dazu einfach die Funktion nurBuchstaben() auf, übergeben ihr den Inhalt des betreffenden Formularelements und werten das Ergebnis der Funktion aus.

Die Funktion nurBuchstaben() wandelt den String zuerst in Kleinbuchstaben um. Dann geht sie den String in einer Schleife Zeichen für Zeichen durch und lässt sich für jedes Zeichen den UNICODE-Code zurückliefern (dessen ersten Zeichen dem ASCII-Code entsprechen). Ein Blick in eine ASCII-Tabelle lehrt uns, dass die Kleinbuchstaben des romanischen Alphabets die Codezahlen von 97 bis 122 haben, das Leerzeichen hat den Code 32. Wir testen daher in der Funktion, ob die einzelnen Zeichen Codezahlen haben, die außerhalb des Bereichs von 97 bis 122 liegen und ungleich 32 sind. Wenn ja, haben wir ein ungültiges Zeichen entdeckt und liefern den Rückgabewert false zurück.

Abbildung 11.4:  Die Verifizierung lässt keine Server Side Includes in den Textfeldern zu

11.4 Zusammenfassung

Heute haben Sie gelernt, wie man mit JavaScript auf Formulare und Steuerelemente in Formularen (Formularfeldern) zugreift. Neben den drei Arrays

haben wir Ihnen die wichtigsten Ereignisse und Eigenschaften der einzelnen Steuerelemente vorgestellt.

Im zweiten Teil des Kapitels haben wir uns einige praktische Beispiele für den Aufbau von grafischen Benutzerschnittstellen mit Steuerelementen und die clientseitige Verarbeitung von Formulareingaben angeschaut.

11.5 Fragen und Antworten

Frage:
Wie kann ich feststellen, wie viele Formulare in einer Webseite enthalten sind?

Antwort:
Die Gesamtzahl der Formulare auf einer Seite ist wie üblich in der length- Eigenschaft des Arrays abgespeichert (document.forms.length). Gleiches gilt für die Anzahl der Felder in einem Formular (oder die Optionen in einer Auswahlliste).

11.6 Workshop

Der Workshop enthält Quizfragen, die Ihnen helfen sollen, Ihr Wissen zu festigen, und Übungen, die Sie anregen sollen, das eben Gelernte umzusetzen und eigene Erfahrungen zu sammeln. Versuchen Sie, das Quiz und die Übungen zu beantworten und zu verstehen, bevor Sie zur Lektion des nächsten Tages übergehen.

Quiz

  1. Wie greift man auf das zweite Formular einer Webseite zu?
  2. Welche Bedeutung hat die Eigenschaft value für
  1. Wie kann man Formulareingaben an einen Webserver zurückschicken?
  2. Wie kann man Formulareingaben mit JavaScript abfangen und bearbeiten, bevor der Browser sie an den Webserver schickt?

Übungen

  1. In Abschnitt 11.1.2 hatten wir bei der Besprechung der Optionsfelder ein Beispiel dafür gesehen, wie man die einzelnen Optionsfelder einer Gruppe über ihre value- Werte identifizieren kann. Wir haben aber auch darauf hingewiesen, dass man in diesem einfachen Beispiel auf die Identifizierung der Optionsfelder im Skriptcode verzichten könnte, wenn man die Hintergrundfarben direkt als Argumente an die Ereignisbehandlungsfunktion farbe() übergibt. Ihre Aufgabe soll nun sein, dies zu realisieren.
  2. In Kapitel 9.1, Listing 9.2, haben wir ein JavaScript-Programm zur Umrechnung von DM in Euro aufgesetzt. Statten Sie dieses Programm mit einer grafischen Benutzerschnittstelle aus (siehe Abbildung 11.5).

    Abbildung 11.5:  Eingabemaske des Euro-Umrechners



vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbackKapitelanfangnächstes Kapitel


1234

© Markt+Technik Verlag, ein Imprint der Pearson Education Deutschland GmbH