Einführung
Das Validieren von Formularen war bekanntermaßen eine schmerzhafte Entwicklungserfahrung. Das Implementieren der clientseitigen Validierung auf benutzerfreundliche, entwicklerfreundliche und zugängliche Weise ist schwierig. Vor HTML5 gab es keine Möglichkeit, die Validierung nativ zu implementieren. Daher haben Entwickler auf eine Vielzahl von JavaScript-basierten Lösungen zurückgegriffen.
Um die Entwickler zu entlasten, hat HTML5 ein Konzept eingeführt, das als Integritätsregelungsvalidierung bezeichnet wird - eine native Methode zur Implementierung der clientseitigen Validierung auf Webformularen.
Trotz der Verfügbarkeit in der neuesten Version aller gängigen Browser ist die Gültigkeitsprüfung von Einschränkungen ein Thema, das weitgehend auf Präsentationen und Demos beschränkt ist. Mein Ziel beim Schreiben ist es, ein wenig Licht in die neuen APIs zu bringen, um Entwicklern dabei zu helfen, bessere Webformulare für alle zu erstellen.
In diesem Tutorial werde ich:
- Präsentieren Sie einen umfassenden Überblick über die Gültigkeitsprüfung von Einschränkungen.
- Informieren Sie sich über die aktuellen Einschränkungen der Spezifikations- und Browserimplementierungen.
- Erläutern Sie, wie Sie die HTML5-Einschränkungsüberprüfung jetzt in Ihren Formularen verwenden können.
Was ist die Constraint-Validierung?
Der Kern der Einschränkungsvalidierung ist ein Algorithmus, der von Browsern ausgeführt wird, wenn ein Formular gesendet wird, um seine Gültigkeit zu bestimmen. Um diese Bestimmung zu machen, verwendet der Algorithmus neues HTML5 - Attribut min
, max
, step
, pattern
, und required
sowie bestehende Attribute maxlength
und type
.
Nehmen Sie als Beispiel dieses Formular mit einer leeren required
Texteingabe:
<form> <input type = "text" erforderlicher Wert = "" /> <input type = "submit" value = "Submit" /> </ form>Versuch es
Wenn Sie versuchen, dieses Formular so wie es ist zu senden, wird die Übermittlung durch unterstützende Browser verhindert und Folgendes angezeigt:
- Chrome 21
- Firefox 15
- Internet Explorer 10
- Opera 12
- Opera Mobile
- Chrome für Android
- Firefox für Android
Gemäß der Spezifikation bleibt es dem Browser selbst überlassen, wie Fehler dem Benutzer angezeigt werden. Die Spezifikation bietet jedoch eine vollständige DOM-API, neue HTML-Attribute und CSS-Hooks, mit denen Autoren die Erfahrung anpassen können.
DOM API
Die API für die Gültigkeitsprüfung von Einschränkungen fügt den DOM-Knoten die folgenden Eigenschaften / Methoden hinzu.
willValidate
Die willValidate
Eigenschaft gibt an, ob der Knoten ein Kandidat für die Gültigkeitsprüfung von Einschränkungen ist. Für einreichbare Elemente wird dies festgelegt, true
sofern der Knoten nicht aus irgendeinem Grund von der Gültigkeitsprüfung für Einschränkungen ausgeschlossen ist , z. B. wenn er das disabled
Attribut besitzt.
<div id = "one" > </ div> <input type = "text" id = "two" /> <input type = "text" id = "three" disabled /> <script> -Dokument . getElementById ( 'one' ). willValidate ; // undefiniertes Dokument . getElementById ( 'two' ). willValidate ; // wahres Dokument . willValidate ; // false </ script>
Gültigkeit
Die validity
Eigenschaft eines DOM-Knotens gibt ein ValidityState
Objekt zurück, das eine Reihe von booleschen Eigenschaften enthält, die sich auf die Gültigkeit der Daten im Knoten beziehen.
-
customError
:true
Wenn für einen Anruf an eine benutzerdefinierte Gültigkeitsnachricht festgelegt wurdesetCustomValidity()
.<input id = "foo" /> <input id = "bar" /> <script> Dokument . getElementById ( 'foo' ). Gültigkeit . customError ; // falsches Dokument . getElementById ( 'bar' ). setCustomValidity ( 'Invalid' ); dokumentieren . getElementById ( 'bar' ). Gültigkeit . customError ; // true </ script>
-
patternMismatch
:true
Wenn der Knotenvalue
nicht mit seinempattern
Attribut übereinstimmt .<input id = "foo" pattern = "[0-9] {4}" value = "1234" /> <input id = "bar" pattern = "[0-9] {4}" value = "ABCD" /> <script> document . getElementById ( 'foo' ). Gültigkeit . patternMismatch ; // falsches Dokument . getElementById ( 'bar' ). Gültigkeit . patternMismatch ;
-
rangeOverflow
:true
Wenn der Knotenvalue
größer als seinmax
Attribut ist.<input id = "foo" type = "number" max = "2" value = "1" /> <input id = "bar" type = "number" max = "2" value = "3" /> <script > Dokument . getElementById ( 'foo' ). Gültigkeit . rangeOverflow ; // falsches Dokument . getElementById ( 'bar' ). Gültigkeit . rangeOverflow ; // true </ script>
-
rangeUnderflow
:true
Wenn der Knotenvalue
kleiner als seinmin
Attribut ist.<input id = "foo" type = "number" min = "2" value = "3" /> <input id = "bar" type = "number" min = "2" value = "1" /> <script > Dokument . getElementById ( 'foo' ). Gültigkeit . rangeUnderflow ; // falsches Dokument . getElementById ( 'bar' ). rangeUnderflow ; // true </ script>
-
stepMismatch
:true
Wenn der Knotenvalue
gemäß seinemstep
Attribut ungültig ist .<input id = "foo" type = "number" step = "2" value = "4" /> <input id = "bar" type = "number" step = "2" value = "3" /> <script > Dokument . getElementById ( 'foo' ). Gültigkeit . stepMismatch ; // falsches Dokument . getElementById ( 'bar' ). Gültigkeit . stepMismatch ; // true </ script>
-
tooLong
:true
Wenn der Knotenvalue
seinmaxlength
Attribut überschreitet . Alle Browser verhindern dies, indem sie verhindern, dass Benutzer Werte eingeben, die die maximale Länge überschreiten. Obwohl selten, ist es möglich, dass diese Eigenschafttrue
in einigen Browsern vorhanden ist. Ich habe darüber geschrieben, wie das hier möglich ist . -
typeMismatch
:true
Wenn der eines Eingabeknotensvalue
gemäß seinemtype
Attribut ungültig ist .<input id = "foo" type = "url" value = "http://foo.com" /> <input id = "bar" type = "url" value = "foo" /> <input id = "foo2" type = "email" value = "foo@foo.com" /> <input id = "bar2" type = "email" value = "bar" /> <script> document . getElementById ( 'foo' ). Gültigkeit . typeMismatch ; // falsches Dokument . getElementById ( 'bar' ). Gültigkeit . typeMismatch ; //wahr dokumentieren . getElementById ( 'foo2' ). Gültigkeit . typeMismatch ; // falsches Dokument . getElementById ( 'bar2' ). Gültigkeit . typeMismatch ; // true </ script>
-
valueMissing
:true
Wenn der Knoten einrequired
Attribut hat, aber keinen Wert.<input id = "foo" type = "text" erforderlicher Wert = "foo" /> <input id = "bar" type = "text" erforderlicher Wert = "" /> <script> document . getElementById ( 'foo' ). Gültigkeit . valueMissing ; // falsches Dokument . getElementById ( 'bar' ). Gültigkeit . valueMissing ;
-
valid
:true
wenn alle oben aufgeführten Gültigkeitsbedingungen erfüllt sindfalse
.<input id = "valid-1" type = "text" erforderlicher Wert = "foo" /> <input id = "valid-2" type = "text" erforderlicher Wert = "" /> <script> document . getElementById ( 'valid-1' ). Gültigkeit . gültig ; // wahres Dokument . getElementById ( 'valid-2' ). Gültigkeit . gültig ; </ script>
validationMessage
Die validationMessage
Eigenschaft eines DOM-Knotens enthält die Nachricht, die der Browser dem Benutzer anzeigt, wenn die Gültigkeit eines Knotens überprüft wird und fehlschlägt.
Der Browser stellt eine lokalisierte Standardnachricht für diese Eigenschaft bereit. Wenn der DOM-Knoten kein Kandidat für die Gültigkeitsprüfung einer Einschränkung ist oder wenn der Knoten gültige Daten enthält, validationMessage
wird eine leere Zeichenfolge festgelegt.
Hinweis: Zum jetzigen Zeitpunkt füllt Opera diese Eigenschaft nicht standardmäßig aus. Es wird dem Benutzer eine korrekte Fehlermeldung angezeigt, es wird nur die Eigenschaft nicht ausgefüllt.
<input type = "text" id = "foo" erforderlich /> <script> document . getElementById ( 'foo' ). validationMessage ; // Chrome -> 'Bitte füllen Sie dieses Feld aus.' // Firefox -> 'Bitte füllen Sie dieses Feld aus.' // Safari -> 'Wert fehlt' // IE10 -> 'Dies ist ein Pflichtfeld.' // Opera -> '' </ script>
checkValidity ()
Die checkValidity
Methode auf einem Formularelementknoten (z. B. Eingabe, Auswahl, Textbereich) gibt zurück, true
ob das Element gültige Daten enthält.
Auf Formularknoten wird zurückgegeben, true
wenn alle untergeordneten Elemente des Formulars gültige Daten enthalten.
<form id = "form-1" > <input id = "input-1" type = "text" required /> </ form> <form id = "form-2" > <input id = "input-2" type = "text" /> </ form> <script> document . getElementById ( 'form-1' ). checkValidity (); // falsches Dokument . getElementById ( 'input-1' ). checkValidity (); //falsch dokumentieren . getElementById ( 'form-2' ). checkValidity (); // wahres Dokument . getElementById ( 'input-2' ). checkValidity (); // true </ script>
Außerdem wird jedes Mal, wenn die Gültigkeit eines Formularelements über überprüft wird checkValidity
und fehlschlägt, ein invalid
Ereignis für diesen Knoten ausgelöst. Wenn Sie mit dem obigen Beispielcode etwas ausführen möchten, wenn der Knoten mit der ID input-1
überprüft wurde und ungültige Daten enthielt, können Sie Folgendes verwenden:
dokumentieren . getElementById ( 'input-1' ). addEventListener ( 'ungültig' , function () { // ... }, false );
Es gibt kein gültiges Ereignis. Sie können das change
Ereignis jedoch für Benachrichtigungen verwenden, wenn sich die Gültigkeit eines Felds ändert.
dokumentieren . getElementById ( 'input-1' ). addEventListener ( 'change' , function ( event ) { if ( event . target . validity . valid ) { // Feld enthält gültige Daten. } else { // Feld enthält ungültige Daten. } }, false );
setCustomValidity ()
Die setCustomValidity
Methode ändert die validationMessage
Eigenschaft und ermöglicht es Ihnen, benutzerdefinierte Validierungsregeln hinzuzufügen.
Durch das Festlegen der validationMessage
Übergabe in einer leeren Zeichenfolge wird das Feld als gültig markiert und durch das Übergeben einer anderen Zeichenfolge wird das Feld als ungültig markiert. Leider gibt es keine Möglichkeit, das zu setzen, validationMessage
ohne auch die Gültigkeit eines Feldes zu ändern.
Wenn Sie beispielsweise zwei Kennwortfelder hatten, deren Gleichheit Sie erzwingen möchten, können Sie Folgendes verwenden:
if ( document . getElementById ( 'password1' ). value ! = document . getElementById ( 'password2' ). value ) { document . getElementById ( 'password1' ). setCustomValidity ( 'Passwörter müssen übereinstimmen.' ); } else { document . getElementById ( 'password1' ). setCustomValidity ( '' ); }
HTML-Attribute
Wir haben bereits gesehen , dass die maxlength
, min
, max
, step
, pattern
, und type
Attribute durch den Browser zu constrain Daten verwendet werden. Für die Gültigkeitsprüfung von Einschränkungen gibt es zwei zusätzliche relevante Attribute - novalidate
und formnovalidate
.
Novalidat
Das boolesche novalidate
Attribut kann auf Formknoten angewendet werden. Wenn vorhanden, gibt dieses Attribut an, dass die Daten des Formulars beim Senden nicht überprüft werden sollen.
<form novalidate > <input type = "text" required /> <input type = "submit" value = "Submit" /> </ form>
Da das obige Formular das novalidate
Attribut hat, wird es gesendet, obwohl es eine leere erforderliche Eingabe enthält.
Formnovalidat
Das boolesche formnovalidate
Attribut kann auf Schaltflächen- und Eingabeknoten angewendet werden, um die Formularüberprüfung zu verhindern. Beispielsweise:
<form> <input type = "text" erforderlich /> <input type = "submit" value = "Validate" /> <input type = " submit " value = "Do NOT Validate" formnovalidate /> </ form>Versuch es
Wenn Sie auf die Schaltfläche "Bestätigen" klicken, wird die Übermittlung des Formulars aufgrund der leeren Eingabe verhindert. Wenn Sie jedoch auf die Schaltfläche "NICHT validieren" klicken, wird das Formular trotz der ungültigen Daten aufgrund des formnovalidate
Attributs gesendet.
CSS-Haken
Beim Schreiben einer wirksamen Formularüberprüfung geht es nicht nur um die Fehler selbst; Ebenso wichtig ist es, dem Benutzer die Fehler auf benutzerfreundliche Weise anzuzeigen, und unterstützende Browser bieten Ihnen CSS-Hooks, um genau das zu tun.
: ungültig und: gültig
In unterstützten Browsern :valid
stimmen die Pseudoklassen mit Formularelementen überein, die den angegebenen Einschränkungen entsprechen, und die :invalid
Pseudoklassen stimmen mit denen überein, die diese Bedingungen nicht erfüllen .
<form> <input type = "text" id = "foo" erforderlich /> <input type = "text" id = "bar" /> </ form> <script> Dokument . querySelectorAll ( 'input [type = "text"]: invalid' ); // Entspricht der Eingabe # foo document . querySelectorAll ( 'input [type = "text"]: valid' ); // Entspricht der Eingabe-Leiste </ script>
Zurücksetzen des Standardstils
Standardmäßig legt Firefox ein rotes box-shadow
und IE10 mit einem roten outline
auf :invalid
Feldern.
- Firefox 15
- Internet Explorer 10
WebKit-basierte Browser und Opera tun standardmäßig nichts. Wenn Sie einen konsistenten Ausgangspunkt wünschen, können Sie die Standardeinstellungen wie folgt unterdrücken.
: ungültig { box-shadow : keine ; / * FF * / outline : 0 ; / * IE 10 * / }
Ich habe eine ausstehende Pull-Anfrage , um zu diskutieren, ob diese Normalisierung in normalize.css gehört .
Inline-Blasen
Eine größere Anzeigedifferenz ist das Aussehen der Inline-Überprüfungsblasen, die der Browser in ungültigen Feldern anzeigt. WebKit ist jedoch das einzige Renderingmodul, mit dem Sie die Sprechblase anpassen können. In WebKit können Sie mit den folgenden 4 Pseudoklassen experimentieren, um ein benutzerdefinierteres Erscheinungsbild zu erhalten.
:: - webkit-validation-bubble {} :: - webkit-validation-bubble-message {} :: - webkit-validation-bubble-arrow {} :: - webkit-validation-bubble-arrow-clipper {}
Entfernen der Standardblase
Da Sie das Aussehen der Sprechblasen in WebKit nur anpassen können, können Sie die Standard-Sprechblase unterdrücken und Ihre eigenen implementieren, wenn Sie ein benutzerdefiniertes Aussehen für alle unterstützten Browser wünschen. Im Folgenden werden die Standard-Inline-Überprüfungsblasen aller Formulare auf einer Seite deaktiviert.
var forms = document . getElementsByTagName ( 'form' ); for ( var i = 0 ; i < Formulare . Länge ; i ++) { Formulare [ i ]. addEventListener ( 'ungültig' , Funktion ( e ) { e . preventDefault (); // Implementiere möglicherweise deine eigene hier. }, true ); }
Wenn Sie die Standardblasen unterdrücken, stellen Sie sicher, dass Sie den Benutzern nach ungültigen Formularübermittlungen Fehler anzeigen. Derzeit sind die Blasen das einzige Mittel, mit dem Browser anzeigen, dass ein Fehler aufgetreten ist.
Aktuelle Implementierungsprobleme und Einschränkungen
Während diese neuen APIs der clientseitigen Formularvalidierung viel Kraft verleihen, gibt es einige Einschränkungen in Bezug auf die Funktionalität.
setCustomValidity
Das einfache Festlegen validationMessage
eines Feldes setCustomValidity
funktioniert, aber wenn die Formulare komplexer werden, werden eine Reihe von Einschränkungen der setCustomValidity
Methode offensichtlich.
Problem Nr. 1 : Behandlung mehrerer Fehler in einem Feld
Das Aufrufen setCustomValidity
eines Knotens überschreibt einfach dessen validationMessage
. Wenn Sie also setCustomValidity
zweimal auf demselben Knoten anrufen, wird beim zweiten Aufruf einfach der erste überschrieben. Es gibt keinen Mechanismus, mit dem eine Reihe von Fehlermeldungen behandelt oder dem Benutzer mehrere Fehlermeldungen angezeigt werden können.
Eine Möglichkeit, dies zu handhaben, besteht darin, zusätzliche Nachrichten an die Knoten validationMessage
als solche anzuhängen .
var foo = document . getElementById ( 'foo' ); foo .setCustomValidity ( foo . validationMessage + 'Ein Fehler ist aufgetreten' );
Sie können keine HTML- oder Formatierungszeichen übergeben, sodass Sie bei der Verkettung von Zeichenfolgen leider Folgendes erhalten:
Problem Nr. 2 : Wissen, wann die Gültigkeit eines Feldes überprüft werden muss
Betrachten Sie zur Veranschaulichung dieses Problems das Beispiel eines Formulars mit zwei Kennworteingabefeldern, die übereinstimmen müssen:
<form> <fieldset> <legend> Passwort ändern </ legend> <ul> <li> <label for = "password1" > Passwort 1: </ label> <input type = "password" Erforderliche ID = "password1" /> </ li> <li> <label for = "password2" > Passwort 2: </ label> <input type = "password" Erforderliche ID = "password2"/> = "submit" /> </ Li> </ ul> <input Typ submit </ fieldset> </ form>
Mein früherer Vorschlag war, das change
Ereignis zu verwenden, um die Validierung zu implementieren, die ungefähr so ??aussieht:
var password1 = Dokument . getElementById ( 'password1' ); var password2 = Dokument . getElementById ( 'password2' ); var checkPasswordValidity = function () { if ( password1 . value ! = password2 . value ) { password1 . setCustomValidity ( 'Passwörter müssen übereinstimmen.' ); } else { password1 . setCustomValidity ( '' ); } }; Passwort1 . addEventListener ( 'change' , checkPasswordValidity , false ); Passwort2 . addEventListener ( 'change' , checkPasswordValidity , false );Versuch es
Wenn nun der Wert eines der Kennwortfelder vom Benutzer geändert wird, wird die Gültigkeit erneut bewertet. Betrachten Sie jedoch ein Skript, das die Kennwörter automatisch ausfüllt, oder sogar ein Skript, das ein Einschränkungsattribut wie zpattern
, required
, min
, max
, oder step
. Dies könnte die Gültigkeit der Kennwortfelder absolut beeinträchtigen, es ist jedoch kein Ereignis erkennbar, dass dies geschehen ist.
Fazit: Wir brauchen ein Mittel von Code ausgeführt wird, wenn ein Gültigkeitsfeld könnte geändert.
Problem Nr. 3 : Wissen, wann ein Benutzer versucht, ein Formular abzusenden
Warum nicht die Formulare verwenden? submit
Ereignis für das oben beschriebene Problem verwenden? Das submit
Ereignis wird erst ausgelöst, nachdem der Browser festgestellt hat, dass ein Formular gültige Daten enthält, wenn alle angegebenen Einschränkungen erfüllt sind. Daher gibt es keine Möglichkeit zu wissen, wann ein Benutzer versucht, ein Formular zu senden, und es wird vom Browser verhindert.
Es kann sehr nützlich sein zu wissen, wann ein Übermittlungsversuch stattfindet. Möglicherweise möchten Sie dem Benutzer eine Liste mit Fehlermeldungen anzeigen, den Fokus ändern oder Hilfetext anzeigen. Leider benötigen Sie eine Problemumgehung, um dies zu erreichen.
Eine Möglichkeit, dies zu erreichen, besteht darin, das novalidate
Attribut dem Formular hinzuzufügen und dessen submit
Ereignis zu verwenden. Aufgrund des novalidate
Attributs wird die Übermittlung des Formulars unabhängig von der Gültigkeit der Daten nicht verhindert. Daher muss das Client-Skript explizit prüfen, ob das Formular in einem submit
Ereignis gültige Daten enthält, und die Übermittlung entsprechend verhindern. Hier ist eine Erweiterung des Kennwortübereinstimmungsbeispiels, die erzwingt, dass die Überprüfungslogik ausgeführt wird, bevor das Formular gesendet wird.
<form id = "passwordForm" novalidate > <fieldset> <legend> Passwort ändern </ legend> <ul> <li> <label for = "password1" > Passwort 1: </ label> <input type = "password" Erforderliche ID = "password1" /> </ li> <li> <label for = "password2" > Passwort 2: </ label> <input type = "Passwort " Erforderliche ID = " Passwort2 " /> </ li> </ ul> <input type = " submit " /> </ fieldset> </ form> <script> var password1 = document . getElementById ( 'password1' ); var password2 = Dokument . getElementById ( 'password2' ); var checkPasswordValidity = function () { if ( password1 . value ! = password2 . value ) { password1 . setCustomValidity ( 'Passwörter müssen übereinstimmen.' ); } else { password1 . setCustomValidity ( '' ); } }; Passwort1 . addEventListener ( 'change' , checkPasswordValidity , false ); Passwort2 . addEventListener ( 'change' , checkPasswordValidity , false ); var form = document . getElementById ( 'passwordForm' ); bilden . addEventListener ( ' submit ' , function () { checkPasswordValidity (); if (! this . checkValidity ()) { event . preventDefault (); // Implementiere eigene Mittel, um dem Benutzer hier Fehlermeldungen anzuzeigen. password1 . focus () ; } }, false ); </ script>Versuch es
Der Hauptnachteil dieses Ansatzes besteht darin, dass das Hinzufügen des novalidate
Attributs zu einem Formular verhindert, dass der Browser dem Benutzer die Inline-Validierungsblase anzeigt. Wenn Sie diese Technik verwenden, müssen Sie daher Ihre eigenen Methoden implementieren, um dem Benutzer Fehlermeldungen anzuzeigen. Hier ist ein einfaches Beispiel, das einen Weg zeigt, dies zu erreichen.
Fazit: Wir brauchen ein forminvalid
Ereignis, das immer dann ausgelöst wird, wenn eine Formularübermittlung aufgrund ungültiger Daten verhindert wurde.
Safari
Obwohl Safari die API für die Gültigkeitsprüfung von Einschränkungen unterstützt, wird Safari zum jetzigen Zeitpunkt (Version 6) das Senden eines Formulars mit Problemen bei der Gültigkeitsprüfung von Einschränkungen nicht verhindern. Für den Benutzer verhält sich Safari nicht anders als ein Browser, der die Gültigkeitsprüfung von Einschränkungen überhaupt nicht unterstützt.
Dies lässt sich am einfachsten umgehen, indem Sie denselben Ansatz wie in der oben beschriebenen Problemumgehung verwenden, allen Formularen das novalidate
Attribut zuweisen und das Senden von Formularen manuell verhindern preventDefault
. Der folgende Code fügt dieses Verhalten allen Formularen hinzu.
var forms = document . getElementsByTagName ( 'form' ); for ( var i = 0 ; i < Formulare . Länge ; i ++) { Formulare [ i ]. noValidate = true ; bildet [ i ]. addEventListener ( ' submit ' , function ( event ) { // Übermittlung verhindern, wenn checkValidity im Formular false zurückgibt. if (! event . target . checkValidity ()) { event . preventDefault (); // Implementieren Sie Ihre eigenen Methoden zum Anzeigen von Fehlern Nachrichten an den Benutzer hier. } }, false ); }Versuch es
Hinweis: Es gibt mehrere dokumentierte Fehler, bei denen die checkValidity
Methode falsch positive Ergebnisse zurückgibt (siehe hier und hier) ). False Positives sind bei der obigen Problemumgehung besonders gefährlich, da der Benutzer auf einem Formular mit gültigen Daten festsitzt. Seien Sie also vorsichtig.
Deklarative Fehlermeldungen
Sie haben zwar die Möglichkeit, die Fehlermeldung eines Feldes durch Setzen des validationMessage
Durchgangs zu ändern setCustomValidity
, es kann jedoch lästig sein, das JavaScript-Boilerplate kontinuierlich einzurichten, um dies zu erreichen, insbesondere bei großen Formularen.
Um diesen Vorgang zu vereinfachen, hat Firefox ein benutzerdefiniertes x-moz-errormessage
Attribut eingeführt, mit dem Felder automatisch festgelegt werden können validationMessage
.
<form> <input type = "text" required x-moz-errormessage = " Bitte ausfüllen ." /> <input type = "submit" value = "Submit" /> </ form>Versuch es
Wenn das obige Formular in Firefox gesendet wird, wird dem Benutzer anstelle der Standardnachricht des Browsers die benutzerdefinierte Nachricht angezeigt.
Diese Funktion wurde dem W3C vorgeschlagen, aber abgelehnt. Daher ist Firefox derzeit der einzige Browser, in dem Sie Fehlermeldungen deklarativ angeben können.
Titel Attribut
Während es das nicht ändert validationMessage
, patternMismatch
zeigen Browser den Inhalt des title
Attributs in der Inline-Blase an, wenn es bereitgestellt wird. ( Hinweis: Chrome zeigt das title
Attribut tatsächlich an , wenn es für einen beliebigen Fehlertyp bereitgestellt wird, nicht nur für patternMismatch
es. )
Wenn Sie beispielsweise versuchen, das folgende Formular einzureichen:
<form> <label for = "price" > Preis: $ </ label> <input type = "text" pattern = "[0-9]. [0-9] [0-9]" title = "Bitte eingeben der Preis im x.xx-Format (zB 3.99) " id = " price " value = " 3 " /> <input type = " submit " value = " Submit " /> </ form>Versuch es
Hier ist eine Auswahl der Browser, die angezeigt werden:
- Chrome 21
- Firefox 15
- Opera 12
- IE 10
: ungültig und: gültig
Wie bereits erwähnt, stimmt die :valid
Pseudoklasse mit Formularelementen überein, die alle angegebenen Bedingungen erfüllen, und die :invalid
Pseudoklasse stimmt mit denjenigen überein, die diese Bedingungen nicht erfüllen . Leider werden diese Pseudoklassen unmittelbar vor dem Absenden des Formulars und vor der Interaktion mit dem Formular abgeglichen. Betrachten Sie das folgende Beispiel:
<style> : ungültig { border : 1px solid red ; } : valid { border : 1px solid green ; } </ style> <form> <input type = "text" erforderlich /> <input type = "text" /> </ form>Versuch es
Ziel ist es, ungültige Felder einfach mit einem roten und gültige Felder mit einem grünen Rand zu umgeben. Dies geschieht sofort, wenn das Formular gerendert wird. Allerdings Usability - Tests von Inline - Formularvalidierung haben gezeigt , dass die beste Zeit , Nutzer - Feedback zu geben , ist unmittelbar nach dem sie wirken mit einem Feld, nicht vor.
Eine Möglichkeit, dies mit dem obigen Beispiel zu erreichen, besteht darin, den Eingaben nach der Interaktion eine Klasse hinzuzufügen und die Rahmen nur dann anzuwenden, wenn die Klasse vorhanden ist.
<style> . interagiert : ungültig { Grenze : 1px durchgehend rot ; } . interagiert : gültig { border : 1px solid green ; } </ Style> <form> <input Typ = "text" erforderlich /> <input Typ = "text" /> <input Typ = "Eintragen" /> </ form> <script> var Eingänge = Dokument . querySelectorAll ( 'input [type = text]' ); for ( var i = 0 ; i < eingaben . länge ; i ++) { eingaben [ i ]. addEventListener ( 'blur' , function ( event ) { event . target . classList . add ( 'interacted' ); }, false ); } </ script>Versuch es
Firefox hat diese Probleme erkannt und zwei zusätzliche Pseudoklassen implementiert - :-moz-ui-invalid
und :-moz-ui-valid
. Im Gegensatz zu :invalid
und :valid
wird :-moz-ui-invalid
und :-moz-ui-valid
nicht mit einem Feld übereinstimmen, bis das Feld geändert wird oder der Benutzer versucht, das Formular mit ungültiger Eingabe zu senden.
Basierend auf dieser Arbeit enthält die Spezifikation der CSS-Selektoren der Stufe 4 eine :user-error
Pseudoklasse, die ähnlich funktioniert :-moz-ui-invalid
. Es muss noch von keinem Browser implementiert werden.
Eine letzte Anmerkung. Beachten Sie, dass :valid
und :invalid
sollte <form>
Knoten zusätzlich zu Formularelementen entsprechen. Derzeit wurde dies nur in Firefox implementiert. Seien Sie jedoch vorsichtig, wenn Sie globale Regeln auf :valid
und anwenden :invalid
.
Nicht unterstützte Browser
Die Browserunterstützung für die Gültigkeitsprüfung von Einschränkungen ist zwar recht gut, es gibt jedoch einige wichtige Player, bei denen sie nicht vorhanden sind, insbesondere IE <= 9, iOS Safari und der Standard-Android-Browser.
Umgang mit nicht unterstützten Browsern
Wenn Sie beabsichtigen, die neuen APIs für die Gültigkeitsprüfung von Einschränkungen in einem Produktionswebformular zu verwenden, müssen Sie Maßnahmen gegen nicht unterstützte Browser ergreifen. Nach meiner Erfahrung gibt es zwei Hauptoptionen:
Option 1 - Sich allein auf die serverseitige Validierung verlassen
Es ist wichtig, sich daran zu erinnern, dass auch mit diesen neuen APIs die clientseitige Validierung nicht die Notwendigkeit einer serverseitigen Validierung beseitigt. Böswillige Benutzer können problemlos clientseitige Einschränkungen umgehen, und HTTP-Anforderungen müssen nicht von einem Browser stammen.
Daher sollte die clientseitige Validierung immer als eine fortschreitende Verbesserung der Benutzererfahrung betrachtet werden. Alle Formulare sollten auch dann verwendbar sein, wenn keine clientseitige Validierung vorliegt.
Da Sie ohnehin eine serverseitige Validierung benötigen, haben Sie einen eingebauten Fallback für Browser, die keine Form der clientseitigen Validierung unterstützen, wenn Sie Ihren serverseitigen Code einfach dazu bringen, sinnvolle Fehlermeldungen zurückzugeben und sie dem Endbenutzer anzuzeigen.
Option 2 - Polyfill
Für einige Anwendungen ist es zwar sinnvoll, sich auf die serverseitige Validierung zu verlassen, für viele ist es jedoch keine Option, die Benutzerfreundlichkeitsvorteile der clientseitigen Validierung für Benutzer in nicht unterstützten Browsern zu vernachlässigen.
Wenn Sie Code mit den neuen APIs schreiben möchten und er überall funktionieren soll, können Sie dies am besten mit einer Polyfüllung erreichen . Zusätzlich dazu, dass die APIs in nicht unterstützten Browsern funktionieren, benötigen viele Polyfills einen zusätzlichen Schritt und umgehen einige der Probleme in den nativen Implementierungen.
Polyfüllung
Es gibt eine Reihe von Polyfills , die die Verwendung der API für die Gültigkeitsprüfung von Einschränkungen in jedem Browser ermöglichen. Ich werde zwei der beliebtesten verfügbaren Optionen diskutieren.
Webshims
Webshims ist eine Sammlung von Polyfills, darunter eines für HTML5-Formulare und die API für die Gültigkeitsprüfung von Einschränkungen.
Um zu zeigen, wie Webshims verwendet wird, kehren wir zu unserem ursprünglichen Beispiel eines Formulars mit einer einzigen required
Texteingabe zurück.
<form> <input type = "text" erforderlicher Wert = "" /> <input type = "submit" value = "Submit" /> </ form>
Damit dies in allen Browsern konsistent funktioniert, müssen Sie Webshims und ihre Abhängigkeiten einbeziehen und dann aufrufen $.webshims.polyfill('forms')
.
<! - Abhängigkeiten von Webshims -> <script src = "js / jquery-1.8.2.js" > </ script> <script src = "js / modernizr-yepnope-custom.js" > </ script> <! - Webshims base -> <script src = "js-webshim / minified / polyfiller.js" > </ script> <script> jQuery . Webshims . Polyfill ( "Formen" ); </ script> <form> <input type = "text" erforderlicher Wert = "" /> <input type = "submit" value = "Submit" /> </ form>Versuch es
In unterstützten Browsern gibt es keinen Unterschied im Ergebnis. Browser, die die Einschränkungsüberprüfung nicht standardmäßig unterstützen, verhindern jetzt ungültige Formularübermittlungen und zeigen eine Fehlermeldung in einer benutzerdefinierten Sprechblase an. Zum Beispiel ist hier, was der Benutzer in Safari und IE8 sehen wird.
- Safari 6
- Internet Explorer 8
Zusätzlich zur Polyfüllung bietet Webshims auch Lösungen für viele der Einschränkungen der Integritätsbedingungsvalidierung, die zuvor erläutert wurden.
- Geben Sie Fehlermeldungen deklarativ über ein
data-errormessage
Attribut an. - Bietet Klassen
form-ui-valid
undform-ui-invalid
die ähnlich wie:-moz-ui-valid
und funktionieren:-moz-ui-invalid
. - Stellt benutzerdefinierte Ereignisse
firstinvalid
,lastinvalid
,changedvalid
, undchangedinvalid
. - Enthält Problemumgehungen für WebKit-Fehlalarme beim Absenden des Formulars.
Weitere Informationen zu Webshims finden Sie in den HTML5-Formulardokumenten .
H5F
H5F ist eine einfache, abhängigkeitsfreie Polyfill, die die vollständige API für die Gültigkeitsprüfung von Einschränkungen sowie eine Reihe neuer Attribute implementiert.
Um zu sehen, wie H5F verwendet wird, fügen wir es unserem Basisbeispiel eines Formulars mit einer einzigen required
Texteingabe hinzu.
<script src = "H5F.js" > </ script> <form> <input type = "text" erforderlicher Wert = "" /> <input type = "submit" value = "Submit" /> </ form> <script> H5F . setup ( document . getElementsByTagName ( 'form' )); </ script>Versuch es
H5F verhindert die Übermittlung des Formulars in allen Browsern, der Benutzer sieht jedoch nur eine Inline-Überprüfungsblase in Browsern, die dies nativ unterstützen. Da H5F die vollständige API für die Gültigkeitsprüfung von Einschränkungen ausfüllt, können Sie damit Ihre eigene Benutzeroberfläche implementieren, um alles zu tun, was Sie möchten.
Wenn Sie nach Beispielen suchen, wie Sie die API nutzen können, finden Sie auf der Demo-Seite von H5F eine Implementierung, in der die Meldungen in einer Blase rechts neben den Eingaben angezeigt werden. Ich habe auch ein Beispiel, das zeigt, wie Sie alle Fehlermeldungen in einer Liste oben in Formularen anzeigen können.
Zusätzlich zum Polyfüllen der API für die Gültigkeitsprüfung von Einschränkungen bietet H5F auch Klassen zum Nachahmen von :-moz-ui-valid
und :-moz-ui-invalid
. Standardmäßig sind valid
und error
können diese Klassen angepasst werden, indem ein zweiter Parameter an übergeben wird H5F.setup
.
H5F . setup ( document . getElementById ( 'foo' ), { validClass : 'valid' , invalidClass : 'invalid' });
Weitere Informationen zu H5F finden Sie auf Github .
Fazit
Mit den Integritätsregel-Validierungs-APIs von HTML5 können Sie Formulare schnell clientseitig validieren und gleichzeitig eine JavaScript-API und CSS-Hooks zur Anpassung bereitstellen.Während es noch einige Probleme mit den Implementierungen und alten Browsern gibt, können Sie diese APIs mit einer guten Polyfill oder einem guten serverseitigen Fallback heute in Ihren Formularen verwenden.