JavaScript Constraint Validation API
Lerne die HTML5 Constraint Validation API in JavaScript: checkValidity, reportValidity, setCustomValidity, das ValidityState-Objekt, benutzerdefinierte Fehlermeldungen, Musterabgleich und Echtzeit-Formularvalidierung.
JavaScript ist eine unverzichtbare Sprache für die Webentwicklung, die dynamische Inhalte und verbesserte Benutzerinteraktionen ermöglicht. Ein zentraler Aspekt von JavaScript in Webformularen ist die HTML5 Constraint Validation API. Dieser Leitfaden erklärt die API ausführlich — ihre Methoden, das ValidityState-Objekt und wie man benutzerdefinierte Meldungen sowie Echtzeit-Feedback erstellt — mit praxisnahen Beispielen für Anfänger und erfahrene Entwickler gleichermaßen.
Diese Seite baut auf der Arbeit mit Formularen im DOM und dem Submit-Ereignis und der Submit-Methode auf. Wenn du die Formulardaten nach der Validierung lesen oder senden möchtest, siehe Formulareigenschaften und -methoden und FormData.
Einführung in die HTML5 Constraint Validation API
Die HTML5 Constraint Validation API bietet eine native clientseitige Validierung von Formularelementen und erkennt Fehler, bevor das Formular abgeschickt wird. Einschränkungen werden direkt in HTML über Attribute wie required, type="email", min, max, minlength, maxlength, step und pattern deklariert. Der Browser setzt sie dann automatisch durch und stellt sie JavaScript zur Verfügung, damit du das Verhalten anpassen kannst.
Clientseitige Validierung lässt Formulare reaktionsschnell wirken und reduziert unnötige Serveranfragen. Sie ist jedoch keine Sicherheitsgrenze — ein Benutzer kann sie vollständig umgehen, indem er JavaScript deaktiviert oder eigene Anfragen erstellt. Führe die Validierung immer auch serverseitig durch.
Die Oberfläche der Constraint Validation API
Jedes formularbezogene Element (<input>, <textarea>, <select>, <button>, <fieldset> und das <form>-Element selbst) stellt denselben kleinen Satz von Mitgliedern bereit.
Methoden
element.checkValidity()— gibttruezurück, wenn das Element alle seine Einschränkungen erfüllt, andernfallsfalse. Bei einem Fehler wird außerdem eininvalid-Ereignis auf dem Element ausgelöst.element.reportValidity()— wiecheckValidity(), zeigt aber zusätzlich die native Fehlermeldung des Browsers für das erste ungültige Feld an. Nützlich, wenn du die native Benutzeroberfläche ohne eine eigene Meldung nutzen möchtest.element.setCustomValidity(message)— setzt eine benutzerdefinierte Fehlermeldung. Ein nicht leerer string markiert das Element als ungültig; ein leerer string ('') löscht den benutzerdefinierten Fehler und ermöglicht es dem Element, wieder gültig zu sein.form.checkValidity()/form.reportValidity()— validiert alle Steuerelemente im Formular auf einmal.
Eigenschaften
element.validity— ein schreibgeschütztesValidityState-Objekt, das beschreibt, warum das Feld ungültig ist.element.validationMessage— die lokalisierte Meldung, die der Browser für den aktuellen ungültigen Zustand anzeigen würde (leer, wenn gültig).element.willValidate—true, wenn das Element bei der Validierung geprüft wird (deaktivierte undreadonly-Felder werden übersprungen).
Das ValidityState-Objekt
element.validity stellt einen boolean für jede Art von Fehler bereit, plus valid:
| Eigenschaft | true wenn… |
|---|---|
valueMissing | ein required-Feld leer ist |
typeMismatch | der Wert den falschen Typ hat (z. B. ein ungültiges type="email") |
patternMismatch | der Wert nicht mit dem pattern-Attribut übereinstimmt |
tooShort / tooLong | der Wert kürzer/länger als minlength/maxlength ist |
rangeUnderflow / rangeOverflow | eine Zahl/ein Datum unter min oder über max liegt |
stepMismatch | der Wert nicht dem step-Inkrement entspricht |
customError | setCustomValidity() eine nicht leere Meldung übergeben wurde |
valid | das Feld alle Einschränkungen erfüllt |
Das Prüfen dieser Flags ermöglicht es dir, die Meldung an das genaue Problem anzupassen:
const input = document.querySelector('#age');
const v = input.validity;
if (v.valueMissing) {
input.setCustomValidity('Age is required.');
} else if (v.rangeUnderflow) {
input.setCustomValidity('You must be at least 18.');
} else {
input.setCustomValidity(''); // clears the custom error
}Deine erste Validierung einrichten
Bevor du dich in komplexe Regeln stürzt, beginne mit den Grundlagen: Überprüfe, ob ein required-Feld nicht leer ist.
Das Hinzufügen des novalidate-Attributs zu einem Formular deaktiviert die Standard-Validierungs-UI des Browsers. Die Constraint Validation API funktioniert in JavaScript weiterhin — checkValidity() und validity bleiben korrekt — sodass du dein eigenes Feedback erstellen kannst, ohne die nativen Sprechblasen anzuzeigen.
<form id="registrationForm" novalidate>
<label for="username">Username:</label>
<input type="text" id="username" required />
<button type="submit">Register</button>
<span id="usernameError" style="color: red;"></span>
<span id="registerSuccess" style="color: green; display: none;">Registration successful!</span>
</form>
<script>
document.getElementById('registrationForm').addEventListener('submit', function(event) {
event.preventDefault();
const input = document.getElementById('username');
const usernameError = document.getElementById('usernameError');
const registerSuccess = document.getElementById('registerSuccess');
if (!input.checkValidity()) {
usernameError.textContent = 'Username is required.';
registerSuccess.style.display = 'none'; // Hide success message if visible
} else {
usernameError.textContent = ''; // Clear error message
registerSuccess.textContent = 'Registration successful!';
registerSuccess.style.display = 'block'; // Show success message
input.value = ''; // Reset the username input
}
});
</script>Dieses Code-Beispiel zeigt die grundlegende Einrichtung, bei der die input.checkValidity()-Prüfung verwendet wird, um ein Feld als Pflichtfeld durchzusetzen. Das Formular zeigt eine Fehlermeldung an, wenn das Benutzernamefeld leer gelassen wird.
Benutzerdefinierte Validierungsmeldungen implementieren
Über die Standard-Fehlermeldungen des Browsers hinaus kannst du eine besser integrierte Benutzererfahrung schaffen, indem du benutzerdefinierte Fehlermeldungen direkt im HTML-Layout anzeigst. So kannst du das umsetzen:
Beachte, dass die Standard-HTML5-E-Mail-Validierung möglicherweise keine Top-Level-Domain erfordert, sodass Eingaben wie w3docs@aol als gültig akzeptiert werden können. Um sicherzustellen, dass E-Mail-Adressen eine Domain enthalten, haben wir dem E-Mail-Eingabefeld ein strengeres Muster .+@.+\..+ hinzugefügt. Dieser reguläre Ausdruck erfordert mindestens einen Punkt nach dem @-Symbol und entspricht damit realen E-Mail-Formaten besser. (Um die Regex-Syntax hinter Mustern zu erlernen, siehe Anker für Zeichenkettenanfang und -ende.)
<form id="contactForm" novalidate>
<label for="email">Email:</label>
<input type="email" id="email" pattern=".+@.+\..+" required />
<button type="submit">Submit</button>
<span id="emailError" style="color: red"></span>
<span id="successMessage" style="color: green; display: none;">Submission successful!</span>
</form>
<script>
document.getElementById("contactForm").addEventListener("submit", function (event) {
event.preventDefault(); // Prevent default form submission
const email = document.getElementById("email");
const errorMessage = document.getElementById("emailError");
const successMessage = document.getElementById("successMessage");
if (!email.checkValidity()) {
errorMessage.textContent = "Please enter a valid email address, including a domain."; // Display custom error message
successMessage.style.display = "none"; // Hide success message if visible
} else {
errorMessage.textContent = ""; // Clear the error message
successMessage.textContent = "Submission successful!";
successMessage.style.display = "block"; // Show success message
email.value = ""; // Reset the email input
}
});
</script>Dieser Code verbessert die Benutzererfahrung, indem er unmittelbares, direkt eingebettetes Feedback zur Gültigkeit der E-Mail-Eingabe gibt.
Formularvalidierungen mit Mustern erweitern
Manchmal sind spezifischere Validierungen erforderlich, beispielsweise um zu überprüfen, ob eine Eingabe einem bestimmten Muster entspricht. Dies wird häufig für Telefonnummern, Postleitzahlen und ähnliche Felder verwendet. Das pattern-Attribut ist implizit verankert — der gesamte Wert muss übereinstimmen — daher akzeptiert [0-9]{3}-[0-9]{3}-[0-9]{4} den Wert 123-456-7890, lehnt aber 1234567890 ab.
<form id="signupForm" novalidate>
<label for="phone">Phone (XXX-XXX-XXXX):</label>
<input type="tel" id="phone" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" required />
<button type="submit">Sign Up</button>
<span id="phoneError" style="color:red;"></span>
<span id="successMessage" style="color:green; display:none;">Submission successful!</span>
</form>
<script>
document.getElementById('signupForm').addEventListener('submit', function(event) {
const phone = document.getElementById('phone');
const phoneError = document.getElementById('phoneError');
const successMessage = document.getElementById('successMessage');
if (!phone.checkValidity()) {
phoneError.textContent = 'Please enter a phone number in the format XXX-XXX-XXXX.';
successMessage.style.display = 'none'; // Hide success message if present
} else {
phoneError.textContent = '';
phone.value = ''; // Reset the input field
successMessage.textContent = 'Submission successful!';
successMessage.style.display = 'block'; // Show success message
}
});
</script>Dieses Beispiel verwendet das pattern-Attribut, um festzulegen, dass die Telefonnummer einem bestimmten Format entsprechen muss, was die Qualität der über das Formular erfassten Daten verbessert.
Echtzeit-Validierung mit dem ValidityState-Objekt
Bis zum Absenden zu warten kann sich träge anfühlen. Indem du das input-Ereignis abhorchst und die validity-Flags ausliest, kannst du während der Eingabe Feedback geben und eine Meldung für den genauen Fehler formulieren:
<form id="profileForm" novalidate>
<label for="user">Username (3-12 letters/digits):</label>
<input type="text" id="user" pattern="[A-Za-z0-9]{3,12}" required />
<span id="userMsg" style="color:red;"></span>
</form>
<script>
const user = document.getElementById('user');
const msg = document.getElementById('userMsg');
user.addEventListener('input', function () {
const v = user.validity;
if (v.valueMissing) {
msg.textContent = 'Username is required.';
} else if (v.patternMismatch) {
msg.textContent = 'Use 3-12 letters or digits only.';
} else {
msg.textContent = ''; // valid
}
});
</script>Hier stammen valueMissing und patternMismatch direkt aus dem ValidityState-Objekt, sodass ein einziger Handler den genauen Grund meldet, ohne die Regeln manuell neu implementieren zu müssen.
Deklarative und benutzerdefinierte Regeln kombinieren
Einige Prüfungen — wie „Passwörter müssen übereinstimmen" — lassen sich nicht mit HTML-Attributen ausdrücken. Verwende setCustomValidity(), um sie in dieselbe Validierungs-Pipeline einzubinden:
const password = document.getElementById('password');
const confirm = document.getElementById('confirm');
confirm.addEventListener('input', function () {
if (confirm.value !== password.value) {
confirm.setCustomValidity('Passwords do not match.');
} else {
confirm.setCustomValidity(''); // clear so the field becomes valid
}
});Da der benutzerdefinierte Fehler an checkValidity() beteiligt ist, benötigt der Submit-Handler des Formulars keinen Sonderfall — das nicht übereinstimmende Feld wird einfach wie jedes andere als ungültig gemeldet.
Fazit
Die HTML5 Constraint Validation API ist ein leistungsstarkes Werkzeug für Webentwickler, die clientseitige Formularvalidierung implementieren möchten. Sie verbessert nicht nur die Benutzererfahrung durch sofortiges Feedback, sondern entlastet auch den Server. Indem du den in diesem Leitfaden bereitgestellten Beispielen folgst, kannst du robustere, effizientere und benutzerfreundlichere Webformulare erstellen. Für Echtzeit-Feedback solltest du auch das Abhören von input- oder change-Ereignissen neben dem Submit-Handler in Betracht ziehen.