HTML: Formulare
Formulare finden überall dort Verwendung, wo wir Benutzeingaben weiterverarbeiten wollen, sei es z. B. für ein Kontaktformular, ein Gästebuch oder einen Online-Shop. Über Formulareingaben kann man aber auch beispielsweise die Darstellung einer Webseite beeinflussen lassen. Ein Formular besteht aus einer Anzahl von Formular-Objekten, mit deren Hilfe den im Formular verwendeten Variablen Werte zugewiesen werden können. Diese Variablen können zusammen mit ihren Werten auf zwei grundsätzlich verschiedene Weisen beim Abschicken des Formulars an das Zieldokument übertragen werden. Diese zwei Methoden lauten post und get. Während bei der get-Methode die Daten über die Adresszeile des Browsers geschickt werden, bleiben sie bei der post-Methode unsichtbar. In manchen Fällen ist es von Vorteil, mit der get-Methode eine bestimmte URL zu generieren, die man unter Umständen auch als Lesezeichen speichern können soll. Diese Methode eignet sich vor allem für Situationen, wo nur eine kleine Anzahl von Werten übertragen wird. Für umfangreichere Abfragen, z. B. bei ganzen Textpassagen in der Eingabe, bietet sich die post-Methode an. Da die Auswertung von Formularen in der Regel an programmatische Prozesse gekoppelt ist, die mit reinem HTML nicht möglich sind, kommen sie meist eher z. B. in einer PHP-Umgebung zur Anwendung. Daher wird die Auswertung eines Formulars auch erst im Abschnitt über PHP behandelt.
Wird ein Formular für einen Suchvorgang verwendet, so kann dies durch einen <search>-Container explizit semantisch kenntlich gemacht werden.
Ein Minimalformular kann nun z. B. so aussehen:
<form accept-charset='utf-8' action='anzeigen.php' method='post'>
Bitte gib deinen Vornamen ein:
<input type='text' name='vorname' size='20' maxlength='30' value=''><br>
<input type='submit' name='form1submit' value='abschicken'>
<input type='reset' value='Wert zurücksetzen'>
</form>
<search>
<form action='result.php' method='get'>
<input type='search' name='suchbegriff' placeholder='Suchbegriff eingeben...'>
</form>
</search>
Das Formular wird allgemein durch das <form>-Tag markiert. Das Attribut accept-charset='utf-8' weist das Formular explizit an, bei allen Eingaben die Zeichenkodierung UTF-8 zu akzeptieren. Das Attribut action gibt an, wohin die Daten des Formulars nach dem Absenden geschickt werden sollen, in diesem Fall ist es die Datei anzeigen.php, wo die Daten dann weiterverarbeitet werden können. Das Attribut method enthält die oben erwähnte Methode der Datenübermittlung, in diesem Fall post.
Einzeilige Eingabefelder
Innerhalb des <form>-Tags stehen nun diverse Formular-Objekte, die im Folgenden beschrieben werden. Im obigen Beispiel ist das zunächst ein einfaches einzeiliges Feld für eine Texteingabe: <input type='text'>, das durch das Attribut size mit einer Länge von 20 Zeichen dargestellt wird. Diese Angabe wird von den Browsern sehr unterschiedlich interpretiert, daher sollte man die Darstellung immer in unterschiedlichen Browsern überprüfen und am besten gleich per CSS steuern. Da wir verhindern möchten, dass jemand mehr als 30 Zeichen in dieses Feld eingeben kann, beschränken wir die Eingabe mit dem Attribut maxlength. Soll eine Eingabe von beliebiger Länge möglich sein, lässt man dieses Attribut einfach weg. Im Attribut value könnten wir einen Text angeben, mit dem das Feld vorbelegt ist, was unter Umständen erwünscht ist, hier aber eher stört. Daher ist kein Wert angegeben, man kann auch das gesamte Attribut in einem solchen Fall weglassen. Die Variable die mit diesem Formular-Objekt einen Wert zugewiesen bekommt, lautet hier vorname und ist der Wert des Attributs name.
Das Attribut type='text' ist die Vorgabe für <input>-Elemente und kann daher auch weggelassen werden.
In manchen Fällen möchte man zwar ein Eingabefeld in ein Formular setzen, ein vorgegebener Wert soll aber unveränderbar sein. Dazu setzt man das Feld auf readonly (= nur lesen):
Preis: <input type='text' name='preis' value='123,50 €' readonly>
Schließlich kann man solche Eingabefelder auch noch mit dem Attribut disabled zusätzlich ausgrauen, um deutlich zu machen, dass dieses Feld (obwohl existent) nicht für eine Eingabe vorgesehen ist. In diesem Fall wird der Wert des Feldes beim Absenden auch nicht übertragen:
Preis: <input type='text' name='preis' value='123,50 €' readonly disabled>
Datenliste
Das Element <datalist> kann einem Eingabefeld folgen und enthält eine Datenliste, aus der automatisch alle Einträge angezeigt werden, die bereits in das Eingabefeld eingegebenen Zeichen entsprechen. Bei einigen Browsern öffnet ein Doppelklick auf das Eingabefeld die gesamte Liste, so dass ein Begriff direkt ausgewählt werden kann.
<form accept-charset='utf-8' action='anzeigen.php' method='post'>
Obst:
<input name='fruit' list='fruitlist'>
<datalist id='fruitlist'>
<option value='Apfel'>
<option value='Birne'>
<option value='Melone'>
<option value='Orange'>
<option value='Kirsche'>
<option value='Kiwi'>
<option value='Pflaume'>
<option value='Banane'>
</datalist>
</form>
Buttons zum Abschicken und Zurücksetzen
Als nächstes haben wir im Beispiel oben zwei Buttons (Schaltflächen), die durch <input type='submit'> und <input type='reset'> definiert werden. Der Submit-Button ist eigentlich immer notwendig, da wir mit ihm unsere Formularangaben abschicken. Nur wenn das Formular ein einzeiliges Eingabefeld enthält, können die Daten auch durch Druck der Eingabe-Taste abgeschickt werden, wenn sich der Cursor in dem Eingabefeld befindet.
Der Reset-Button setzt alle Formular-Objekte auf den Wert zurück, den das Formular hatte, als es aufgerufen wurde. Das heißt nicht grundsätzlich, dass alle Werte gelöscht werden. Wenn wir das Feld vorname z. B. mit einem Wert vorbelegt hatten, so wird genau dieser Wert durch den Reset-Button wieder hergestellt. Das Attribut name ist ein Variablenname, durch den wir den Button in unserem Zieldokument auch abfragen können, wenn wir das wollen, was beim Submit-Button manchmal vorkommen kann, beim Reset-Button zwar möglich aber kaum jemals relevant ist. Das Attribut value gibt den Text an, der auf dem Button in der Browserdarstellung angezeigt wird.
Es gibt noch die Möglichkeit, einen Button grafisch aufzupeppen, indem man ihm ein Bild zugrunde legt:
<button name='form1submit' type='button'>
<img src='http://www.decocode.de/img/happy.png' style='width:60px;height:60px;' alt='einfach nur ein Button'>
<br><b>Hallo Welt!</b>
</button>
Hier wird innerhalb eines <button>-Tags ein beliebiger Inhalt angegeben, in diesem Fall ein Bild und ein Text. All das wird nun in einen Button umgewandelt. Das Attribut type kann ebenso wie bei einem Reset-Button oder einem Submit-Button den Wert 'reset' bzw. 'submit' haben (in diesem Fall ist er ohne Funktion, daher type='button').
Man kann einen Button auch zu einem Link umfunktionieren, indem man ihn in ein leeres Formular setzt und als Formularziel die Zieldatei angibt, zu der man verweisen möchte (das Attribut method ist hier nicht notwendig):
<form action='http://www.google.de/'>
<input type='submit' value='Gehe zu Google'>
</form>
<form action='http://www.decocode.de/files/test.zip'>
<input type='submit' value='Download test.zip'>
</form>
Bildkoordinate auswählen
Unter Umständen möchte man in einem Bild eine bestimmte Region auswählen, beispielsweise auf einer Landkarte. Mit dem Element <input type='image'> ist dies möglich. Dieses Element ist zugleich ein Submit-Button. Wird das Bild angeklickt, wird das Formular abgeschickt und zusätzlich zu allen übrigen Formulareinträgen auch die x- und y-Koordinate übermittelt, an der das Bild angeklickt wurde.
<input type='image' name='smiley' src='http://www.decocode.de/img/happy.png' style='width:60px;height:60px;' alt='Symbol: Abschicken' title='Abschicken'>
Eingabefeld für Passwörter
<input type='password' name='user_pw' size='16' maxlength='16'>
Dieses Feld ist dem normalen einzeiligen Eingabefeld ähnlich, nur dass in diesem Fall die eingegebenen Zeichen durch Sterne oder Kreise ersetzt werden, damit niemand heimlich über die Schulter gucken kann.
URL, E-Mail-Adresse, Telefonnummer und Suche
Weitere Typen für einzeilige Eingabefelder sind:
<input type='url'> für URLs.
<input type='email'> für E-Mail-Adressen.
<input type='tel'> für Telefonnummern.
<input type='search'> für Suchbegriffe.
<input type='url' name='myurl'>
<input type='tel' name='mytel'>
<input type='email' name='myemail'>
<input type='search' name='mysearch'>
Zeit- und Datumsangabe
Für Zeit- und Datumsangaben stehen zwei eigenständige Formularobjekte zur Verfügung. Beim Objekt mit dem Typ time für Zeitangaben kann im Attribut value ein Wert in der Form Stunde:Minute:Sekunde vorgegeben werden. Beim Objekt mit dem Typ date für Datumsangaben kann im Attribut value ein Wert in der Form Jahr:Monat:Tag vorgegeben werden.
<input type='time' value='16:39:57'>
<input type='date' value='2017-11-16'>
Mehrzeilige Eingabefelder
Für umfangreicheren Text benötigt man ein Formularfeld mit mehreren Zeilen, was durch das <textarea>-Tag erreicht wird.
<textarea name='textbody' cols='30' rows='15'>Hallo!</textarea>
In diesem Fall haben wir ein mehrzeiliges Eingabefeld mit 30 Spalten (cols = columns), d. h. Zeichen pro Zeile, und 15 Zeilen (rows). Außerdem ist es mit dem Wert Hallo! vorbelegt. Wenn wir keine Vorbelegung wünschen, können Anfangs- und End-Tag auch unmittelbar aufeinander folgen. Die Angabe der Größe für die Anzeige eines Textfeldes beschränkt dieses nicht auf die Eingabe von Text, der über dessen Anzeigegröße hinausgeht. Ebenso wie bei einem einzeiligen Eingabefeld kann man auch das <textarea>-Element auf readonly setzen, um eine Eingabe zu verhindern.
<textarea name='textbody' cols='30' rows='15' readonly>Hallo!</textarea>
Auch hier lässt sich das Eingabefeld ausgrauen:
<textarea name='textbody' cols='30' rows='15' disabled>Hallo!</textarea>
Checkboxen
Checkboxen <input type='checkbox'> sind Kästchen zum Wählen einer Ja/Nein-Alternative.
<form accept-charset='utf-8' action='anzeigen.php' method='post'>
Deine Hobbys:<br>
<input type='checkbox' name='hobby1' value='Lesen'> Lesen<br>
<input type='checkbox' name='hobby2' value='Schwimmen' checked> Schwimmen<br>
<input type='checkbox' name='hobby3' value='Radfahren'> Radfahren<br>
<input type='checkbox' name='hobby4' value='Singen' checked disabled> Singen<br>
<input type='reset' value='Wert zurücksetzen'>
</form>
Das Feld für ›Schwimmen‹ wurde mit dem Attribut checked ausgewählt. Das Feld für ›Singen‹ wurde ausgewählt und mit disabled deaktiviert.
Radiobuttons
Bei Radiobuttons <input type='radio'> kann man innerhalb einer Gruppe von Radiobuttons immer nur genau ein Element auswählen. Zusammengehörige Radiobuttons werden durch das name-Attribut gekennzichnet.
<form accept-charset='utf-8' action='anzeigen.php' method='post'>
<div>Deine Geschlecht:<br>
<input type='radio' name='geschlecht' value='m'> männlich<br>
<input type='radio' name='geschlecht' value='w'> weiblich<br>
<input type='radio' name='geschlecht' value='a'> anderes<br>
</div>
<div>Dein Alter:<br>
<input type='radio' name='alter' value='teen'> 0 - 18<br>
<input type='radio' name='alter' value='adult' checked> 19 - 39<br>
<input type='radio' name='alter' value='old'> 40 - 100<br>
<input type='radio' name='alter' value='antique'> 101+<br>
<input type='radio' name='alter' value='biblical' disabled> 1000+<br><br>
<input type='reset' value='Wert zurücksetzen'>
</div>
</form>
Im Beispiel wurde das Alter adult vorausgewählt. Das geht innerhalb einer Gruppe natürlich immer nur bei genau einem Element.
Zahlen, Wertebereiche und Farben
Außerdem existieren folgende Typen für das <input>-Element. Die mögliche ›Konfiguration‹ der Elemente durch ihre Attribute ist noch flexibler als hier dargestellt, siehe dazu die Spezifikation.
<input type='number'>
Ein Eingabefeld für eine Zahl, bei dem der untere Grenzwert min, der oberere Grenzwert max und die Schrittweite step angegeben werden kann.
<input type='range'>
Ein Schieberegler, bei dem der untere Grenzwert min und der oberere Grenzwert max angegeben werden kann.
<input type='color'>
Ein Farbwähler.
<input type='number' name='mynumber' value='4.0' min='0' max='10' step='.5'>
<input type='range' name='myrange' value='3' min='0' max='10'>
<input type='color' name='mycolor' value='#abcdef'>
Auswahllisten
Auswahllisten können hinsichtlich der Anzahl der angezeigten Elemente sowie hinsichtlich der Anzahl der auswählbaren Elemente definiert werden.
<form accept-charset='utf-8' action='anzeigen.php' method='post'>
<p>Dein Urlaubsziel:</p>
<select name='ziel_a'>
<option>Buxtehude</option>
<option>Mallorca</option>
<option selected>Timbuktu</option>
<option>Island</option>
<option>Kambodscha</option>
</select><br><br>
<select name='ziel_b' size='2'>
<option value='ziel01'>Buxtehude</option>
<option value='ziel02'>Mallorca</option>
<option value='ziel03'>Timbuktu</option>
<option value='ziel04' selected>Island</option>
<option value='ziel05'>Kambodscha</option>
</select><br><br>
<select name='ziel_c' size='5' multiple>
<option value='ziel01'>Buxtehude</option>
<option value='ziel02' selected>Mallorca</option>
<option value='ziel03'>Timbuktu</option>
<option value='ziel04' disabled>Island</option>
<option value='ziel05' selected>Kambodscha</option>
</select><br><br>
<select name='ziel_d' size='5' multiple disabled>
<option value='ziel01'>Buxtehude</option>
<option value='ziel02' selected>Mallorca</option>
<option value='ziel03'>Timbuktu</option>
<option value='ziel04'>Island</option>
<option value='ziel05' selected>Kambodscha</option>
</select><br><br>
<input type='reset' value='Wert zurücksetzen'>
</form>
Hier haben wir vier Listen mit unterschiedlichen Einstellungen. Eine Liste wird immer durch das <select>-Tag definiert. Das Attribut name gibt auch hier wieder die Variable an, der der Wert der Auswahl des Benutzers zugewiesen wird. Das Attribut size gibt die Anzahl der angezeigten Elemente an. Das Attribut multiple gibt an, dass nicht nur ein, sondern mehrere Elemente ausgewählt werden können. Dies geschieht mit Hilfe der Shift- bzw. Strg-Taste. Man markiert das erste Element mit der Maus, dann hält man die Shift-Taste gedrückt und markiert das letzte Element mit der Maus, alle Elemente dazwischen werden ebenfalls ausgewählt. Hält man die Strg-Taste, kann man einzelne Elemente der Auswahl hinzufügen oder aus ihr entfernen.
Jedes einzelne Element der Liste wird von dem <option>-Tag umschlossen. Wird kein value angegeben (s. Liste ziel_a), gilt als Wert der Inhalt des Tags, also der angezeigte Text zwischen Anfangs- und End-Tag. Wird ein Wert angegeben (s. Liste ziel_b bis ziel_d), wird dieser der Variable zugewiesen. Das Attribut selected besagt, dass dieses Element vorausgewählt wird. Das Attribut disabled besagt, dass dieses Element nicht auswählbar wird.
Mit Hilfe des Elements <optgroup> können mehrere <option>-Elemente unter eine gemeinsame Überschrift zusammengefasst werden, die im label-Attribut angegeben wird.
<select name='food'>
<optgroup label='Obst'>
<option>Äpfel</option>
<option>Birnen</option>
<option>Kirschen</option>
<option>Orangen</option>
<option>Bananen</option>
</optgroup>
<optgroup label='Gemüse'>
<option>Kartoffeln</option>
<option>Möhren</option>
<option>Kürbisse</option>
<option>Blumenkohl</option>
<option>Tomaten</option>
</optgroup>
</select>
Versteckte Objekte
Manchmal möchte man Werte übermitteln, die bereits feststehen und nicht von dem Benutzer eingegeben oder ausgewählt werden. Dazu verwendet man ein verstecktes Objekt <input type='hidden'>, das zwar nicht dargestellt aber übermittelt wird.
<form accept-charset='utf-8' action='anzeigen.php' method='post'>
<p>Dein Vorname:</p>
<input type='text' name='vorname'><br><br>
<input type='hidden' name='xy' value='2006'>
<input type='submit' value='abschicken'>
</form>
Ausgabe
Das Element <output> markiert das Ergebnis eines ausgewerteten Formulars, wobei im Attribut for angegeben wird, auf welche Eingabefelder sich das Ergebnis bezieht. In diesem Skript wird die Summe von a und b mit JavaScript berechnet.
<form onsubmit='return false' oninput='o.value = a.valueAsNumber + b.valueAsNumber'>
<input name='a' type='number' step='any'> +
<input name='b' type='number' step='any'> =
<output name='o' for='a b'></output>
</form>
Datei-Upload
Wenn man Dateien auf einen Server hochladen möchte, benötigt man ein spezielles Formular, das einen Button enthält, durch den man die eigene Festplatte nach der gewünschten Datei durchsuchen kann. Nach Bestätigung der Auswahl wird der Pfad der Datei automatisch in das Eingabefeld eingetragen.
<form action='upload.php' method='post' enctype='multipart/form-data'>
<input type='hidden' name='MAX_FILE_SIZE' value='1000000'>
Datei: <input type='file' name='datei' accept='image/*'>
<input type='submit' value='abschicken'>
</form>
Wie eine solche ausgewählte Datei nach Abschicken des Formulars weiterverarbeitet wird, wird im Abschnitt über PHP beschrieben. Dieses Formular hat nun einige Besonderheiten. Zunächst muss im <form>-Tag das Attribut enctype='multipart/form-data' gesetzt werden (encryption type). Dann enthält das Formular ein verstecktes Objekt mit dem Namen MAX_FILE_SIZE und dem Wert der maximal zulässigen Dateigröße in Bytes, um ein Sprengen des Speicherplatzes bzw. der Serveraktivität zu verhindern (hier 1 MB). Schließlich gibt es ein spezielles Eingabefeld des Typs type='file'. Das Attribut accept kann zur Einschränkung von hochladbaren Dateitypen verwendet werden. Der Wert gibt den zugelassenen MIME-Typ an, in diesem Fall für alle Bild-Dateien.
Da das Element <input type='file'> von den verschiedenen Browsern sehr unterschiedlich dargestellt wird, sollte man es mit CSS grafisch anpassen.
Tabellenlose Formulare
Um zu demonstrieren, wie man auch ohne Tabellen ein ordentliches Formular erzeugt, gibt es hier ein Skript für ein Kontaktformular, das mit Gruppenfeldern und Definitionslisten arbeitet und per CSS formatiert wurde.
<!DOCTYPE html>
<html lang='de'>
<head>
<title>Kontaktformular</title>
<meta charset='UTF-8'>
<meta name='description' content='Kontaktformular'>
<style media='screen, print'>
body, form dl dd input, form dl dd textarea, .button { font-family:sans-serif; font-size:14px; }
#contact { width:630px; margin:auto; }
form fieldset { margin-top:60px; background-color:#eee; padding:10px; border-radius:4px; }
form #formtitle { font-size:20px; }
form fieldset fieldset { margin-top:16px; background-color:#ddd; }
form fieldset div { text-align:center; }
form .button { margin-top:12px; }
form dl dt, form dl dd { float:left; margin:0 0 4px; }
form dl dt { width:120px; clear:left; text-align:right; padding:4px 6px 0 0; }
form dl dd input, form dl dd textarea { padding:3px; width:400px; box-shadow:hsl(0,0%,20%) 1px 1px 3px inset; border:1px solid silver; border-radius:4px; }
</style>
</head>
<body>
<form accept-charset='utf-8' action='index.php' method='post'>
<fieldset>
<legend id='formtitle'><b>Kontaktformular</b></legend>
<div class='lpad1'></div>
<fieldset>
<legend><i>Deine Daten</i></legend>
<div class='lpad2'></div>
<dl>
<dt><label for='name'>Name</label></dt>
<dd><input id='name' name='name' value=''></dd>
<dt><label for='email'>E-Mail-Adresse</label></dt>
<dd><input id='email' name='email' value=''></dd>
</dl>
</fieldset>
<fieldset>
<legend><i>Deine Nachricht</i></legend><div class='lpad2'></div>
<dl>
<dt><label for='subject'>Betreff</label></dt>
<dd><input id='subject' name='subject' value=''></dd>
<dt><label for='message'>Nachricht</label></dt>
<dd><textarea id='message' name='message' rows='12' cols='24'></textarea></dd>
</dl>
</fieldset>
<div>
<input type='submit' class='button' value='abschicken'>
<input type='reset' class='button' value='zurücksetzen'>
</div>
</fieldset>
<script> document.getElementById('name').focus(); </script>
</form>
</body>
</html>
Bei dieser Gelegenheit wird auch das <label>-Element vorgestellt.
Mit dem kleinen JavaScript in Zeile 49 lässt sich übrigens der Cursor automatisch in das angegebene Feld name setzen.