La Guida Completa ai Form HTML e alla Validazione dei Controlli

In questo articolo, esaminiamo i campi dei moduli HTML e le opzioni di convalida offerte da HTML5. Esamineremo anche come queste possano essere migliorate attraverso l’uso di CSS e JavaScript.

Che cos’è la Convalida per Vincoli?

Ogni campo del modulo ha uno scopo. E questo scopo è spesso regolato da vincoli — o le regole che governano cosa dovrebbe e non dovrebbe essere inserito in ogni campo del modulo. Ad esempio, un campo email richiederà un indirizzo email valido; un campo password potrebbe richiedere determinati tipi di caratteri e avere un numero minimo di caratteri richiesti; e un campo di testo potrebbe avere un limite su quanti caratteri possono essere inseriti.

I browser moderni hanno la capacità di verificare che questi vincoli siano rispettati dagli utenti e possono avvisarli quando quelle regole sono state violate. Questo è noto come convalida per vincoli.

Convalida lato client vs lato server

La maggior parte del codice JavaScript scritto nei primi anni del linguaggio si occupava della convalida dei moduli lato client. Ancora oggi, i sviluppatori dedicano molto tempo alla scrittura di funzioni per controllare i valori dei campi. È ancora necessario nei browser moderni? Probabilmente no. Nella maggior parte dei casi, dipende davvero da ciò che si sta cercando di fare.

Ma prima, ecco un grande avvertimento:

La convalida lato client è una comodità che può prevenire errori comuni nell’inserimento dei dati prima che un’app perda tempo e larghezza di banda inviando dati a un server. Non è un sostituto della convalida lato server!

Sempre sanificare i dati lato server. Non ogni richiesta arriverà da un browser. Anche quando lo fa, non c’è garanzia che il browser abbia validato i dati. Chiunque sappia come aprire gli strumenti per sviluppatori di un browser può anche bypassare il tuo amorevolmente curato HTML e JavaScript.

Campi Input HTML5

HTML offre:

Ma userai più spesso <input>:

<input type="text" name="username" />

L’attributo type imposta il tipo di controllo, e c’è una vasta scelta di opzioni:

type description
button a button with no default behavior
checkbox a check/tick box
color a color picker
date a date picker for the year, month, and day
datetime-local a date and time picker
email an email entry field
file a file picker
hidden a hidden field
image a button which displays the image defined by the src attribute
month a month and year picker
number a number entry field
password a password entry field with obscured text
radio a radio button
range a slider control
reset a button that resets all form inputs to their default values (but avoid using this, as it’s rarely useful)
search a search entry field
submit a form submission button
tel a telephone number entry field
text a text entry field
time a time picker with no time zone
url a URL entry field
week a week number and year picker

Il browser ricade su text se ometti l’attributo type o non supporta un’opzione. I browser moderni hanno un buon supporto per tutti i tipi, ma i browser vecchi mostreranno ancora una casella di immissione testuale.

Altri attributi utili di <input> includono:

attribute description
accept file upload type
alt alternative text for the image types
autocomplete hint for field auto-completion
autofocus focus field on page load
capture media capture input method
checked checkbox/radio is checked
disabled disable the control (it won’t be validated or have its value submitted)
form associate with a form using this ID
formaction URL for submission on submit and image buttons
inputmode data type hint
list ID of <datalist> autocomplete options
max maximum value
maxlength maximum string length
min minimum value
minlength minimum string length
name name of control, as submitted to server
pattern a regular expression pattern, such as [A-Z]+ for one or more uppercase characters
placeholder placeholder text when the field value is empty
readonly the field is not editable, but it will still be validated and submitted
required the field is required
size the size of the control (often overridden in CSS)
spellcheck set true or false spell-checking
src image URL
step incremental values in numbers and ranges
type field type (see above)
value the initial value

Campi Output HTML

Oltre ai tipi di input, HTML5 fornisce output di sola lettura:

  • output: un risultato testuale di un calcolo o di un’azione dell’utente
  • progress: una barra di avanzamento con attributi value e max
  • meter: una scala che può cambiare tra verde, ambra e rosso a seconda dei valori impostati per gli attributi value, min, max, low, high e optimum.

Etichette di Input

I campi dovrebbero avere un’etichetta associata <label>, che puoi avvolgere attorno all’elemento:

<label>your name <input type="text" name="name" /><label>

O collegare l’ID del campo all’etichetta utilizzando un attributo for:

<label for="nameid">your name</label>
<input type="text" id="nameid" name="name" />

Le etichette sono importanti per l’accessibilità. Potresti aver incontrato moduli che utilizzano un placeholder per risparmiare spazio sullo schermo:

<input type="text" name="name" value="" placeholder="your name" />

Il testo del placeholder scompare una volta che l’utente digita qualcosa — anche uno spazio singolo. È meglio mostrare un’etichetta che costringere l’utente a ricordare cosa voleva il campo!

Comportamenti di Input

I tipi di campo e gli attributi di restrizione modificano il comportamento di input del browser. Ad esempio, un input number mostra una tastiera numerica sui dispositivi mobili. Il campo potrebbe mostrare una rotellina e le pressioni dei tasti freccia su/giù della tastiera incrementeranno e decrementeranno i valori.

La maggior parte dei tipi di campo è ovvia, ma ci sono eccezioni. Ad esempio, i numeri delle carte di credito sono numerici, ma la funzione di incremento/decremento è inutile e è troppo facile premere su o giù durante l’inserimento di un numero di 16 cifre. È meglio utilizzare un tipo standard text, ma impostare l’attributo inputmode su numeric, che mostra una tastiera appropriata. Impostare anche autocomplete="cc-number" suggerisce eventuali numeri di carta preconfigurati o inseriti in precedenza.

Utilizzare il tipo di campo corretto e autocorrect offre benefici che sarebbero difficili da ottenere in JavaScript. Ad esempio, alcuni browser per dispositivi mobili possono:

Convalida automatica

Il browser garantisce che il valore immesso rispetti le restrizioni definite dagli attributi type, min, max, step, minlength, maxlength, pattern e required. Ad esempio:

<input type="number" min="1" max="100" required />

Provando a inviare un valore vuoto impedisce l’invio del modulo e mostra il seguente messaggio in Chrome:

I lancette non consentono valori al di fuori dell’intervallo da 1 a 100. Messaggi di validazione simili compaiono se si digita una stringa che non è un numero. Tutto senza scrivere una sola riga di JavaScript.

È possibile disabilitare la validazione del browser con:

  • l’aggiunta di un attributo novalidate all’elemento <form>
  • l’aggiunta di un attributo formnovalidate al pulsante o all’immagine di invio

Creazione di Inputs Personalizzati in JavaScript

Se stai scrivendo un nuovo componente di inserimento dati basato su JavaScript, ti preghiamo di fermarti e allontanarti dalla tua tastiera!

Scrivere controlli di input personalizzati è difficile. Devi considerare il mouse, la tastiera, il tocco, la voce, l’accessibilità, le dimensioni dello schermo e cosa succede quando JavaScript fallisce. Stai anche creando un’esperienza utente diversa. Forse il tuo controllo è superiore al selettore di date standard su desktop, iOS e Android, ma l’interfaccia utente sconosciuta confonderà alcuni utenti.

Ci sono tre ragioni principali per cui gli sviluppatori scelgono di creare input basati su JavaScript.

1. I controlli standard sono difficili da formare

La formattazione CSS è limitata e spesso richiede hack, come sovrapporre un input con i pseudo-elementi ::before e ::after del suo etichetta. La situazione sta migliorando, ma metti in discussione qualsiasi design che priorizza la forma sulla funzione.

2. I tipi moderni di <input> non sono supportati nei vecchi browser

Fondamentalmente, stai codificando per Internet Explorer. Gli utenti di IE non otterranno un selettore di date ma possono comunque inserire date nel formato AAAA-MM-GG. Se il tuo cliente insiste, allora carica un polyfill solo in IE. Non c’è bisogno di appesantire i browser moderni.

3. Richiedi un nuovo tipo di input che non è mai stato implementato prima

Queste situazioni sono rare, ma inizia sempre con campi HTML5 appropriati. Sono veloci e funzionano anche prima che lo script sia caricato. Puoi migliorare progressivamente i campi come necessario. Ad esempio, un pizzico di JavaScript può garantire che la data di fine di un evento del calendario si verifichi dopo la data di inizio.

In sintesi: evita di reinventare i controlli HTML!

Stile di convalida CSS

Puoi applicare i seguenti pseudo-classi ai campi di input per decorarli in base allo stato attuale:

selector description
:focus the field with focus
:focus-within an element contains a field with focus (yes, it’s a parent selector!)
:focus-visible an element has focus owing to keyboard navigation, so a focus ring or more evident styling is necessary
:required a field with a required attribute
:optional a field without a required attribute
:valid a field that has passed validation
:invalid a field that has not passed validation
:user-valid a field that has passed validation after the user has interacted with it (Firefox only)
:user-invalid a field that hasn’t passed validation after the user has interacted with it (Firefox only)
:in-range the value is within range on a number or range input
:out-of-range the value is out of range on a number or range input
:disabled a field with a disabled attribute
:enabled a field without a disabled attribute
:read-only a field with a read-only attribute
:read-write: a field without a read-only attribute
:checked a checked checkbox or radio button
:indeterminate an indeterminate checkbox or radio state, such as when all radio buttons are unchecked
:default the default submit button or image

Puoi decorare il testo del placeholder di un input con il ::placeholder pseudo-elemento:

/* placeholder blu su campi email */
input[type="email"]::placeholder {
  color: blue;
}

I selettori sopra hanno la stessa specificità, quindi l’ordine può essere importante. Considera questo esempio:

input:invalid { color: red; }
input:enabled { color: black; }

I campi di input non validi hanno testo rosso, ma viene applicato solo ai campi con un attributo disabledquindi tutti i campi abilitati sono neri.

Il browser applica gli stili di convalida al caricamento della pagina. Ad esempio, nel seguente codice ogni campo non valido viene dato un bordo rosso:

:invalid {
  border-color: #900;
}

L’utente si trova di fronte a un imponente insieme di caselle rosse prima di interagire con il modulo. Visualizzare gli errori di convalida dopo il primo invio o man mano che il valore cambia offrirebbe un’esperienza migliore. È qui che entra in gioco JavaScript…

JavaScript e l’API di Convalida per Vincoli

L’API di Convalida per Vincoli offre opzioni di personalizzazione del modulo che possono migliorare il controllo standard dei campi HTML. Potresti:

  • bloccare la convalida fino a quando l’utente interagisce con un campo o invia il modulo
  • visualizzare messaggi di errore con stili personalizzati
  • fornire una convalida personalizzata che è impossibile solo con HTML. Questo è spesso necessario quando è necessario confrontare due input — come quando si inserisce un indirizzo email o un numero di telefono, si verifica che i campi “nuovo” e “conferma” password abbiano lo stesso valore, o si assicura che una data venga dopo un’altra.

Convalida del Form

Prima di utilizzare l’API, il tuo codice dovrebbe disabilitare la convalida predefinita e i messaggi di errore impostando la proprietà noValidate del modulo su true (lo stesso di aggiungere un attributo novalidate):

const myform = document.getElementById('myform');
myform.noValidate = true;

Puoi quindi aggiungere gestori di eventi — come quando il modulo viene inviato:

myform.addEventListener('submit', validateForm);

Il gestore può verificare che l’intero modulo sia valido utilizzando i metodi checkValidity() o reportValidity(), che restituiscono true quando tutti gli input del modulo sono validi. (La differenza è che checkValidity() verifica se qualsiasi input è soggetto a convalida per vincoli.)

Le documentazioni di Mozilla spiegano:

Si attiva anche un evento invalid su ogni campo non valido. Questo non si propaga: i gestori devono essere aggiunti a ogni controllo che lo utilizza.

// validare il modulo al momento della sottoscrizione
function validateForm(e) {

  const form = e.target;

  if (form.checkValidity()) {

    // il modulo è valido - effettuare ulteriori controlli

  }
  else {

    // il modulo è non valido - annullare la sottoscrizione
    e.preventDefault();

  }

};

A valid form could now incur further validation checks. Similarly, an invalid form could have invalid fields highlighted.

Validazione dei campi

I campi individuali hanno le seguenti proprietà di validazione delle restrizioni:

  • willValidate: restituisce true se l’elemento è un candidato per la validazione delle restrizioni.

  • validationMessage: il messaggio di validazione. Questo sarà una stringa vuota se il campo è valido.

  • valitity: un oggetto ValidityState. Questo ha una proprietà valid impostata su true quando il campo è valido. Se è false, uno o più delle seguenti proprietà saranno true:

    ValidityState descrizione
    .badInput il browser non può comprendere l’input
    .customError è stato impostato un messaggio di validità personalizzato
    .patternMismatch il valore non corrisponde all’attributo pattern specificato
    .rangeOverflow il valore è maggiore dell’attributo max
    .rangeUnderflow il valore è inferiore all’attributo min
    .stepMismatch il valore non rispetta le regole dell’attributo step
    .tooLong la lunghezza della stringa è maggiore dell’attributo maxlength
    .tooShort la lunghezza della stringa è inferiore all’attributo minlength
    .typeMismatch il valore non è un indirizzo email o URL valido
    .valueMissing un valore richiesto è vuoto

I campi individuali hanno i seguenti metodi di convalida delle restrizioni:

  • setCustomValidity(message): imposta un messaggio di errore per un campo non valido. Deve essere passato una stringa vuota quando il campo è valido, altrimenti il campo resterà invalido per sempre.
  • checkValidity(): restituisce true quando l’input è valido. La proprietà valitity.valid fa la stessa cosa, ma checkValidity() attiva anche un evento invalid sul campo che potrebbe essere utile.

La funzione gestore validateForm() potrebbe scorrere ogni campo e applicare una classe invalid al suo elemento genitore dove necessario:

function validateForm(e) {
  const form = e.target;
  if (form.checkValidity()) {
    // il modulo è valido - effettuare ulteriori controlli
  }
  else {
    // il modulo è non valido - annulla invio
    e.preventDefault();
    // applica classe non valida
    Array.from(form.elements).forEach(i => {
      if (i.checkValidity()) {
        // campo è valido - rimuovi classe
        i.parentElement.classList.remove('invalid');
      }
      else {
        // campo è non valido - aggiungi classe
        i.parentElement.classList.add('invalid');
      }
    });
  }
};

Si assuma che il vostro HTML abbia definito un campo email:

<div>
  <label for="email">email</label>
  <input type="email" id="email" name="email" required />
  <p class="help">Please enter a valid email address</p>
</div>

Il script applica una classe invalid al <div> quando l’email non è specificata o è non valida. CSS può mostrare o nascondere il messaggio di convalida quando il modulo viene inviato:

.help { display: none; }
.invalid .help { display: block; }
.invalid label, .invalid input, .invalid .help {
  color: red;
  border-color: red;
}

Creazione di un Validatore di Form Custom

Il seguente esempio mostra un modulo di contatto che richiede un nome utente e un indirizzo email, un numero di telefono o entrambi:

È implementato utilizzando una classe generica di validazione del form chiamata FormValidate. Un elemento form viene passato durante l’istanziazione di un oggetto. Un secondo parametro opzionale può essere impostato:

  • true per convalidare ogni campo mentre l’utente lo interagisce
  • false (impostazione predefinita) per convalidare tutti i campi dopo il primo invio (la convalida a livello di campo avviene dopo)
// convalida modulo contatto
const contactForm = new FormValidate(document.getElementById('contact'), false);

Un metodo .addCustom(field, func) definisce funzioni di convalida personalizzate. Il codice seguente garantisce che sia il campo email o il campo tel siano validi (nessuno dei due ha l’attributo required):

// convalida personalizzata - email e/o telefono
const
  email = document.getElementById('email'),
  tel = document.getElementById('tel');

contactForm.addCustom(email, f => f.value || tel.value);
contactForm.addCustom(tel, f => f.value || email.value);

A FormValidate object monitors both of the following:

  • eventi focusout, che quindi controllano un campo individuale
  • eventi di submit del form, che quindi controllano ogni campo

Entrambi chiamano il metodo .validateField(field), che controlla se un campo supera la convalida delle restrizioni standard. Quando lo fa, qualsiasi funzione di convalida personalizzata assegnata a quel campo viene eseguita a turno. Tutte devono restituire true affinché il campo sia valido.

I campi non validi hanno una classe invalid applicata all’elemento padre del campo, che visualizza un messaggio di aiuto rosso utilizzando CSS.

Infine, l’oggetto chiama una funzione personalizzata submit quando l’intero modulo è valido:

// submit personalizzato
contactForm.submit = e => {
  e.preventDefault();
  alert('Form is valid!\n(open the console)');
  const fd = new FormData(e.target);
  for (const [name, value] of fd.entries()) {
    console.log(name + ': ' + value);
  }
}

In alternativa, puoi utilizzare un addEventListener standard per gestire gli eventi submit del modulo, poiché FormValidate impedisce l’esecuzione di ulteriori gestori quando il modulo è non valido.

Form Finesse

I moduli sono la base di tutti gli applicativi web e gli sviluppatori dedicano molto tempo alla manipolazione dell’input utente. La validazione delle restrizioni è ben supportata: i browser possono gestire la maggior parte dei controlli e mostrare opzioni di input appropriate.

Raccomandazioni:

  • Utilizza i tipi di input HTML standard dove possibile. Imposta gli attributi min, max, step, minlength, maxlength, pattern, required, inputmode, e autocomplete come appropriato.
  • Se necessario, usa un po’ di JavaScript per abilitare la validazione personalizzata e i messaggi.
  • Per campi più complessi, migliora progressivamente gli input standard.

Infine: dimentica Internet Explorer!

A meno che i tuoi clienti non siano prevalentemente utilizzatori di IE, non c’è bisogno di implementare le proprie funzioni di validazione di fallback. Tutti i campi di input HTML5 funzionano in IE, ma potrebbero richiedere maggiore impegno da parte dell’utente. (Ad esempio, IE non rileverà quando si inserisce un indirizzo email non valido.) Devi comunque validare i dati sul server, quindi considera di utilizzare quella come base per il controllo degli errori in IE.

Domande frequenti (FAQs) sui form HTML e la validazione delle restrizioni

Qual è l’importanza della validazione dei form HTML?

La validazione dei form HTML è un aspetto cruciale dello sviluppo web. Garantisce che i dati inseriti dagli utenti in un modulo rispettino determinati criteri prima di essere inviati al server. Ciò non solo mantiene l’integrità dei dati, ma migliora anche l’esperienza utente fornendo feedback immediato sulla correttezza dei dati inseriti. Senza la validazione dei form, c’è il rischio di ricevere dati errati, incompleti o persino dannosi, il che può causare vari problemi, tra cui corruzione dei dati, violazioni della sicurezza e crash del sistema.

In che modo HTML5 migliora la validazione dei form?

HTML5 introduce diversi nuovi elementi e attributi dei form che rendono molto più semplice ed efficiente la validazione dei form. Ad esempio, fornisce nuovi tipi di input come email, URL e numero, che validano automaticamente i dati di input in base al tipo. Introduce anche nuovi attributi come required, pattern e min/max che ti consentono di specificare varie restrizioni sui dati di input. Inoltre, HTML5 fornisce un’API di validazione integrata che ti permette di eseguire una validazione personalizzata utilizzando JavaScript.

Posso eseguire la validazione dei form senza JavaScript?

Sì, è possibile eseguire la convalida di base dei moduli utilizzando solo HTML5. HTML5 introduce diversi nuovi tipi di input e attributi che consentono di specificare varie restrizioni sul dato di input. Ad esempio, puoi utilizzare l’attributo required per rendere un campo obbligatorio, l’attributo pattern per imporre un formato specifico e gli attributi min/max per impostare un intervallo per l’input numerico. Tuttavia, per una convalida più complessa, potresti comunque dover ricorrere a JavaScript.

Come posso personalizzare i messaggi di errore nella convalida dei moduli HTML5?

HTML5 fornisce un’API di convalida che ti consente di personalizzare i messaggi di errore. Puoi utilizzare il metodo setCustomValidity dell’oggetto ValidityState per impostare un messaggio di errore personalizzato per un campo. Questo metodo accetta un argomento di stringa, che diventa il messaggio di convalida del campo quando il campo è non valido. Puoi chiamare questo metodo in risposta all’evento invalid, che viene innescato quando un campo non supera la convalida.

Come posso disabilitare la convalida dei moduli HTML5?

Puoi disabilitare la convalida dei moduli HTML5 aggiungendo l’attributo novalidate all’elemento form. Quando questo attributo è presente, il browser non eseguirà alcuna convalida sul modulo al momento del suo invio. Ciò può essere utile se desideri gestire la convalida interamente sul lato server o utilizzando JavaScript personalizzato.

Come posso convalidare insieme più campi in HTML5?

HTML5 non fornisce un modo integrato per convalidare più campi insieme. Tuttavia, è possibile raggiungere questo obiettivo utilizzando JavaScript. È possibile scrivere una funzione di convalida personalizzata che controlla i valori di più campi e imposta un messaggio di validità personalizzato se non soddisfano i criteri richiesti. È possibile chiamare questa funzione in risposta all’evento di invio del modulo o agli eventi di input/cambio dei campi.

Come posso convalidare un campo in base al valore di un altro campo in HTML5?

HTML5 non fornisce un modo integrato per convalidare un campo in base al valore di un altro campo. Tuttavia, è possibile raggiungere questo obiettivo utilizzando JavaScript. È possibile scrivere una funzione di convalida personalizzata che controlla il valore di un campo rispetto al valore di un altro campo e imposta un messaggio di validità personalizzato se non corrispondono. È possibile chiamare questa funzione in risposta agli eventi di input/cambio dei campi.

Come posso eseguire la convalida asincrona in HTML5?

HTML5 non supporta la convalida asincrona di serie. Tuttavia, è possibile raggiungere questo obiettivo utilizzando JavaScript. È possibile scrivere una funzione di convalida personalizzata che esegue un’operazione asincrona, come una richiesta AJAX, e imposta un messaggio di validità personalizzato in base al risultato. È possibile chiamare questa funzione in risposta agli eventi di input/cambio dei campi o all’evento di invio del modulo.

Come posso modificare lo stile dei messaggi di errore nella convalida dei moduli HTML5?

L’aspetto dei messaggi di errore nella convalida dei moduli HTML5 è determinato dal browser e non può essere direttamente formattato utilizzando CSS. Tuttavia, è possibile creare messaggi di errore personalizzati utilizzando JavaScript e formattarli come si desidera. È possibile utilizzare l’API di convalida per determinare quando un campo è invalido e visualizzare un messaggio di errore personalizzato di conseguenza.

Come posso testare la convalida di un modulo HTML?

È possibile testare la convalida di un modulo HTML inserendo vari tipi di dati nei campi e tentando di inviare il modulo. Si dovrebbe testare sia con dati validi che non validi per assicurarsi che la convalida funzioni correttamente in tutti i casi. È inoltre possibile utilizzare strumenti o librerie di test automatizzati per eseguire test più esaustivi.

Source:
https://www.sitepoint.com/html-forms-constraint-validation-complete-guide/