Verwendung der HTML-Formularvalidierung und der Constraint Validation API
Die Erstellung von Webformularen war schon immer eine komplexe Aufgabe. Während die Auszeichnung des Formulars selbst einfach ist, ist es schwierig zu überprüfen, ob jedes Feld einen gültigen und kohärenten Wert hat, und den Benutzer über das Problem zu informieren kann zur Herausforderung werden. HTML5 führte neue Mechanismen für Formulare ein: Es fügte neue semantische Typen für das <input>
-Element und die Constraint-Validierung hinzu, um die Überprüfung des Formularinhalts auf der Clientseite zu erleichtern. Grundlegende, übliche Einschränkungen können ohne den Einsatz von JavaScript durch das Setzen neuer Attribute überprüft werden; komplexere Einschränkungen können mithilfe der Constraint Validation API getestet werden.
Für eine grundlegende Einführung in diese Konzepte mit Beispielen, siehe das Formularvalidierungs-Tutorial.
Hinweis: Die HTML Constraint Validation ersetzt nicht die Notwendigkeit der Validierung auf der Serverseite. Auch wenn weitaus weniger ungültige Formularanforderungen zu erwarten sind, können ungültige dennoch auf viele Arten gesendet werden:
- Durch Ändern von HTML über die Entwicklertools des Browsers.
- Durch manuelles Erstellen einer HTTP-Anfrage ohne Verwendung des Formulars.
- Durch programmgesteuertes Schreiben von Inhalten in das Formular (bestimmte Constraint-Validierungen werden nur für Benutzereingaben ausgeführt und nicht, wenn Sie den Wert eines Formularfelds mithilfe von JavaScript setzen).
Daher sollten Sie Formulardaten immer auf der Serverseite validieren, konsistent mit dem, was auf der Clientseite gemacht wird.
Intrinsische und grundlegende Einschränkungen
In HTML werden grundlegende Einschränkungen auf zwei Arten deklariert:
- Durch die Wahl des semantisch geeignetsten Wertes für das
type
-Attribut des<input>
-Elements, z. B. führt die Auswahl des Typsemail
automatisch zu einer Einschränkung, die überprüft, ob der Wert eine gültige E-Mail-Adresse ist. - Durch das Setzen von Werten auf validierungsbezogene Attribute, wodurch grundlegende Einschränkungen ohne JavaScript beschrieben werden können.
Semantische Eingabetypen
Die intrinsischen Einschränkungen für das type
-Attribut sind:
Eingabetyp | Beschreibung der Einschränkung | Zugehöriger Verstoß |
---|---|---|
<input type="URL"> |
Der Wert muss eine absolute URL sein, wie im URL Living Standard definiert. | TypeMismatch Constraint-Verstoß |
<input type="email"> |
Der Wert muss eine syntaktisch korrekte E-Mail-Adresse sein, die im Allgemeinen das Format username@hostname.tld hat, aber auch lokal wie username@hostname sein kann. |
TypeMismatch Constraint-Verstoß |
Für beide dieser Eingabetypen, wenn das multiple
-Attribut gesetzt ist, können mehrere Werte als kommagetrennte Liste gesetzt werden. Wenn einer dieser Werte die hier beschriebene Bedingung nicht erfüllt, wird der Type mismatch Constraint-Verstoß ausgelöst.
Beachten Sie, dass die meisten Eingabetypen keine intrinsischen Einschränkungen haben, da einige von der Constraint-Validierung ausgeschlossen sind oder einen Bereinigungsalgorithmus haben, der falsche Werte in einen korrekten Standardwert umwandelt.
Validierungsbezogene Attribute
Zusätzlich zum oben beschriebenen type
-Attribut werden die folgenden Attribute verwendet, um grundlegende Einschränkungen zu beschreiben:
Attribut | Unterstützte Eingabetypen | Mögliche Werte | Beschreibung der Einschränkung | Zugehöriger Verstoß |
---|---|---|---|---|
pattern
|
text , search , url ,
tel , email , password
|
Ein
JavaScript-Regulärer Ausdruck
(kompiliert mit den global , ignoreCase , und multiline Flags deaktiviert)
|
Der Wert muss dem Muster entsprechen. |
patternMismatch
Constraint-Verstoß
|
min
|
range , number |
Eine gültige Zahl | Der Wert muss größer oder gleich dem Wert sein. |
rangeUnderflow
Constraint-Verstoß
|
date , month , week |
Ein gültiges Datum | |||
datetime-local , time
|
Ein gültiges Datum und Uhrzeit | |||
max
|
range , number |
Eine gültige Zahl | Der Wert muss kleiner oder gleich dem Wert sein. |
rangeOverflow
Constraint-Verstoß
|
date , month , week |
Ein gültiges Datum | |||
datetime-local , time
|
Ein gültiges Datum und Uhrzeit | |||
required
|
text , search , url ,
tel , email , password ,
date , datetime-local ,
month , week , time ,
number , checkbox , radio ,
file ; auch auf den <select> und
<textarea> Elementen
|
keine da es ein Boolean-Attribut ist: seine Existenz bedeutet wahr, seine Abwesenheit bedeutet falsch | Es muss ein Wert vorhanden sein (falls gesetzt). |
valueMissing
Constraint-Verstoß
|
step
|
date |
Eine ganze Zahl von Tagen |
Sofern der Schritt nicht auf das Literal any gesetzt ist, muss der Wert
min + ein ganzzahliges Vielfaches des Schritts sein.
|
stepMismatch
Constraint-Verstoß
|
month |
Eine ganze Zahl von Monaten | |||
week |
Eine ganze Zahl von Wochen | |||
datetime-local , time
|
Eine ganze Zahl von Sekunden | |||
range , number |
Eine ganze Zahl | |||
minlength
|
text , search , url ,
tel , email , password ; auch auf dem
<textarea> Element
|
Eine ganzzahlige Länge |
Die Anzahl der Zeichen (Codepunkte) darf nicht kleiner als der Wert
des Attributs sein, falls nicht leer. Alle neuen Zeilen werden für
<textarea> zu einem einzigen Zeichen normalisiert.
|
tooShort
Constraint-Verstoß
|
maxlength
|
text , search , url ,
tel , email , password ; auch auf dem
<textarea> Element
|
Eine ganzzahlige Länge | Die Anzahl der Zeichen (Codepunkte) darf den Wert des Attributs nicht überschreiten. |
tooLong
Constraint-Verstoß
|
Prozess der Constraint-Validierung
Die Constraint-Validierung wird entweder über die Constraint Validation API auf einem einzelnen Formularfeld oder auf Formularebene auf dem <form>
-Element selbst durchgeführt. Die Constraint-Validierung erfolgt auf folgende Weise:
- Durch einen Aufruf der
checkValidity()
oderreportValidity()
-Methode einer formularassoziierten DOM-Schnittstelle, (HTMLInputElement
,HTMLSelectElement
,HTMLButtonElement
,HTMLOutputElement
oderHTMLTextAreaElement
), die die Einschränkungen nur auf diesem Element auswertet und es einem Skript ermöglicht, diese Informationen zu erhalten. DiecheckValidity()
-Methode gibt ein Boolean zurück, das angibt, ob der Wert des Elements seine Einschränkungen besteht. (Dies wird normalerweise vom User-Agent getan, um zu bestimmen, welche der CSS-Pseudoklassen,:valid
oder:invalid
, Anwendung findet.) Im Gegensatz dazu meldet diereportValidity()
-Methode dem Benutzer etwaige Verstöße gegen die Einschränkungen. - Durch einen Aufruf der
checkValidity()
oderreportValidity()
-Methode auf derHTMLFormElement
-Schnittstelle. - Durch das Absenden des Formulars selbst.
Das Aufrufen von checkValidity()
wird als statische Validierung der Einschränkungen bezeichnet, während das Aufrufen von reportValidity()
oder das Absenden des Formulars als interaktive Validierung der Einschränkungen bezeichnet wird.
Hinweis:
- Wenn das
novalidate
-Attribut auf dem<form>
-Element gesetzt ist, erfolgt keine interaktive Validierung der Einschränkungen. - Der Aufruf der
submit()
-Methode auf derHTMLFormElement
-Schnittstelle löst keine Constraint-Validierung aus. Mit anderen Worten, diese Methode sendet die Formulardaten an den Server, selbst wenn sie die Einschränkungen nicht erfüllen. Rufen Sie stattdessen dieclick()
-Methode für eine Schaltfläche zum Absenden auf. - Die
minlength
- undmaxlength
-Einschränkungen werden nur bei benutzereingegebener Eingabe geprüft. Sie werden nicht überprüft, wenn ein Wert programmatisch gesetzt wird, selbst bei explizitem Aufruf voncheckValidity()
oderreportValidity()
.
Komplexe Einschränkungen mit der Constraint Validation API
Durch die Verwendung von JavaScript und der Constraint API ist es möglich, komplexere Einschränkungen zu implementieren, beispielsweise Einschränkungen, die mehrere Felder kombinieren, oder Einschränkungen, die komplexe Berechnungen beinhalten.
Grundsätzlich geht es darum, JavaScript bei einem Formularfeldevent (wie onchange) auszulösen, um zu berechnen, ob die Einschränkung verletzt wird, und dann die Methode field.setCustomValidity()
zu verwenden, um das Ergebnis der Validierung festzulegen: Ein leerer String bedeutet, dass die Einschränkung erfüllt ist, und ein anderer String bedeutet, dass ein Fehler vorliegt und dieser String die Fehlermeldung anzeigt, die dem Benutzer angezeigt werden soll.
Einschränkung, die mehrere Felder kombiniert: Validierung der Postleitzahl
Das Format der Postleitzahl variiert von Land zu Land. Viele Länder erlauben ein optionales Präfix mit dem Ländercode (wie D-
in Deutschland, F-
in Frankreich und CH-
in der Schweiz). Einige Länder verwenden nur eine feste Anzahl von Ziffern in Postleitzahlen, während andere, wie das Vereinigte Königreich, komplexere Formate haben, die Buchstaben an einigen spezifischen Positionen erlauben.
Hinweis: Dies ist keine umfassende Bibliothek zur Postleitzahlenvalidierung, sondern eine Demonstration der wichtigsten Konzepte.
Als Beispiel werden wir ein Skript hinzufügen, das die Constraint-Validierung für ein Formular überprüft:
<form>
<label for="postal-code">Postal Code: </label>
<input type="text" id="postal-code" />
<label for="country">Country: </label>
<select id="country">
<option value="ch">Switzerland</option>
<option value="fr">France</option>
<option value="de">Germany</option>
<option value="nl">The Netherlands</option>
</select>
<input type="submit" value="Validate" />
</form>
Dies zeigt das folgende Formular an:
Zuerst schreiben wir eine Funktion, die die Einschränkung selbst überprüft:
const countrySelect = document.getElementById("country");
const postalCodeField = document.getElementById("postal-code");
function checkPostalCode() {
// For each country, defines the pattern that the postal code has to follow
const constraints = {
ch: [
"^(CH-)?\\d{4}$",
"Swiss postal codes must have exactly 4 digits: e.g. CH-1950 or 1950",
],
fr: [
"^(F-)?\\d{5}$",
"French postal codes must have exactly 5 digits: e.g. F-75012 or 75012",
],
de: [
"^(D-)?\\d{5}$",
"German postal codes must have exactly 5 digits: e.g. D-12345 or 12345",
],
nl: [
"^(NL-)?\\d{4}\\s*([A-RT-Z][A-Z]|S[BCE-RT-Z])$",
"Dutch postal codes must have exactly 4 digits, followed by 2 letters except SA, SD and SS",
],
};
// Read the country id
const country = countrySelect.value;
// Build the constraint checker
const constraint = new RegExp(constraints[country][0], "");
console.log(constraint);
// Check it!
if (constraint.test(postalCodeField.value)) {
// The postal code follows the constraint, we use the ConstraintAPI to tell it
postalCodeField.setCustomValidity("");
} else {
// The postal code doesn't follow the constraint, we use the ConstraintAPI to
// give a message about the format required for this country
postalCodeField.setCustomValidity(constraints[country][1]);
}
}
Dann verknüpfen wir es mit dem change
-Ereignis für das <select>
und dem input
-Ereignis für das <input>
:
countrySelect.addEventListener("change", checkPostalCode);
postalCodeField.addEventListener("input", checkPostalCode);
Begrenzung der Dateigröße vor dem Hochladen
Eine weitere übliche Einschränkung besteht darin, die Größe einer hochzuladenden Datei zu begrenzen. Die Prüfung auf der Clientseite, bevor die Datei an den Server übertragen wird, erfordert die Kombination der Constraint Validation API, insbesondere der Methode field.setCustomValidity()
, mit einer anderen JavaScript-API, hier der File API.
Hier ist der HTML-Teil:
<label for="fs">Select a file smaller than 75 kB: </label>
<input type="file" id="fs" />
Dies zeigt:
Das JavaScript liest die ausgewählte Datei aus, verwendet die File.size()
-Methode, um ihre Größe zu ermitteln, vergleicht sie mit dem (hardcodierten) Limit und ruft die Constraint API auf, um den Browser zu informieren, wenn ein Verstoß vorliegt:
const fs = document.getElementById("fs");
function checkFileSize() {
const files = fs.files;
// If there is (at least) one file selected
if (files.length > 0) {
if (files[0].size > 75 * 1000) {
// Check the constraint
fs.setCustomValidity("The selected file must not be larger than 75 kB");
fs.reportValidity();
return;
}
}
// No custom constraint violation
fs.setCustomValidity("");
}
Schließlich verknüpfen wir die Methode mit dem richtigen Ereignis:
fs.addEventListener("change", checkFileSize);
Visuelles Styling der Constraint-Validierung
Neben dem Festlegen von Einschränkungen möchten Webentwickler steuern, welche Nachrichten den Benutzern angezeigt werden und wie sie gestaltet sind.
Steuerung des Erscheinungsbilds von Elementen
Das Erscheinungsbild von Elementen kann über CSS-Pseudoklassen gesteuert werden.
:required und :optional CSS-Pseudoklassen
Die :required
und :optional
Pseudoklassen ermöglichen das Schreiben von Selektoren, die Formularelemente ansprechen, die das required
-Attribut haben oder nicht.
:placeholder-shown CSS-Pseudoklasse
Siehe :placeholder-shown
.
:valid :invalid CSS-Pseudoklassen
Die :valid
und :invalid
Pseudoklassen werden verwendet, um <input>
-Elemente darzustellen, deren Inhalt gemäß der Typeinstellung des Inputs validiert bzw. nicht validiert. Diese Klassen erlauben es dem Benutzer, gültige oder ungültige Formularelemente zu gestalten, um es einfacher zu machen, Elemente zu identifizieren, die entweder korrekt oder inkorrekt formatiert sind.
Steuerung des Textes bei Constraint-Verstößen
Die folgenden Punkte können helfen, den Text bei Constraint-Verstößen zu steuern:
-
Die Methode
setCustomValidity(message)
auf den folgenden Elementen:<fieldset>
. Hinweis: Das Setzen einer benutzerdefinierten Gültigkeitsnachricht auf Fieldset-Elementen verhindert nicht die Formularübermittlung in den meisten Browsern.<input>
<output>
<select>
- Übermittlungsschaltflächen (erstellt entweder mit einem
<button>
-Element mit dem Typsubmit
oder eineminput
-Element mit dem submit-Typ. Andere Arten von Schaltflächen beteiligen sich nicht an der Constraint-Validierung.) <textarea>
-
Die
ValidityState
-Schnittstelle beschreibt das Objekt, das von dervalidity
-Eigenschaft der oben aufgeführten Elementtypen zurückgegeben wird. Es repräsentiert verschiedene Möglichkeiten, wie ein eingegebener Wert ungültig sein kann. Zusammen helfen sie zu erklären, warum der Wert eines Elements nicht gültig ist, falls er nicht validiert.