Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

HTML-Formularvalidierung und die Constraint Validation API verwenden

Das Erstellen von Webformularen war schon immer eine komplexe Aufgabe. Das Formular selbst mit Markup zu versehen ist einfach. Schwieriger ist es, zu prüfen, ob jedes Feld einen gültigen und stimmigen Wert enthält. Auch die Nutzer über ein Problem zu informieren, kann aufwendig sein. HTML5 führte neue Mechanismen für Formulare ein: neue semantische Typen für das Element <input> und die Constraint Validation, die die Prüfung von Formularinhalten auf der Client-Seite erleichtert. Grundlegende, gängige Bedingungen lassen sich ohne JavaScript prüfen, indem neue Attribute gesetzt werden. Komplexere Bedingungen können mit der Constraint Validation API geprüft werden.

Eine grundlegende Einführung in diese Konzepte mit Beispielen finden Sie im Tutorial zur Formularvalidierung.

Hinweis: Die HTML-Constraint-Validation macht eine Validierung auf der Server-Seite nicht überflüssig. Auch wenn mit deutlich weniger ungültigen Formularanfragen zu rechnen ist, können solche Anfragen weiterhin auf verschiedene Weise gesendet werden:

  • Durch Ändern des HTML mit den Entwicklertools des Browsers.
  • Durch manuelles Erstellen einer HTTP-Anfrage ohne Verwendung des Formulars.
  • Durch programmgesteuertes Eintragen von Inhalten in das Formular (bestimmte Validierungsprüfungen werden nur bei Nutzereingaben ausgeführt, nicht aber, wenn Sie den Wert eines Formularfelds mit JavaScript setzen).

Validieren Sie Formulardaten daher immer auch auf der Server-Seite, und zwar entsprechend der Validierung auf der Client-Seite.

Intrinsische und grundlegende Bedingungen

In HTML werden grundlegende Bedingungen auf zwei Arten festgelegt:

  • Durch Auswahl des semantisch am besten geeigneten Werts für das Attribut type des Elements <input>. Die Auswahl des Typs email legt beispielsweise automatisch eine Bedingung fest, die prüft, ob der Wert eine gültige E-Mail-Adresse ist.
  • Durch Setzen von Werten für validierungsbezogene Attribute. So lassen sich grundlegende Bedingungen ohne JavaScript beschreiben.

Semantische Input-Typen

Für das Attribut type gelten folgende intrinsische Bedingungen:

Input-Typ Beschreibung der Bedingung Zugehöriger Validierungsfehler
<input type="URL"> Der Wert muss eine absolute URL gemäß dem URL Living Standard sein. TypeMismatch-Validierungsfehler
<input type="email"> Der Wert muss eine syntaktisch gültige E-Mail-Adresse sein. Diese hat im Allgemeinen das Format username@hostname.tld, kann aber auch lokal sein, etwa username@hostname. TypeMismatch-Validierungsfehler

Wenn beim Input-Typ email das Attribut multiple gesetzt ist, können mehrere Werte als kommagetrennte Liste angegeben werden. Erfüllt einer der Werte in der Liste die hier beschriebene Bedingung nicht, wird der Validierungsfehler Type mismatch ausgelöst.

Beachten Sie, dass die meisten Input-Typen keine intrinsischen Bedingungen haben: Einige sind von der Constraint Validation ausgeschlossen, andere verfügen über einen Bereinigungsalgorithmus, der ungültige Werte in einen gültigen Standardwert umwandelt.

Validierungsbezogene Attribute

Zusätzlich zum oben beschriebenen Attribut type werden die folgenden Attribute verwendet, um grundlegende Bedingungen zu beschreiben:

Attribut Input-Typen, die das Attribut unterstützen Mögliche Werte Beschreibung der Bedingung Zugehöriger Validierungsfehler
pattern text, search, url, tel, email, password Ein regulärer JavaScript-Ausdruck (kompiliert mit deaktivierten Flags global, ignoreCase und multiline) Der Wert muss dem Muster entsprechen. patternMismatch-Validierungsfehler
min range, number Eine gültige Zahl Der eingegebene Wert muss größer oder gleich dem Attributwert sein. rangeUnderflow-Validierungsfehler
date, month, week Ein gültiges Datum
datetime-local, time Ein gültiges Datum mit Uhrzeit
max range, number Eine gültige Zahl Der eingegebene Wert muss kleiner oder gleich dem Attributwert sein. rangeOverflow-Validierungsfehler
date, month, week Ein gültiges Datum
datetime-local, time Ein gültiges Datum mit Uhrzeit
required text, search, url, tel, email, password, date, datetime-local, month, week, time, number, checkbox, radio, file; außerdem bei den Elementen <select> und <textarea> Keiner, da es sich um ein boolesches Attribut handelt: Ist es vorhanden, bedeutet dies true, andernfalls false. Wenn das Attribut gesetzt ist, muss ein Wert vorhanden sein. valueMissing-Validierungsfehler
step date Eine ganzzahlige Anzahl von Tagen Sofern die Schrittweite nicht auf das Literal any gesetzt ist, muss der Wert min plus einem ganzzahligen Vielfachen der Schrittweite entsprechen. stepMismatch-Validierungsfehler
month Eine ganzzahlige Anzahl von Monaten
week Eine ganzzahlige Anzahl von Wochen
datetime-local, time Eine ganzzahlige Anzahl von Sekunden
range, number Eine Ganzzahl
minlength text, search, url, tel, email, password; außerdem beim Element <textarea> Eine ganzzahlige Länge Wenn der Wert nicht leer ist, darf die Anzahl der Zeichen (Codepunkte) nicht kleiner als der Attributwert sein. Bei <textarea> werden alle Zeilenumbrüche zu einem einzelnen Zeichen normalisiert (statt zu CRLF-Paaren). tooShort-Validierungsfehler
maxlength text, search, url, tel, email, password; außerdem beim Element <textarea> Eine ganzzahlige Länge Die Anzahl der Zeichen (Codepunkte) darf den Attributwert nicht überschreiten. tooLong-Validierungsfehler

Ablauf der Constraint Validation

Die Constraint Validation wird mithilfe der Constraint Validation API entweder für ein einzelnes Formularelement oder für das gesamte Formular über das Element <form> ausgeführt. Dafür gibt es folgende Möglichkeiten:

  • Durch Aufruf der Methode checkValidity() oder reportValidity() einer formularbezogenen DOM-Schnittstelle (HTMLInputElement, HTMLSelectElement, HTMLButtonElement, HTMLOutputElement oder HTMLTextAreaElement). Dabei werden nur die Bedingungen für dieses Element geprüft, sodass ein Skript das Ergebnis abrufen kann. Die Methode checkValidity() gibt einen booleschen Wert zurück, der angibt, ob der Wert des Elements seine Bedingungen erfüllt. (Dies geschieht normalerweise durch den User-Agent, wenn er bestimmt, welche der CSS-Pseudoklassen :valid oder :invalid zutrifft.) Die Methode reportValidity() hingegen meldet den Nutzern Verstöße gegen die Bedingungen.
  • Durch Aufruf der Methode checkValidity() oder reportValidity() der Schnittstelle HTMLFormElement.
  • Durch Absenden des Formulars.

Der Aufruf von checkValidity() wird als statische Validierung der Bedingungen bezeichnet. Der Aufruf von reportValidity() oder das Absenden des Formulars wird als interaktive Validierung bezeichnet.

Hinweis:

  • Wenn das Attribut novalidate für das Element <form> gesetzt ist, findet keine interaktive Validierung der Bedingungen statt.
  • Ein Aufruf der Methode submit() der Schnittstelle HTMLFormElement löst keine Constraint Validation aus. Anders ausgedrückt: Diese Methode sendet die Formulardaten auch dann an den Server, wenn sie die Bedingungen nicht erfüllen. Rufen Sie stattdessen die Methode click() auf einem Submit-Button auf.
  • Die Bedingungen minlength und maxlength werden nur bei Nutzereingaben geprüft. Wird ein Wert programmgesteuert gesetzt, findet die Prüfung auch dann nicht statt, wenn checkValidity() oder reportValidity() ausdrücklich aufgerufen wird.

Komplexe Bedingungen mit der Constraint Validation API

Mit JavaScript und der Constraint Validation API können komplexere Bedingungen implementiert werden, beispielsweise Bedingungen, die mehrere Felder miteinander verknüpfen oder komplexe Berechnungen erfordern.

Grundsätzlich wird bei einem Ereignis eines Formularfelds (etwa onchange) JavaScript ausgeführt, um zu bestimmen, ob eine Bedingung verletzt ist. Anschließend wird mit der Methode field.setCustomValidity() das Ergebnis der Validierung festgelegt: Ein leerer String bedeutet, dass die Bedingung erfüllt ist. Jeder andere String bedeutet, dass ein Fehler vorliegt, und dient als Fehlermeldung für die Nutzer.

Bedingung für mehrere Felder: Postleitzahlvalidierung

Das Format von Postleitzahlen unterscheidet sich von Land zu Land. In vielen Ländern ist ein optionales Präfix mit dem Ländercode zulässig (etwa D- in Deutschland, F- in Frankreich und CH- in der Schweiz). In manchen Ländern bestehen Postleitzahlen nur aus einer festen Anzahl von Ziffern. Andere Länder wie das Vereinigte Königreich verwenden komplexere Formate, bei denen an bestimmten Stellen Buchstaben zulässig sind.

Hinweis: Dies ist keine umfassende Bibliothek zur Postleitzahlvalidierung, sondern eine Veranschaulichung der grundlegenden Konzepte.

Als Beispiel fügen wir einem Formular ein Skript hinzu, das die Bedingungen prüft:

html
<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>

Dadurch wird das folgende Formular angezeigt:

Zuerst schreiben wir eine Funktion, die die Bedingung selbst prüft:

js
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]);
  }
}

Anschließend verknüpfen wir sie mit dem Ereignis change für <select> und dem Ereignis input für <input>:

js
countrySelect.addEventListener("change", checkPostalCode);
postalCodeField.addEventListener("input", checkPostalCode);

Dateigröße vor dem Upload begrenzen

Eine weitere häufige Bedingung ist die Begrenzung der Größe einer hochzuladenden Datei. Um dies auf der Client-Seite zu prüfen, bevor die Datei an den Server übertragen wird, muss die Constraint Validation API – insbesondere die Methode field.setCustomValidity() – mit einer weiteren JavaScript-API kombiniert werden, hier der File API.

Hier ist der HTML-Teil:

html
<label for="fs">Select a file smaller than 75 kB: </label>
<input type="file" id="fs" />

Damit wird Folgendes angezeigt:

Das JavaScript liest die ausgewählte Datei, ermittelt ihre Größe mit der Methode File.size(), vergleicht sie mit dem fest codierten Grenzwert und teilt dem Browser über die Constraint Validation API mit, ob die Bedingung verletzt ist:

js
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("");
}

Abschließend verknüpfen wir die Methode mit dem passenden Ereignis:

js
fs.addEventListener("change", checkFileSize);

Visuelle Gestaltung der Constraint Validation

Webentwickler möchten nicht nur Bedingungen festlegen, sondern auch steuern, welche Meldungen den Nutzern angezeigt werden und wie diese gestaltet sind.

Darstellung von Elementen steuern

Die Darstellung von Elementen kann über CSS-Pseudoklassen gesteuert werden.

CSS-Pseudoklassen :required und :optional

Mit den Pseudoklassen :required und :optional lassen sich Selektoren schreiben, die Formularelemente mit beziehungsweise ohne das Attribut required auswählen.

CSS-Pseudoklasse :placeholder-shown

Siehe :placeholder-shown.

CSS-Pseudoklassen :valid und :invalid

Die Pseudoklassen :valid und :invalid kennzeichnen <input>-Elemente, deren Inhalt entsprechend dem eingestellten Input-Typ gültig beziehungsweise ungültig ist. Mit diesen Klassen lassen sich gültige und ungültige Formularelemente gestalten, damit korrekt und falsch formatierte Eingaben leichter zu erkennen sind.

Text von Validierungsfehlermeldungen steuern

Die folgenden Möglichkeiten helfen dabei, den Text einer Validierungsfehlermeldung zu steuern:

  • Die Methode setCustomValidity(message) für die folgenden Elemente:

    • <fieldset>. Hinweis: Das Festlegen einer benutzerdefinierten Validierungsfehlermeldung für fieldset-Elemente verhindert in den meisten Browsern nicht, dass das Formular abgesendet wird.
    • <input>
    • <output>
    • <select>
    • Submit-Buttons (erstellt entweder mit einem Element <button> vom Typ submit oder mit einem input-Element vom Typ submit). Andere Button-Typen nehmen nicht an der Constraint Validation teil.
    • <textarea>
  • Die Schnittstelle ValidityState beschreibt das Objekt, das von der Eigenschaft validity der oben aufgeführten Elementtypen zurückgegeben wird. Sie bildet verschiedene Gründe ab, aus denen ein eingegebener Wert ungültig sein kann. So lässt sich nachvollziehen, warum der Wert eines Elements die Validierung nicht besteht.