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

Pre-validazione di un form con Javascript

Uno script completo per la gestione della validazione client-side di moduli
Uno script completo per la gestione della validazione client-side di moduli
Link copiato negli appunti

La validazione dei dati immessi dall'utente in un form è sempre problematica; verificare ciò che egli ha digitato in determinati campi risulta essere un'operazione spesso noiosa e frustrante sia per lo sviluppatore sia per l'utente stesso.

Basti pensare alle migliaia di form sparsi per il web, spesso composti di decine di campi e che consentono, per esempio, l'iscrizione a corsi, seminari, forum, etc., ma che per un banale errore di digitazione ripresentano i campi da correggere segnalati in rosso o, addirittura, la ricompilazione di tutti i campi.
Per fortuna ci viene in aiuto la validazione client-side con l'ausilio di Javascript. Vediamo in pochi step di cosa si tratta:

  • L'utente inserisce delle informazioni in un modulo
  • Dopo aver completato la compilazione, invia tutto al server
  • Prima che le informazioni arrivino al server è richiamata una funzione Javascript gestita dal browser che si occuperà di validare l'input dell'utente
  • Qualora tutti i campi risultino conformi alle regole impostate dal programmatore, i dati procederanno verso il server per una verifica più approfondita e sicura. Altrimenti all'utente sarà inviato un messaggio Javascript per segnalare l'errore, così che possa correggerlo e proseguire correttamente con l'invio

Questo tipo di approccio presenta vantaggi e svantaggi; sarà quindi utile valutare l'uso che se ne dovrà fare e analizzare l'importanza delle informazioni che si dovranno trattare (es. dati bancari).

Vantaggi:

  • L'utente ha in tempo reale un controllo sui valori inseriti nel campo
  • Non vengono sprecate risorse per inviare al server informazioni non corrette che dovranno poi essere riprocessate

Svantaggi:

  • Per usufruire di questo tipo di validazione il browser deve avere abilitato il supporto a Javascript
  • I dati inviati al server devono subire un ulteriore controllo per accertare la corretta integrità del dato

L'esempio che analizzeremo insieme viene in aiuto agli sviluppatori e agli utenti fornendo ai primi uno strumento flessibile e dinamico per il controllo dei dati inseriti e ai secondi uno strumento utile che farà risparmiare tempo nella compilazione di form complessi.

Per far questo ho creato un normale form di registrazione composto da svariati campi (nome, cognome, indirizzo, telefono, cellulare, note, preferenze); per ognuno di essi ho predisposto degli attributi aggiuntivi che prenderanno vita successivamente con l'ausilio di una funzione Javascript opportunamente integrata.

Scendiamo nel dettaglio, ecco la lista degli attributi da me aggiunti:

  • Obbligatorio [1|0]: stabilisce se il campo è obbligatorio o meno (es. se il campo è obbligatorio, il suo valore deve essere diverso da vuoto).
  • Dato[char|int]: stabilisce il contenuto del campo; se il contenuto di un campo è char il campo potrà contenere solo stringhe alfanumeriche, altrimenti se il campo è int potrà contenere solo numeri interi positivi/corretti.
  • Regex[pattern regex]: permette di validare il contenuto di un campo in base ad un'espressione regolare.
  • Msg_errore[stringa]: messaggio che visualizza l'utente tramite un alert Javascript se il valore inserito nel campo non è conforme alle regole specificate dagli altri attributi.

Ecco il codice HTML nelle parti che più ci interessano:

<form method='get' action="index.htm" name='form1'>
<td><input type='text' name='nome' value='' obbligatorio="1" msg_errore="Il valore inserito in questo campo non è corretto!!" dato="char" regex=""></td>
<td><input type='text' name='cognome' value='' obbligatorio="1" msg_errore="Il valore inserito in questo campo non è corretto!!" dato="char" regex=""></td>
<td><input type='text' name='indirizzo' value='' obbligatorio="1" msg_errore="Il valore inserito in questo campo non è corretto!!" dato="char" regex=""></td>
<td><input type='text' name='telefono' value='' obbligatorio="1" msg_errore="Il valore inserito in questo campo non è corretto!!" dato="int" regex=""></td>
<td><input type='text' name='cellulare' value='' obbligatorio="0"></td>
<td><input type='text' name='cod_fiscale' value='' obbligatorio="1" msg_errore="Il valore inserito in questo campo non è corretto!!" dato="char" regex="[a-zA-Z]{6}[0-9]{2}[a-zA-Z][0-9]{2}[a-zA-Z][0-9]{3}[a-zA-Z]"></td>
<td><TEXTAREA name="note" rows="10" cols="25" obbligatorio="0"></TEXTAREA></td>
<select name='preferenza' obbligatorio="1" msg_errore="Il valore inserito in questo campo non è corretto!!" dato="int" regex="">
<option value=''>Seleziona...</option>
<option value='1'>Moto</option>
<option value='2'>Auto</option>
</select>
<input type='button' value='Conferma' onclick="validazione('form1');">
<input type='reset' value='Annulla'>
</form>

Purtroppo questi attributi non sono conformi alle regole di validazione imposte dal W3C dal momento che non sono supportati. Per ovviare a questo problema basterebbe integrare i singoli attributi sotto forma di stringa all'interno di un attributo class, così da far passare queste nuove features come classi di stile (es. per il campo 'nome' <input type='text' name='nome' value='' class='obbligatorio__1 dato__char regex__'>) oppure inserire immediatamente gli attributi per ogni campo tramite Javascript al termine del caricamento della pagina HTML.

Nello script oggetto di questo articolo ho tralasciato queste cose preferendo dare priorità alla chiarezza e all'idea più che alla validazione finale della pagina.

Ritornando al codice, viene predisposto un form cui sarà assegnato un nome di identificazione; all'interno viene specificato un gruppo di campi con determinati attributi aggiuntivi che applicheranno alcune semplici regole di validazione tramite Javascript.
Queste regole entreranno in funzione al click sul pulsante "Conferma" che richiamerà la funzione Javascript "validazione" passando a quest'ultima l'identificativo del form.

Vediamo la funzione "validazione" nel dettaglio:

function validazione(nomeform)
{
//imposto la variabile che segnalerà l'errore
var error=0;
//prendo il contenuto HTML compreso nel mio form
var form_html=document.form1.innerHTML;
//controllo che il browser supporti questo tipo di funzione
if(document.getElementsByTagName)
{
//predispongo un array con tutti i possibili elementi che conterrà il form
var tipo_dati=new Array('input','textarea','select');
for(j=0; j < tipo_dati.length; j++)
{
var x=document.getElementsByTagName(tipo_dati[j]);
for(i=0; i <x.length; i++)
{
var campo=x.item(i).name;
//controllo che il nome del campo sia impostato
if(campo!='')
{
//istruzione uguale per entrambi i browser
var valore=x.item(i).value;
if(navigator.appName.indexOf("Netscape")>=0)
{
var test=x.item(i).attributes;
for(var a=test.length-1; a>=0; a--)
{
switch(test[a].name)
{
case "obbligatorio":
var obbligatorio=test[a].value;
break;
case "msg_errore":
var msg=test[a].value;
break;
case "dato":
var tipo_dato=test[a].value;
break;
case "regex":
var regex=test[a].value;
break;
}
}
}
else
{
var obbligatorio=x.item(i).obbligatorio;
var msg=x.item(i).msg_errore;
var tipo_dato=x.item(i).dato;
var regex=x.item(i).regex;
} if(obbligatorio==1 && valore=='')
{
alert(campo + '-> ' + msg);
error=1;
}
if(obbligatorio==1 && valore!='' && regex=='')
{
if(tipo_dato=='int' && isNaN(valore))
{
alert(campo + '-> ' +msg);
error=1;
}
if(tipo_dato=='char' && !isNaN(valore))
{
alert(campo + '-> ' +msg);
error=1;
}
} if(obbligatorio==1 && valore!='' && regex!='')
{
//prendo il pattern passato dal mio elemento HTML
var pattern=new RegExp(regex);
var result=valore.search(pattern);
if(result!=0)
{
alert(campo + '-> ' +msg);
error=1;
}
}
}//campo
}//for i
}//for j
}
else
{
alert('Il tuo browser non supporta questo tipo di funzione');
return false;
}
//Se tutto è andato a buon fine invia il form
if(error==0)
{
document.forms[nomeform].submit();
}
}//END

La funzione "validazione" riceve come argomento il nome del form a cui deve essere applicata; questo fa sì che l'analisi degli elementi del form per cercare determinati attributi coinvolga solo specifici form e non tutto il contenuto della pagina HTML, risparmiando cosi risorse. Questo stratagemma viene applicato utilizzando "document.form1.innerHTML", che prende tutto il codice HTML compreso tra i tag <form> e </form>.

Prima di analizzare il codice contenuto nel form viene verificato se la funzione "document.getElementsByTagName" è supportata dal browser: se così non è la convalida dei campi non potrà essere portata a termine.

Attraverso questa funzione verranno ricercati i tag specificati all'interno dell'array "tipo_dati" del form; una volta trovato uno di questi tag, se ne ricavano gli attributi standard con i loro valori (es. name, value, type etc.) ma anche quelli da me inseriti a cui assegnerò delle specifiche azioni in seguito.

Il riconoscimento avviene tramite questi semplici step:

a) La lista di tag trovati viene messa sotto forma di array nella variabile "x" usando questa funzione:

var x=document.getElementsByTagName(tipo_dati[j]);

dove tipo_dati[j] sta per uno dei tag da ricercare preso dal mio array tipo_dati popolato in partenza.

b) A questo punto l'array viene ciclato per tutta la sua lunghezza, immagazzinando di volta in volta il nome del campo trovato nella variabile "campo" con questa istruzione:

var campo=x.item(i).name;.

c) Avviene poi il riconoscimento del browser, in quanto Internet Explorer e Firefox hanno due modi di operare differenti per quanto concerne la lettura tramite DOM degli attributi di campo.

IE accede agli attributi utilizzando:

document.getElementsByTagName("nome campo").item("posizione").nome_attributo;

Ad esempio, per accedere al campo "obbligatorio" si utilizzerà la seguente istruzione:

document.getElementsByTagName(tipo_dati[j]).item(i).obbligatorio;.

Firefox invece necessita di un array contenente gli attributi del campo. Per fare ciò si utilizza la seguente istruzione

var test =document.getElementsByTagName(tipo_dati[j]).item(i).attributes

e poi si ciclano tutti gli attributi presenti nell'array "test"; intercettando il nome degli attributi di validazione da me aggiunti si salvano quindi i valori in alcune variabili:

for(var a=test.length-1; a>=0; a--)
{
switch(test[a].name)
{
case "obbligatorio":
var obbligatorio=test[a].value;
break;
case "msg_errore":
var msg=test[a].value;
break;
case "dato":
var tipo_dato=test[a].value;
break;
case "regex":
var regex=test[a].value;
break;
}
}

d) Una volta intercettati tutti gli attributi di validazione si può procedere con il controllo dell'input digitato dall'utente.
Ecco una ad una le varie sezioni:

1. Se l'attributo obbligatorio è settato ad 1 ed il campo è vuoto, sarà restituito il messaggio d'errore impostato per quel campo:

if(obbligatorio==1 && valore=='')
{
alert(campo + '-> ' + msg);
error=1;
}

2. Se l'attributo obbligatorio è settato ad 1 ed il contenuto del campo è diverso da vuoto, allora sarà eseguito un controllo sul contenuto, esaminando così se il valore inserito è un valore numerico oppure una stringa:

if(obbligatorio==1 && valore!='' && regex=='')
{
if(tipo_dato=='int' && isNaN(valore))
{
alert(campo + '-> ' +msg);
error=1;
}
if(tipo_dato=='char' && !isNaN(valore))
{
alert(campo + '-> ' +msg);
error=1;
}
}

3. Se l'attributo regex è settato con un pattern adeguato, sarà eseguito un controllo sul valore inserito all'interno del campo con un'espressione regolare:

if(obbligatorio==1 && valore!='' && regex!='')
{
//prendo il pattern passato dal mio elemento HTML
var pattern=new RegExp(regex);
var result=valore.search(pattern);
if(result!=0)
{
alert(campo + '-> ' +msg);
error=1;
}
}

4. Se, terminati tutti i controlli, il valore della variabile "error" sarà ancora a zero, verrà eseguito l'invio dei dati del form verso il server.

Considerazioni finali

L'esempio analizzato permetterà, a mio avviso, di fornire un punto di partenza per trovare una soluzione definitiva alla validazione dei form; nei passaggi esaminati risulterà infatti evidente come sia possibile semplificare il lavoro dello sviluppatore e dell'utente implementando poche righe di codice che prendono vita con Javascript.

L'esempio è disponibile per il download.

Ti consigliamo anche