API di Validazione dei Vincoli JavaScript
Scopri l'API di Validazione dei Vincoli HTML5 in JavaScript: checkValidity, reportValidity, setCustomValidity, l'oggetto ValidityState, messaggi di errore personalizzati, pattern e validazione in tempo reale dei form.
JavaScript è un linguaggio fondamentale per lo sviluppo web, che consente contenuti dinamici e interazioni avanzate con l'utente. Un aspetto critico di JavaScript nei form web è l'API di Validazione dei Vincoli HTML5. Questa guida esplora l'API in profondità — i suoi metodi, l'oggetto ValidityState e come costruire messaggi personalizzati e feedback in tempo reale — con esempi pratici per sviluppatori sia principianti che esperti.
Questa pagina si basa su come lavorare con i form nel DOM e sull'evento e metodo submit. Se hai bisogno di leggere o inviare i dati del form dopo la validazione, consulta proprietà e metodi dei form e FormData.
Introduzione all'API di Validazione dei Vincoli HTML5
L'API di Validazione dei Vincoli HTML5 fornisce la validazione nativa lato client degli elementi dei form, intercettando gli errori prima che il form venga inviato. I vincoli vengono dichiarati direttamente nell'HTML tramite attributi come required, type="email", min, max, minlength, maxlength, step e pattern. Il browser li applica automaticamente e li espone a JavaScript in modo da poter personalizzare l'esperienza.
La validazione lato client rende i form più reattivi e riduce i round-trip non necessari verso il server. Non è tuttavia un confine di sicurezza — un utente può aggirarla del tutto disabilitando JavaScript o costruendo una propria richiesta. Validare sempre di nuovo sul server.
La superficie dell'API di Validazione dei Vincoli
Ogni elemento associato ai form (<input>, <textarea>, <select>, <button>, <fieldset> e lo stesso <form>) espone lo stesso piccolo insieme di membri.
Metodi
element.checkValidity()— restituiscetruese l'elemento soddisfa tutti i suoi vincoli, altrimentifalse. In caso di fallimento, genera anche un eventoinvalidsull'elemento.element.reportValidity()— comecheckValidity(), ma visualizza inoltre il fumetto di errore nativo del browser per il primo campo non valido. Utile quando si desidera l'interfaccia nativa senza un messaggio personalizzato.element.setCustomValidity(message)— imposta una stringa di errore personalizzata. Una stringa non vuota segna l'elemento come non valido; una stringa vuota ('') cancella l'errore personalizzato e consente all'elemento di essere valido di nuovo.form.checkValidity()/form.reportValidity()— validano tutti i controlli nel form in una sola volta.
Proprietà
element.validity— un oggettoValidityStatedi sola lettura che descrive perché il campo non è valido.element.validationMessage— il messaggio localizzato che il browser mostrerebbe per lo stato non valido corrente (vuoto quando valido).element.willValidate—truese l'elemento verrà controllato durante la validazione (i campi disabilitati ereadonlyvengono saltati).
L'oggetto ValidityState
element.validity espone un boolean per ogni tipo di errore, più valid:
| Proprietà | true quando… |
|---|---|
valueMissing | un campo required è vuoto |
typeMismatch | il valore è del tipo sbagliato (es. un type="email" malformato) |
patternMismatch | il valore non corrisponde all'attributo pattern |
tooShort / tooLong | il valore è più corto/lungo di minlength/maxlength |
rangeUnderflow / rangeOverflow | un numero/data è sotto min o sopra max |
stepMismatch | il valore non rispetta l'incremento step |
customError | a setCustomValidity() è stato passato un messaggio non vuoto |
valid | il campo supera tutti i vincoli |
Ispezionare questi flag consente di adattare il messaggio al problema esatto:
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
}Configurare la Prima Validazione
Prima di addentrarsi in regole complesse, inizia dalle basi: verificare che un campo required non sia vuoto.
Aggiungere l'attributo novalidate a un form disabilita l'interfaccia di validazione predefinita del browser. L'API di Validazione dei Vincoli continua a funzionare in JavaScript — checkValidity() e validity rimangono accurati — quindi è possibile costruire un feedback personalizzato sopprimendo i fumetti nativi.
<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>Questo frammento di codice dimostra la configurazione di base in cui il controllo input.checkValidity() viene usato per rendere obbligatorio un campo. Il form mostrerà un messaggio di errore se il campo username viene lasciato vuoto.
Implementare Messaggi di Validazione Personalizzati
Andando oltre i messaggi di avviso predefiniti del browser, puoi creare un'esperienza utente più integrata mostrando messaggi di errore personalizzati all'interno del layout HTML. Ecco come implementarlo:
Tieni presente che la validazione email predefinita di HTML5 potrebbe non richiedere un dominio di primo livello, permettendo a input come w3docs@aol di risultare validi. Per garantire che gli indirizzi email includano un dominio, abbiamo aggiunto un pattern più restrittivo .+@.+\..+ al campo email. Questa regex richiede almeno un punto dopo il simbolo @, avvicinandosi maggiormente ai formati email reali. (Per conoscere la sintassi regex dietro i pattern, consulta ancore per l'inizio e la fine della stringa.)
<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>Questo codice migliora l'esperienza utente fornendo un feedback immediato e inline sulla validità dell'input email.
Migliorare le Validazioni del Form con i Pattern
A volte sono necessarie validazioni più specifiche, come verificare che l'input sia conforme a un determinato pattern. Questo è comunemente usato per numeri di telefono, codici postali e campi simili. L'attributo pattern è implicitamente ancorato — l'intero valore deve corrispondere — quindi [0-9]{3}-[0-9]{3}-[0-9]{4} accetta 123-456-7890 ma rifiuta 1234567890.
<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>Questo esempio usa l'attributo pattern per specificare che il numero di telefono deve corrispondere a un formato specifico, migliorando la qualità dei dati raccolti tramite il form.
Validazione in tempo reale con l'oggetto ValidityState
Attendere fino all'invio può sembrare lento. Ascoltando l'evento input e leggendo i flag di validity, puoi fornire feedback mentre l'utente digita e costruire un messaggio per l'errore esatto:
<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>Qui valueMissing e patternMismatch provengono direttamente dall'oggetto ValidityState, quindi un singolo gestore riporta la ragione precisa senza dover reimplementare manualmente le regole.
Combinare regole dichiarative e personalizzate
Alcuni controlli — come "le password devono corrispondere" — non possono essere espressi con attributi HTML. Usa setCustomValidity() per integrarli nella stessa pipeline di validazione:
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
}
});Poiché l'errore personalizzato partecipa a checkValidity(), il gestore di submit del form non necessita di alcun caso speciale — il campo non corrispondente viene semplicemente segnalato come non valido come qualsiasi altro.
Conclusione
L'API di Validazione dei Vincoli HTML5 è uno strumento potente per gli sviluppatori web che desiderano implementare la validazione lato client dei form. Non solo migliora l'esperienza utente fornendo feedback immediato, ma riduce anche il carico sul server. Seguendo gli esempi forniti in questa guida, puoi creare form web più robusti, efficienti e facili da usare. Per il feedback in tempo reale, considera di ascoltare gli eventi input o change insieme al gestore di submit.