Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Validazione dei form con CSS3 e HTML5

Puntiamo lo sguardo in avanti e pensiamo al futuro: validare un modulo usando le nuove specifiche
Puntiamo lo sguardo in avanti e pensiamo al futuro: validare un modulo usando le nuove specifiche
Link copiato negli appunti

Questa è la traduzione dell'articolo Forward Thinking Form Validation di Ryan Seddon, pubblicato originariamente su A List Apart il 21 Settembre 2010. La traduzione viene qui presentata con il consenso dell'editore (A List Apart Magazine) e dell'autore.

La validazione dei form è sempre stata una questione problematica, sin dagli albori del web. All'inizio ci fu il messaggio di errore riassuntivo della validazione lato server. Poi siamo passati alla validazione lato client per verificare la correttezza della compilazione mentre l'utente riempie i vari campi. Ora siamo di fronte alla marcia trionfale di HTML5 e CSS3: il capitolo dedicato ai form della specifica HTML5 presenta nuovi tipi di input e di attributi che rendono possibile l'inserimento di specifici vincoli nella compilazione e nella conseguente validazione del modulo. Il modulo Basic UI dei CSS3 fornisce diverse pseudo-classi per aiutarci ad applicare degli stili ai diversi stati della validazione e a cambiare l'aspetto dei campi in base alle azioni degli utenti. Vediamo come combinare queste due tecnologie per creare un validatore di form basato sui CSS che abbia un ampio supporto sui browser attuali.

Più aiutiamo in tempo reale un utente a procedere nella compilazione di un form, meno probabile sarà l'eventualità che egli compia degli errori. Date un'occhiata all'esempio di validazione dei form con i CSS allegato a questo articolo in un browser che supporta le pseudo-classi Basic UI dei CSS3 (Chrome 4+, Safari 5+, Opera 9.6+). Ho usato queste pseudo-classi e gli attributi dei form di HTML5 per creare il tutto. Vediamo come funziona.

Pseudo-classi CSS3 per l'interfaccia utente

Il modulo UI presenta diverse pseudo-classi che aiutando ad applicare stili ai campi di un form in diversi stati:

  • valid
  • invalid
  • required
  • optional
  • in-range
  • out-of-range
  • read-only
  • read-write

Nella demo ho usato le pseudo-classi required, invalid e valid per implementare la validazione CSS:

input:focus:required:invalid {
  background: pink url(ico_validation.png) 379px 3px no-repeat;
}
input:required:valid {
  background-color: #fff;
  background-position: 379px -61px;
}

Dal momento che vogliamo solo specificare che un certo campo non è valido quando esso riceve il focus, usiamo la pseudo-classe focus per attivare lo stile che denota un campo non valido (ovviamente, segnalare come non validi tutti i campi obbligatori sin dall'inizio sarebbe una scelta di design poco azzeccata).

Spostando il focus su un campo obbligatorio che non sia valido attiviamo lo stile che visualizza il punto esclamativo, cosa che avvisa l'utente sul fatto che qualcosa deve essere inserito nel campo. Una volta che i vincoli di validazione siano stati soddisfatti, si attiva la pseudo-classe valid. Ora, rimuoviamo la pseudo-classe focus così che rimanga solo il segnale verde che indica un campo corretto.

Tutte le pseudo-classi elencate sopra si spiegano da sé. Le pseudo-classi in-range e out-of-range dovrebbero usate insieme con gli attributi min e max, su un input basato su un intervallo, su un campo per l'immissione di numeri o su tutti quei tipi di input che accettano quegli attributi. Per esempio, se un utente inserisce un valore che è fuori dall'intervallo (out-of-range, possiamo usare la pseudo-classe per cambiare lo stile che riflette lo stato; possiamo fare lo stesso per in-range.

Solo Opera supporta al momento le pseudo-classi relative al range. Altri browser lo faranno presto.

Nuovi di tipi di input e attributi

La specifica sui form di HTML5 introduce anche nuovi tipi di input come email, url e number. Per esempio, email attiva la pseudo-classe valid solo quando l'utente inserisce un indirizzo e-mail valido; la stessa cosa si applica al campo di tipo number o url. I vincoli per la validazione di un campo url variano da browser a browser. In Opera, inserendo qualcosa come http:// il contenuto del campo è considerato valido. Su Chrome scrivere http://w è valido. Su Safari è valido scrivere semplicemente http:.

Ci sono pure alcuni attributi che facilitano la validazione come placeholder, required, maxlength, pattern, min, max e step:

<input id="postcode" name="postcode" type="number" min="1001" max="8000"
maxlength="4" required />

Il campo postcode usa un input di tipo number e alcuni attributi. In Australia un codice postale può essere solo di 4 cifre, così impostiamo un attributo maxlenght pari a 4 per restringere l'inserimento di ulteriori caratteri. Vogliamo anche limitare quanto alto o quanto basso potrà essere il valore di un codice, così usiamo min e max per definire i limiti. L'attributo required (obbligatorio) si spiega da sé.

Possiamo usare l'attributo step per restringere ulteriormente un campo sui cui si siano usati min e max. Di default, step è impostato su 1, così ogni numero compreso tra min e max incrementato almeno di 1 è valido. Cambiando il valore di step a 100, rende valido il campo se l'utente inserisce un valore incrementato di 100. Per esempio, se imposto l'attributo step su 100, 1001 sarà valido, così cpme 1101, 1201, 1301, etc.

Trovare il pattern

Per attivare la pseudo-classe invalid in condizioni più specifiche, come su un rudimentale numero di telefono, possiamo usare l'attributo pattern, che ci consente di applicare ad un campo un'espressione regolare:

<input type="tel" id="tel" name="tel" pattern="d{10}" placeholder=
"Please enter a ten digit phone number" required />

L'espressione regolare appena vista è semplice. Dice: "Accetto solo dieci caratteri e non di più". Così, il campo sarà sempre non valido fino a quando non vengano soddisfatti i requisiti dell'espressione regolare. Notate come si sia usato l'attributo placeholder per dare all'utente un aiuto nella compilazione.

Possiamo spingere molto in avanti la potenza dell'attributo pattern applicando un'espressione regolare più complessa, come su questo campo per le password:

<input id="password" name="password" type="password" title="Minimum 8
characters, one number, one uppercase and one lowercase letter" required
pattern="(?=^.{8,}$)((?=.*d)|(?=.*W+))(?![.n])(?=.*[A-Z])
(?=.*[a-z]).*" />

Dal momento che abbiamo specifiche condizioni che restringono quanto può essere inserito dagli utenti, costringendoli a creare password più sicure, definiamo un'espressione regolare come mostrato sopra. La password deve essere almeno di 8 caratteri, contenere un numero, una lettera in minuscolo e una in maiuscolo.

Per aiutare un utente a soddisfare queste condizioni, usiamo l'attributo title per aiutarlo a comprendere esattamente quali siano i requisiti. Non usiamo in questo caso l'attributo placeholder, perché c'è bisogno di una spiegazione più lunga e placeholder dovrebbe essere usato solo per brevi suggerimenti.

Aggiungere un aiuto

Se l'utente non passa mai con il mouse sul campo, e si sposta invece con il tasto tabulatore, non visualizzerà mai le istruzioni di aiuto comprese nell'attributo title. Potete notare che sui campi per il telefono, per il codice postale e per le password, appare un testo di aiuto quando il campo ha bisogno di ulteriori spiegazioni in vista della compilazione.

<input id="password" type="password"  />
<p class="validation01">
  <span class="invalid">Minimum 8 characters, one number, one uppercase
letter and one lowercase letter</span>
  <span class="valid">Your password meets our requirements, thank you.
</span>
</p>

Il markup visto qui sopra introduce un contenitore extra con i box d'aiuto per quando il campo è valido e per quando è non valido. In questo modo, quando il campo non è valido, conterrà l'informazione extra per andare in aiuto dell'utente. Quando tutto è corretto, il nostro messaggio e il segno verde lo rassicurano sul fatto che la compilazione è avvenuta correttamente.

.validation01 {
  background: red;
  color: #fff;
  display: none;
  font-size: 12px;
  padding: 3px;
  position: absolute;
  right: -110px;
  text-align: center;
  top: 0;
  width: 100px;
}
input:focus + .validation01 {
  display: block;
}
input:focus:required:valid + .validation01 {
  background: green;
}
input:focus:required:valid + .validation01 .invalid {
  display: none;
}
input:focus:required:invalid + .validation01 .valid {
  display: none;
}

Per mostrare o nascondere il box di aiuto, a seconda dello stato del campo, possiamo prendere il campo come target facendo ricorso alle pseudo-classi, usando il selettore dell'elemento adiacente (+). Una volta che il campo sia stato compilato correttamente, lo sfondo cambia diventando verde e viene visualizzato un messaggio di validità.

Fine prima parte.

Problemi di usabilità con l'approccio corrente

C'è principalmente un problema rispetto al modo in cui funziona la pseudo-classe invalid quando un campo è settato come obbligatorio (required) e ha condizioni addizionali che devono essere soddisfatte. Per esempio quando un campo è definito come required e il suo tipo è impostato su email. Dal momento che il campo è sempre non valido fino a quando tutte le condizioni non vengono soddisfatte, esso attiverà gli stili che si applicano quando un campo non è valido. In questo caso, nella nostra demo iniziale, il campo sarà da subito non valido e marcato di rosso con un messaggio di errore anche prima che l'utente abbia inserito qualcosa. Ecco perché usiamo la pseudo-classe focus per visualizzare gli stili di non validità solo quando un campo ha il focus. Ciò non è ottimale: se un utente si sposta dal campo senza soddisfare le condizioni di validazione, il campo non indicherà che qualcosa è sbagliato fino a quando il focus non torna su di esso.

Una soluzione per questo problema potrebbe consistere nell'aggiungere la pseudo-classe indeterminate disponibile per i radio button e per i checkbox. Tecnicamente, un campo che ha più condizioni rispetto all'unica rappresentata dell'essere obbligatorio, quando è vuoto non è valido né non valido, è piuttosto indeterminato. Questa idea correggerebbe il problema del messaggio di validità che compare anche quando il campo è vuoto e ci consente di applicare uno stile a seconda della condizione di validità.

Inoltre, possiamo aggiungere delle funzionalità interessanti senza ricorrere a Javascript. Possiamo indicare in quale stato si trova un campo, se è obbligatorio, possiamo dire ad esso di conformarsi ad un certo pattern con con un'espressione regolare, specificare valori minimi e massimi e molto altro. Ma cosa accade se non è abbastanza? Cosa possiamo fare se volessimo portare il tutto più avanti? Beh, siamo fortunati, perché la specifica HTML5 a proposito dei form definisce anche una API per i vincoli di validazione.

API per i vincoli di validazione

Insieme ai nuovi attributi, ai nuovi tipi di input e alle pseudo-classi CSS3, abbiamo a disposizione nella specifica HTML5 una semplice API Javascript che ci consente di estendere le funzionalità di validazione con comodi metodi, attributi ed eventi. Date un'occhiata alla demo aggiornata che usa tra l'altro proprio questa API.

Ogni campo del modulo ha un attributo chiamato validity. L'attributo validity restituisce un oggetto ValidityState che rappresenta lo stato di validazione corrente di un elemento. L'oggetto ValidityState contiene diversi attributi boolaani che identificano in quale condizione di validità si trova l'elemento corrente. In pratica, si tratta di una serie risposte di tipo vero/falso (true/false) che dicono ad uno sviluppatore cosa esattamente c'è di sbagliato in un campo:

  • valueMissing: Questo attributo restituisce true se un campo obbligatorio è vuoto.
  • typeMismatch: Questo valore si applica a tutti i nuovi tipi di attributo. Per esempio, se un valore per un campo email non è corretto, questo attributo restituisce true.
  • patternMismatch: Quando un elemento contiene l'attributo pattern e non è conforme alle condizioni impostate nell'espressione regolare, questo attributo restituisce true.
  • tooLong: Quando un elemento supera la sua proprietà maxlenght questo attributo restituisce true.
  • rangeUnderflow e rangeOverflow: Se gli attributi min e max di un elemento sono sopra o sotto i valori specificati, questo attributo restituisce true.
  • stepMismatch: Quando un elemento con l'attributo step non è conforme al valore richiesto per step, questo attributo restituisce true.
  • valid: Se uno dei valori appena elencati restituisce true, questo attributo restituisce false per indicare che un form non è valido. Altrimenti, se tutte le condizioni sono soddisfatte, restituirà true.

Dettagli aggiuntivi

L'evento invalid è un'altra funzionalità molto comoda. Sarà invocata dal campo quando esso è ancora non valido. Così possiamo attaccare ad esso una qualche forma di interazione e, nel nostro caso, modificare lo stile del campo affinché rifletta il suo stato.

Inoltre, il metodo checkValidity può essere eseguito su un campo individuale o su un form nel suo complesso, e può restituire true o false. Eseguire il metodo fa anche anche programmaticamente attivare l'evento invalid su tutti i campi non validi, oppure, se viene eseguito su un campo singolo, solo su quello.

Rivediamo la demo

Riprendiamo la nostra demo e miglioriamola con l'uso della API sulla validazione. Basandoci su quello che abbiamo appreso da Luke Wroblewski nel suo articolo La validazione inline dei form e sulle nostre esperienze, possiamo applicare queste idee al nostro modulo per creare un'esperienza di validazione ottimale.

La prima cosa che possiamo correggere è l'applicazione immediata dello stile di errore su un campo non valido. Piuttosto che applicare subito uno stile per indicare che l'utente non ha compilato il campo in modo corretto, aspettiamo fino a quando non si sposta dal campo per mostrare qualunque tipo di messaggio.

Se l'utente soddisfa i requisiti di compilazione mentre il focus è ancora su un certo campo, gli facciamo subito sapere che il campo è corretto e valido. Lo facciamo collegando l'evento input per verificare se se il campo è valido. Quando lo è, aggiorniamo lo stile perché il campo rifletta i cambiamenti.

Se il campo contiene valori non corretti e l'utente si sposta sul prossimo campo, l'evento blur verificherà la validità del campo e quindi applicherà gli stili di errore per far sapere all'utente che ha sbagliato qualcosa. Manterrà lo stile di errore fino a quando i requisiti non siano soddisfatti.

Cosa fare con i vecchi browser?

Tutti gli argomenti discussi sono piuttosto nuovi e il supporto sui vari browser, sebbene sia buono, non ci garantirebbe nel contesto di un ambiente di produzione rivolto al mondo reale, quello in cui dovremmo supportare tutti i browser. Ecco a cosa serve lo script che ho creato.

Per i browser che non supportano i form HTML5 e la API per la validazione, lo script emula quelle funzionalità. Per i browser che supportano queste funzionalità, lo script identifica il supporto e si affida alle funzionalità native. Diamo ora un'occhiata alla demo ulteriormente aggiornata con l'aggiunta del nuovo script. Provatelo con Firefox e IE per verificare che funziona esattamente come sui browser che supportano le funzionalità di validazione nativamente.

Supporto dei browser

Lo script è stato testato e funziona sui seguenti browser:

  • IE6+
  • Firefox 1+—FF4 avrà un supporto nativo.
  • Chrome 4+—Supporto nativo.
  • Safari 3.2+—Safari 5 ha un supporto nativo.
  • Opera 9.6+—Supporto nativo.

Le seguenti funzionalità sono emulate nello script:

  • ogni campo ha l'oggetto validity in modalità live e vi fornirà informazioni sullo stato corrente del campo;
  • il metodo checkValidity è disponibile e indica se il form o uno specifico elemento non sono validi;
  • sono supportati gli attributi pattern, placeholder, required, min, max e step;
  • per le textarea sono supportati gli attributi placeholder e required;
  • l'attributo required è supportato anche per i campi di tipo select;
  • i tipi di input email e url sono verificati rispetto ad una espressione regolare integrata nel codice e saranno non validi fino a quando non siano conformi a tale espressione regolare.

Validazione in abbondanza!

Il supporto dei browser per i form HTML5 e per il modulo UI dei CSS3 sta iniziando ad essere più ampio. Opera 9 ha guidato la pattuglia implementando i Web Forms 2.0 prima che essi fossero incorporati nella specifica HTML5, ma ha un supporto per il modulo UI dei CSS3 solo a partire dalla versione 9.6. Chrome garantisce il supporto dalla versione 4, Safari ha implementato tutto di recente con la versione 5, Firefox introdurrà un supporto esteso con la versione 4.0, IE9, se continua sulla via intrepresa del progresso nel supporto degli standard, dovrebbe avere un supporto di base per queste funzionalità nelle prossime release.

Possiamo fare cose straordinarie con questi nuovi moduli di HTML5 e CSS3. Man mano che i browser allargheranno il supporto queste tecniche diventeranno un'alternativa effettiva che potrà adattarsi ai problemi semplici e complessi della validazione dei form.

Ti consigliamo anche