Webkrauts Logo

Webkrauts Webkrauts Schriftzug

- für mehr Qualität im Web

Formulare auf der Höhe der Zeit

Formulare auf der Höhe der Zeit

Auch wenn noch nicht alle Browser die HTML5-Neuerungen für Formulare unterstützen, müssen wir nicht auf deren sinnvolle Verwendung verzichten. Störrischen Browsern können diese Neuerungen mit etwas jQuery schonend beigebracht werden.

Gemälde (Ausschnitt): Bernardo Bellotto, Die Kreuzkirche in Dresden vor der Zerstörung. 1747-56. Eremitage, St. Petersburg.

Neben neuen strukturellen Elementen und der nativen Wiedergabe von Audio und Video beschert HTML5 auch einige Neuerungen im Hinblick auf Formulare. Damit nimmt sich die Web Hypertext Application Technology Working Group (WHATWG) sowie das W3C der bisher sehr limitierten Funktionalitäten eines der wichtigsten Interaktions-Elemente des Internets an. Wer jedoch die Diskussionen rund um HTML5 verfolgt hat, fragt sich nun zu Recht, ob diese Neuerungen jetzt schon verwendet werden können. Hier kann ich mit einem klaren »Ja« antworten. Auch wenn noch nicht alle Browser (und manche bisher nur sehr rudimentär) die neuen Formular-Funktionalitäten von HTML5 unterstützen, können die Nachzügler mit ein wenig jQuery-Feenstaub dazu gebracht werden, diese zumindest zu imitieren.

Formular-Neuerungen in HTML5

Eine ausführliche Übersicht aller Formular-Neuerungen in HTML5 wurde bereits an anderer Stelle (Dive Into HTML5: No 9. A Form of Madness) zusammengestellt. Wer so masochistisch veranlagt ist und sich die Spezifikationen der WHATWG durchlesen möchte, findet diese im Kapitel 4.10 Forms. Außerdem möchte ich auf den Webkrauts-Artikel »Tipphilfen« hinweisen, in dem Stefanie Rückert die Neuerungen unter die Lupe genommen hat. Ich möchte hier »nur« ein paar – aus meiner Sicht – nützliche neue Attribute vorstellen und wie diese mit jQuery auch Browsern verständlich gemacht werden können, die diese (noch) nicht verstehen.

Das placeholder-Attribut

Das placeholder-Attribut ermöglicht, das Eingabefeld mit beispielhaftem Inhalt zu befüllen, der bei Klick in ebendieses (bzw. Fokus, um genau zu sein) verschwindet. Diese Funktionalität erforderte bisher den Einsatz von JavaScript, welches auch für einen entsprechenden Fallback notwendig ist.

  1. <input type="text" name="email" placeholder="max.mustermann@domain.de" />

Das Fallback für Browser, die das placeholder-Attribut nicht verstehen, funktioniert wie folgt:

Zuerst wird überprüft, ob der Browser das Attribut unterstützt. Dieser Test ist angelehnt an die von Mark Pilgrim in »Dive Into HTML5« erklärten Methode. Per JavaScript wird ein input-Element erzeugt und dann geprüft, ob ein bestimmtes Attribut existiert, was nur dann der Fall ist, wenn es vom Browser unterstützt wird.

  1. var inputElement = document.createElement('input');
  2. if(!('placeholder' in inputElement)) { }

Falls dies nicht der Fall ist, werden alle Eingabefelder mit diesem Attribut durchlaufen und mit dem Wert des placeholder-Attributs befüllt.

  1. $('input[placeholder]').each(function(n,element){
  2.   var placeholderValue = $(this).attr('placeholder');
  3.   $(this).val(placeholderValue);
  4.   $(this).addClass('placeholderValue');
  5. });

Ist der Fokus auf dem Eingabefeld, wird der Platzhalter-Inhalt entfernt.

  1. $('input[placeholder]').focus(function() {
  2.   if($(this).val() == $(this).attr('placeholder')) {
  3.     $(this).val('');
  4.     $(this).removeClass('placeholderValue');
  5.   }
  6. });

Wenn das Feld nicht mehr im Fokus ist und noch leer ist, wird dieser Platzhalter-Inhalt wieder eingefügt.

  1. $('input[placeholder]').blur(function() {
  2.   if($(this).val().length == 0) {
  3.     $(this).val($(this).attr('placeholder'));
  4.     $(this).addClass('placeholderValue');
  5.   }
  6. });

Siehe auch den entsprechenden Artikel »Der perfekte Suchschlitz« von Gerrit van Aaken aus dem Adventskalender 2008.

Das autofocus-Attribut

Eine weitere Funktion, die bisher bei vielen Internetauftritten mit Hilfe von JavaScript realisiert wurde, ist das automatische Setzen des Fokus auf ein bestimmtes Eingabefeld. Hierfür gibt es nun das neue boolesche Attribut autofocus.

  1. <input type="text" name="s" autofocus />

Im Vergleich zum Fallback für das placeholder-Attribut ist dieses hier natürlich deutlich kürzer. Zuerst wird wieder die Unterstützung dieses Attributs durch den Browser getestet und falls dies negativ ausfällt, der Fokus auf das input-Element gelegt, bei dem dieses Attribut gesetzt ist.

  1. var inputElement = document.createElement('input');
  2. if(!('autofocus' in inputElement)) {
  3.   $('input[autofocus]').focus();
  4. }

Da z.B. Opera 10 zwar das autofocus-Attribut, nicht aber das placeholder-Attribut versteht, setzt dieser den Cursor logischerweise hinter den per jQuery eingefügten Platzhalter-Inhalt. Um dies zu vermeiden, ist folgende Ausnahmeregelung notwendig:

  1. if($('input[autofocus]').val() == $('input[autofocus]').attr('placeholder')) {
  2.   $('input[autofocus]').val('');
  3. }

Das required-Attribut

Mit Hilfe von HTML5 wird die clientseitige Überprüfung der Formular-Eingaben erstmals direkt vom Browser übernommen. Hierfür wird das boolesche Attribut required verwendet, womit jedes Pflichtfeld versehen wird.

  1. <input type="text" name="email" required />

In unserem Beispiel-Formular wird in erster Linie überprüft, ob die Pflichtfelder ausgefüllt sind. Hierfür werden per jQuery alle Eingabefelder mit dem Attribut required durchlaufen und überprüft, ob deren Inhalt länger als 0 Zeichen ist.

  1. $('form').submit(function() {
  2.   var err = 0;
  3.   $('input[required]').each(function(n,element) {
  4.     if($(element).val().length == 0) {
  5.       err++;
  6.     }
  7.   });
  8.   if(err > 0) {
  9.     return false;
  10.   } else {
  11.     return true;
  12.   }
  13. });

Zusätzlich kann dieses neue Attribut hervorragend dafür verwendet werden, ein damit verbundenes label mit einer Kennzeichnung zu versehen. Ich habe hierfür das weit verbreitete Sternchen verwendet und füge die Erklärung des Sternchens dem fieldset-Code hinzu.

  1. $('input[required]').siblings('label').append('*');
  2. $('input[required]').parents('fieldset').append('<p><small>*Pflichtfelder</small></p>');

Neue Eingabefeld-Typen

Neben neuen Attributen kommen mit HTML5 einige nützliche Eingabefeld-Typen hinzu, die zum einen die Eingabe für den User erleichtern sollen und zum anderen eine wichtige Rolle bei der clientseitigen Überprüfung der Eingaben spielen. Im Hinblick auf das zu erstellende Kontaktformular ist nur der Typ email relevant.

Eigene Patterns und Validierung

Währed für Eingabefeld-Typen wie email bereits ein – wenn auch sehr rudimentäres – Validierungs-Muster hinterlegt ist, sieht HTML5 für Eingabefelder auch vor, dass im Attribut pattern eigene Validierungs-Muster hinterlegt werden können. Dies wäre u.a. für die Eingabe von Postleitzahlen (in diesem Falle einer deutschen Postleitzahl mit zwingend fünf Zahlen) sinnvoll. Auch wenn hierfür der neue Eingabefeld-Typ number auf den ersten Blick wie geschaffen erscheint, zeigt der zweite Blick und v.a. die Implementierung in Verbindung mit einer sog. »spin box« (Pfeile zum Erhöhen und Verringern der Zahl), dass dieser für Postleitzahlen nicht geeignet ist. Deshalb ziehe ich hier die Verwendung eines eigenen Patterns vor.

  1. <input type="text" name="postal-code" pattern="[0-9]{5}" />

Leider wird gerade die Formular-Validierung momentan selbst von modernen Browsern (außer Opera) noch sehr rudimentär unterstützt. Die Verwendung dieses Attributs ermöglicht jedoch bereits jetzt ein entsprechendes Fallback per jQuery. Wenn das Attribut pattern existiert, wird dessen Wert zur Validierung herangezogen.

  1. var fieldPattern = new RegExp('^' + $(element).attr('pattern') + '$');
  2. var fieldValue = $(element).val();
  3. if($(element).attr('pattern') && !fieldValue.match(fieldPattern)) {
  4.   return false;
  5. } else {
  6.   return true;
  7. }

Selbstredend kann eine clientseitige Eingabe-Prüfung nur ergänzend zu einer serverseitigen Prüfung verwendet werden, da – wie wir alle wissen – nicht davon ausgegangen werden kann, dass JavaScript aktiviert ist.

WAI-ARIA

Auch wenn WAI-ARIA nicht Gegenstand dieses Artikel ist, habe ich die entsprechenden Attribute verwendet. Nähere Infos gibt es auf den Seiten der Web Accessibility Initiative (WAI) des W3C.

Und nun alles zusammen

Wenn wir nun das oben aufgeführte zusammenstellen, erhalten wir ein Beispiel-Formular, das in allen Browsern ähnlich aussieht und sich ähnlich verhält.

JavaScript deaktiviert?

Im Sinne von »progressive enhancement« wird JavaScript in diesem Beispiel nur zur Erweiterung der bereits existierenden browserübergreifenden Basis-Funktionalität verwendet, weshalb das Formular natürlich auch ohne JavaScript voll funktionsfähig ist. Der einzige heikle Punkte wäre in diesem Zusammenhang die Kennzeichnung der Pflichtfelder, für die ein entsprechender Fallback bedacht werden sollte. Außerdem müssen die Benutzer natürlich auf die teilweise sehr hilfreichen Eingabehilfen wie Platzhalter-Texte verzichten. Die Überprüfung der Benutzer-Eingabe erfolgt dann, wie oben bereits erwähnt, nur serverseitig, weshalb diese unabdingbar ist.

Wer kann was?

Leider hält sich die native Unterstützung der oben angesprochenen HTML5-Neuerungen noch sehr in Grenzen. Im Folgenden habe ich zusammengestellt, welche Neuerungen von welchen Browsern unterstützt werden. Wichtig und hilfreich ist, dass die neuen Eingabefeld-Typen von Browsern, die diese nicht verstehen, wie normale Text-Eingabefelder behandelt werden.

placeholder-Attribut
Firefox ab 4.0 Beta, Safari ab 3.2, Chrome ab 4.0
autofocus-Attribut
Safari ab 4.0, Chrome ab 3.0, Opera ab 10.0
required-Attribut
Firefox ab 4.0, Opera ab 9.0
pattern-Attribut
Firefox ab 4.0, Safari ab 5.0, Chrome ab 6.0, Opera ab 9.0
Validierung
Firefox ab 4.0, Safari ab 5.0, Chrome ab 6.0, Opera ab 9.0

Schönes neues HTML5

Je mehr ich mit HTML5 arbeite, desto überzeugter bin ich davon, dass dieses einen großen Wurf bedeutet. Auch wenn sich HTML5 noch in der Entwicklung befindet und somit auch von Browsern noch sehr unterschiedlich – wenn überhaupt – unterstützt wird, zeigt das obige Beispiele, wie wir Webworker zukunftsfähiges Markup schreiben können und dieses mit Hilfe von jQuery für Browser mit Verständnisschwierigkeiten einfach aufbereiten.

Gemälde (Ausschnitt): Bernardo Bellotto, Die Kreuzkirche in Dresden vor der Zerstörung. 1747-56. Eremitage, St. Petersburg.

Kommentare

Gunnar Bittersmann
am 13.12.2010 - 09:23

<input type="email"> ist gegenwärtig ziemlich unbrauchbar; es ist
1. in der HTML5-Spec falsch spezifiziert und
2. in Browsern dementsprechend falsch implementiert.

Siehe dazu meinen Kommentar in ALA und meine Postings im SELFHTML-Forum.

Wenn man E-Mail-Adressen clientseitig prüfen will, müsste man sich selbst ein Pattern schreiben, das nicht zu restriktiv ist und gültige E-Mail-Adressen abweist. Auf mehr als irgendwas '@' irgendwas '.' irgendwas kann man nicht prüfen:
<input pattern="^[^@]+@[^@.]+\.[^@]+$">

BTW, type="email" darf man dann nicht angeben, da dies das Pattern überschreibt.

Permanenter Link
Sylvia Egger

Sylvia Egger
am 13.12.2010 - 10:33

Lange haben wir auf eine Verbesserung von Formularfeldern gewartet. Nun sind sie endlich da. Herrlich. :)

Das Arbeiten mit Javascript-Fallback find ich in den meisten Fälle wie etwa placeholder nicht wirklich wichtig. Zum einen ist man die letzten Jahre eindeutig weg von diesem Attribut gegangen, weil es im konkreten Ausfüllungsfall eher hinderlich und redundant ist, zum anderen braucht man in diesem Fall im Grunde kein Fallback.

Das autofocus-Attribut sollte man wirklich mit großem Bedacht setzen, nicht nur im Bezug auf die Barrierefreiheit. Den Fokus nach dem Laden bereits auf ein bestimmtes Formularfeld zu setzen, kann auch so etwas usability-technisch schwierig sein. Liegt es etwa etwas weiter unter, gerät der Inhalt oberhalb des Formulars aus dem Blickfeld. Mit Blick auf Barrierefreiheit hat Bruce Lawson das vor einiger Zeit schon zusammengefasst.

Auch sollte man darüber nachdenken, ob das Setzen des Pflichthinweises wirklich per Javascript erfolgen muss, ich finde ja immer, was inhaltlich wichtig ist, kann auch so als Inhalt integriert werden. Auch wenn wir dann mit HTML 5 und WAI-ARIA gewisse Redundanzen haben.

Permanenter Link

Gunnar Bittersmann
am 13.12.2010 - 11:42

Als Ersatz für @placeholder den Text als value des Eingabefeldes zu setzen, halte ich für bedenklich. Da gibt es auch andere Möglichkeiten.

Bei der Kombination von @placeholder und @autofocus wird der Placeholder-Text nicht initial im Eingabefeld nicht angezeigt. IMHO wäre dies aber trotz gesetztem Fokus wünschenswert: Der Placeholder-Text verschwindet erst, wenn der Nutzer etwas eingibt. Zumindest sollte der Seitenautor die Möglichkeit bekommen anzugeben, wie sich das UI bei @placeholder + @autofocus verhalten soll.

Permanenter Link

Bastian Heist
am 13.12.2010 - 14:20

Schöne Zusammenfassung! Ich wollte mich schon länger mal mit den neuen HTML5-Funktionen in Formularen beschäftigen, das ist ein schöner Einstieg. Vielen Dank!

Permanenter Link
Michael Grosch

Michael Grosch (Autor)
am 14.12.2010 - 09:55

Vielen Dank für die wichtigen Hinweise.

Dass die Validierung beim Eingabefeld-Typ email bisher in Browsern nur rudimentär implementiert ist, hatte ich ja erwähnt. Allerdings war mir nicht bewusst, dass dies auf die möglicherweise fehlerhafte Spezifikation zurückzuführen ist. Außerdem wusste ich nicht, dass eine E-Mail-Adresse wie (die von dir im Kommentar bei ALA genannte) "джон.доу@россия.рф" gültig ist. Auf der anderen Seite führt eine Prüfung der E-Mail-Adresse auf "irgendwas '@' irgendwas '.' irgendwas" aber das Bestreben nach Prüfung der Benutzer-Eingaben auf deren Sinnhaftigkeit ad absurdum.

Der sinnvolle Einsatz von placeholder und autofocus wird mit Sicherheit durch die steigende Unterstützung in Browsern weiter kritisch betrachtet. In diesem Zuge darf auch der semantische Unterschied zwischen label und placeholder nicht außer Acht gelassen werden.

Permanenter Link

Gunnar Bittersmann
am 14.12.2010 - 11:58

Domainnamen mit Nicht-ASCII-Zeichen gibt es ja schon längere Zeit (bspw. Umlautdomains im deutschsprachigen Raum). Mittlerweile gibt es auch einige Nicht-ASCII-TLDs.

Der Fehler der HTML5-Spec ist, sich auf RFCs zu beziehen, die dahinterliegende Techniken beschreiben (wo Nicht-ASCII-Zeichen escapet werden), die dem Nutzer verborgen bleiben sollten und die ihn auch überhaupt nicht interessieren.

"irgendwas '@' irgendwas '.' irgendwas" war schon etwas salopp formuliert; mein angegebenes Pattern tut schon etwas mehr: Es prüft, ob genau ein '@' vorkommt und ob nach diesem mindestens ein '.' vorkommt. Das ist doch schon mal was, mehr kann man nicht tun.

Permanenter Link

alexander farkas
am 14.12.2010 - 13:33

@Gunnar

Es prüft, ob genau ein '@' vorkommt und ob nach diesem mindestens ein '.' vorkommt. Das ist doch schon mal was, mehr kann man nicht tun.

Hier liegt dann aber das nächste Problem: "in@fo"@blä.de bzw. in\@fo@blä.de sind ebenfalls valide. Zudem darf der dritte teil auch keinen punkt enthalten.

Kurz: Je mehr man sich mit email-validierung beschäftigt, desto kranker wird es. Scott gonzales hat mal einem regulären Ausdruck gearbeitet, der alles mitberücksichtigt. An manchen stellen scheint er mir aber zu lasch zu sein (aber lieber zu lasch als zu strikt). Hier der vollständige Ausdruck (der ist so schön lesbar):

/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|(\x22((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?\x22))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i

Permanenter Link

Joe Kolade
am 14.12.2010 - 21:11

Das placeholder-Attribut mit der Validierung in Einklang zu bringen wird noch eine Herausforderung.

Wenn die Validierung erstmal versteht, dass der placeholder nicht als Inhalt ausreicht, was passiert dann wenn mal ein "Max Mustermann" das Formular absenden will???

Permanenter Link
Michael Grosch

Michael Grosch (Autor)
am 15.12.2010 - 00:27

Das ist ein guter Punkt. Dies ließe sich umgehen, indem man dem Wert des placeholder-Attributs ein Leerzeichen anhängt.

Permanenter Link

Gunnar Bittersmann
am 15.12.2010 - 01:56

@Michael: Und wenn ein "Max Mustermann " ein Formular absenden will? SCNR. Aber wie gesagt, man schreibt den Placeholder-Text besser nicht in den value des Eingabefeldes, sondern in ein hinter dem Eingabefeld dargestelltes Element.

Permanenter Link

Die Kommentare sind geschlossen.