Quando gestiamo una form HMTL è molto utile sfruttare la funzione focus()
di JavaScript per portare all'attenzione dell'utente i campi che non hanno passato il check di validazione della form. Il modo tradizionale di fare questo controllo è qualcosa del genere
<input type="button" onclick="return postForm();" >
…
<script language="JavaScript">
function postForm() {
num = document.form_name.field0;
if (num.value == "") {
alert("Campo obbligatorio!");
num.focus();
return false;
}
ecc..
Questo modo di lavorare è un po' datato, ma resta sempre valido. Oggi abbiamo a disposizione strumenti molto più comodi, come ad esempio i framework e librerie JavaScript. Vediamo ad esempio un modo più semplice di validare una form
HTML usando jQuery.
Rispolveriamo i selettori CSS
Tra i selettori CSS abbiamo le pseudo-classi, di cui abbiamo già parlato in questo articolo. Una di queste è la pseudo-classe focus
, che permette di selezionare l'elemento che riceve il focus per assegnare delle proprietà CSS a nostro piacimento, ad esempio:
input:focus { BACKGROUND-COLOR: cyan; }
il selettore qui sopra assegnerà lo sfondo cyan
all'elemento (di tipo input) che ha il focus. E' importante sottolineare che si tratta “solo di una meccanica CSS”, e non di un evento associato all'elemento input. Il motivo di questa precisazione ci sarà chiaro tra poche righe.
All'abbordaggio con jQuery
Uno dei vantaggi di jQuery è di sfruttare la gran parte delle regole del CSS. Questo ci permette di implementare lo stesso effetto del CSS visto sopra scrivendo
$('input:focus').css('background-color', 'cyan');
a questo punto uno potrebbe pensare di validare i campi input al volo, man mano che l'utente si muove con il tasto TAB attraverso di essi. Non possiamo però usare il comando
$('input:focus')
per gestire l'evento “cambio di focus”, perché, come abbiamo detto qui sopra, la regola non seleziona l'evento focus, ma solamente l'elemento HTML che ha il focus! Per gestire correttamente la validazione di un input HTML quando l'utente si sposta dal quel campo dovremmo invece usare una funzione come
$("input").blur(function() {
if (this.value == '') {
alert('Campo obbligatorio!') ;
// Gestire il focus qui
}
});
in questo modo sfruttiamo la funzione blur()
di jQuery, che viene invocata da un elemento HTML quando esso perde il focus, ovvero quando l'utente si sposta su un altro campo. A questo punto sorge però un problema: come ridare il focus all'elemento che l'utente ha lasciato vuoto?
Di primo acchito si potrebbe pensare di scrivere, al posto del commento “Gestire il focus qui”, un comando come
this.focus() ;
ma non funziona! Il problema è la gestione dell'evento associato all' ultimo elemento (quello che l'utente ha lasciato non compilato). Esemplificando possiamo dire che l'evento blur è ancora in corso, ovvero l'elemento input
sta “ancora perdendo il focus”, per cui possiamo riassegnarglielo così brutalmente.
La situazione è infatti molto diversa da quella che abbiamo visto all'inizio di questo articolo, quando abbiamo considerato il codice Javascript tradizionalmente usato per validare le form HTML. In quel caso la validazione veniva triggerata dall'evento onclick
su un pulsante, quindi al momento del controllo il focus era sul pulsante stesso!
Come possiamo riassegnare il focus ad un elemento durate l'evento blur?
La soluzione
Il problema si risolve ricordando come va gestito il delay in Javascript (vedi questa guida). Il trucco è eseguire la funzione focus dopo che l'evento blur è stato consumato. Questo modo di procedere ci risparmia i meccanismi della propagazione degli eventi Javascript (come ad esempio il metodo stopPropagation
). Una soluzione potrebbe quindi essere
$("input").blur(function() {
if (this.value == '') {
alert('Campo obbligatorio') ;
setTimeout('document.getElementsByName(\'' +
this.name + '\')[0].focus()', 500) ;
}
});
Alcune note su questa soluzione:
- Qui abbiamo considerato il caso (frequente) dove ogni campo
input
dellaform
ha un nome unico, per cui possiamo recuperare l'elemento con un tradizionalegetElementsByName
, assumendo che esso sia unico. In caso contrario possiamo selezionare l'elemento usando jQuery o usando un ID unico - La funzione è comoda perché da sola controlla tutti i campi di tipo input, anche se la nostra
form
contenesse centinaia di campi. Occorre quindi stare attenti ed eventualmente ragionare in modo esclusivo, ovvero escludere gli eventuali campi input che non dobbiamo validare - La funzione controlla solo che il campo non sia vuoto. Se dobbiamo validare alcuni campi in modo più specifico, controllando ad esempio la lunghezza minima o verificando il match con il pattern di un'espressione regolare, allora dovremo inserire un controllo ad hoc