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 auszuzeichnen ist einfach. Schwieriger ist es, zu prüfen, ob jedes Feld einen gültigen und stimmigen Wert enthält. Auch die Nutzer über Probleme zu informieren, kann aufwendig sein. HTML5 führte neue Mechanismen für Formulare ein: neue semantische Typen für das <input>-Element und die Validierung von Einschränkungen, die das Prüfen von Formularinhalten auf der Clientseite erleichtert. Einfache, übliche Einschränkungen lassen sich ohne JavaScript durch Attribute prüfen; komplexere Einschränkungen können mit der Constraint Validation API getestet werden.

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

Hinweis: Die HTML-Validierung von Einschränkungen ersetzt nicht die Validierung auf der Serverseite. Auch wenn deutlich weniger ungültige Formularanfragen zu erwarten sind, können solche Anfragen weiterhin auf verschiedene Weise gesendet werden:

  • Durch Ändern des HTML-Codes mit den Entwicklertools des Browsers.
  • Durch manuelles Erstellen einer HTTP-Anfrage, ohne das Formular zu verwenden.
  • Durch programmgesteuertes Einfügen von Inhalten in das Formular (bestimmte Validierungen von Einschränkungen 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 Serverseite, und zwar nach denselben Regeln wie auf der Clientseite.

Intrinsische und grundlegende Einschränkungen

In HTML werden grundlegende Einschränkungen auf zwei Arten festgelegt:

  • Durch die Wahl des semantisch passendsten Werts für das Attribut type des <input>-Elements. Beispielsweise legt der Typ email automatisch eine Einschränkung fest, die prüft, ob der Wert eine gültige E-Mail-Adresse ist.
  • Durch das Setzen validierungsbezogener Attribute. Damit lassen sich grundlegende Einschränkungen ohne JavaScript beschreiben.

Semantische Eingabetypen

Für das Attribut type gelten folgende intrinsische Einschränkungen:

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

Wenn beim Eingabetyp email das Attribut multiple gesetzt ist, können mehrere Werte als kommagetrennte Liste angegeben werden. Erfüllt ein Wert in der Liste die hier beschriebene Bedingung nicht, wird die Einschränkung Type mismatch verletzt.

Beachten Sie, dass die meisten Eingabetypen keine intrinsischen Einschränkungen haben: Manche sind von der Validierung von Einschränkungen ausgeschlossen, andere verwenden einen Bereinigungsalgorithmus, der ungültige Werte in einen gültigen Standardwert umwandelt.

Validierungsbezogene Attribute

Neben dem oben beschriebenen Attribut type werden die folgenden Attribute verwendet, um grundlegende Einschränkungen zu beschreiben:

Attribut Eingabetypen, die das Attribut unterstützen Mögliche Werte Beschreibung der Einschränkung Zugehörige Verletzung
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. Verletzung der Einschränkung patternMismatch
min range, number Eine gültige Zahl Der Wert muss größer oder gleich dem Wert des Attributs sein. Verletzung der Einschränkung rangeUnderflow
date, month, week Ein gültiges Datum
datetime-local, time Ein gültiges Datum und eine gültige Uhrzeit
max range, number Eine gültige Zahl Der Wert muss kleiner oder gleich dem Wert des Attributs sein. Verletzung der Einschränkung rangeOverflow
date, month, week Ein gültiges Datum
datetime-local, time Ein gültiges Datum und eine gültige 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> Keine, 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. Verletzung der Einschränkung valueMissing
step date Eine ganze Anzahl von Tagen Sofern die Schrittweite nicht auf any gesetzt ist, muss der Wert min plus einem ganzzahligen Vielfachen der Schrittweite entsprechen. Verletzung der Einschränkung stepMismatch
month Eine ganze Anzahl von Monaten
week Eine ganze Anzahl von Wochen
datetime-local, time Eine ganze Anzahl von Sekunden
range, number Eine ganze Zahl
minlength text, search, url, tel, email, password; außerdem beim <textarea>-Element Eine ganzzahlige Länge Wenn der Wert nicht leer ist, darf die Anzahl der Zeichen (Codepoints) den Wert des Attributs nicht unterschreiten. Bei <textarea> werden alle Zeilenumbrüche zu einem einzelnen Zeichen normalisiert (anstelle eines CRLF-Paars). Verletzung der Einschränkung tooShort
maxlength text, search, url, tel, email, password; außerdem beim <textarea>-Element Eine ganzzahlige Länge Die Anzahl der Zeichen (Codepoints) darf den Wert des Attributs nicht überschreiten. Verletzung der Einschränkung tooLong

Ablauf der Validierung von Einschränkungen

Die Validierung von Einschränkungen erfolgt über die Constraint Validation API, entweder für ein einzelnes Formularelement oder für das gesamte Formular über das <form>-Element. Sie kann auf folgende Weise ausgeführt werden:

  • Durch Aufrufen der Methode checkValidity() oder reportValidity() einer formularbezogenen DOM-Schnittstelle (HTMLInputElement, HTMLSelectElement, HTMLButtonElement, HTMLOutputElement oder HTMLTextAreaElement). Dabei werden nur die Einschränkungen dieses Elements 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 Einschränkungen erfüllt. (Dies geschieht üblicherweise durch den User-Agent, wenn er bestimmt, welche der CSS-Pseudoklassen :valid oder :invalid zutrifft.) Die Methode reportValidity() hingegen meldet Nutzern alle Verletzungen von Einschränkungen.
  • Durch Aufrufen der Methode checkValidity() oder reportValidity() auf der Schnittstelle HTMLFormElement.
  • Durch Absenden des Formulars.

Das Aufrufen von checkValidity() wird als statische Validierung der Einschränkungen bezeichnet. Das Aufrufen von reportValidity() oder das Absenden des Formulars gilt dagegen als interaktive Validierung.

Hinweis:

  • Wenn das Attribut novalidate beim <form>-Element gesetzt ist, findet keine interaktive Validierung der Einschränkungen statt.
  • Das Aufrufen der Methode submit() auf der Schnittstelle HTMLFormElement löst keine Validierung der Einschränkungen aus. Die Methode sendet die Formulardaten also auch dann an den Server, wenn sie die Einschränkungen nicht erfüllen. Rufen Sie stattdessen die Methode click() einer Schaltfläche zum Absenden auf.
  • Die Einschränkungen minlength und maxlength werden nur bei Nutzereingaben geprüft. Wird ein Wert programmgesteuert gesetzt, werden sie auch dann nicht geprüft, wenn checkValidity() oder reportValidity() ausdrücklich aufgerufen wird.

Komplexe Einschränkungen mit der Constraint Validation API

Mit JavaScript und der Constraint Validation API lassen sich komplexere Einschränkungen umsetzen, beispielsweise solche, die mehrere Felder kombinieren oder komplexe Berechnungen erfordern.

Das Grundprinzip besteht darin, bei einem Ereignis eines Formularfelds (etwa onchange) JavaScript auszuführen, um zu prüfen, ob die Einschränkung verletzt ist. Anschließend wird das Ergebnis der Validierung mit der Methode field.setCustomValidity() festgelegt: Eine leere Zeichenfolge bedeutet, dass die Einschränkung erfüllt ist. Jede andere Zeichenfolge bedeutet, dass ein Fehler vorliegt, und dient als Fehlermeldung für die Nutzer.

Einschränkung über mehrere Felder: Postleitzahlen validieren

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, etwa das Vereinigte Königreich, verwenden komplexere Formate, bei denen an bestimmten Stellen Buchstaben erlaubt sind.

Hinweis: Dies ist keine umfassende Bibliothek zur Validierung von Postleitzahlen, sondern eine Demonstration der wichtigsten Konzepte.

Als Beispiel fügen wir einem Formular ein Skript hinzu, das die Einschränkungen 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:

Zunächst schreiben wir eine Funktion, die die Einschränkung 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 das <select>-Element und dem Ereignis input für das <input>-Element:

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

Dateigröße vor dem Hochladen begrenzen

Eine weitere häufige Einschränkung ist die maximale Größe einer hochzuladenden Datei. Um diese vor der Übertragung an den Server auf der Clientseite zu prüfen, 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" />

Das Ergebnis sieht so aus:

Das JavaScript liest die ausgewählte Datei, ermittelt ihre Größe mit der Methode File.size(), vergleicht sie mit dem fest im Code hinterlegten Grenzwert und informiert den Browser über die Constraint Validation API, falls die Einschränkung 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("");
}

Zum Schluss verknüpfen wir die Methode mit dem passenden Ereignis:

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

Visuelle Gestaltung der Validierung von Einschränkungen

Neben dem Festlegen von Einschränkungen möchten Webentwickler steuern, welche Meldungen Nutzern angezeigt werden und wie diese gestaltet sind.

Darstellung von Elementen steuern

Die Darstellung von Elementen lässt sich mit CSS-Pseudoklassen steuern.

CSS-Pseudoklassen :required und :optional

Mit den Pseudoklassen :required und :optional lassen sich Selektoren für Formularelemente schreiben, die das Attribut required haben beziehungsweise nicht haben.

CSS-Pseudoklasse :placeholder-shown

Siehe :placeholder-shown.

CSS-Pseudoklassen :valid und :invalid

Die Pseudoklassen :valid und :invalid kennzeichnen <input>-Elemente, deren Inhalt gemäß dem festgelegten Eingabetyp gültig beziehungsweise ungültig ist. Mit diesen Klassen können gültige und ungültige Formularelemente unterschiedlich gestaltet werden, damit korrekt und falsch formatierte Eingaben leichter zu erkennen sind.

Text von Meldungen zu verletzten Einschränkungen steuern

Mit den folgenden Möglichkeiten lässt sich der Text einer Meldung zu einer verletzten Einschränkung steuern:

  • Die Methode setCustomValidity(message) bei folgenden Elementen:

    • <fieldset>. Hinweis: Das Festlegen einer benutzerdefinierten Validierungsmeldung für fieldset-Elemente verhindert in den meisten Browsern nicht das Absenden des Formulars.
    • <input>
    • <output>
    • <select>
    • Schaltflächen zum Absenden (erstellt entweder mit einem <button>-Element vom Typ submit oder einem input-Element vom Typ submit). Andere Schaltflächentypen nehmen nicht an der Validierung von Einschränkungen teil.
    • <textarea>
  • Die Schnittstelle ValidityState beschreibt das Objekt, das die Eigenschaft validity der oben aufgeführten Elementtypen zurückgibt. Sie bildet die verschiedenen Gründe ab, aus denen ein eingegebener Wert ungültig sein kann. Dadurch lässt sich nachvollziehen, warum der Wert eines Elements die Validierung nicht besteht.