Controlliamo i form con Javascript non intrusivo
UPDATE: 27/11/2006 (Commenti n. 5 e 6)
Utilizzare Javascript non intrusivo non è complicato. In questo esempio, ispirato dalla rivista Hacker Journal, controlleremo un semplice form di autenticazione prima di inviare i dati al server.
Nella rubrica CookBook di qualche settimana fa, veniva proposto un esempio di codice javascript per convalidare un form. L’esempio originale era un unico file HTML con layout a tabelle e il codice Javascript era inserito direttamente nella pagina (es. <form onsubmit="return canSubmit(this)">). L’idea mi è sembrata interessante e con qualche ritocco ho ottenuto il codice di questo esempio.
È possibile utilizzare l’esempio online oppure scaricare il tutto in un unico file.
Passo 1: Separiamo i componenti
La prima cosa da fare è separare dalla pagina tutto ciò che non è HTML. Creiamo un documento XHTML vuoto e aggiungiamo i collegamenti con il foglio stile e con il codice Javascript.
<head>
<title>Form Validation Example</title>
<link type="text/css" rel="stylesheet" href="style.css" />
<script type="text/javascript" src="validation.js" ></script>
</head>
Il foglio stile è volutamente molto semplice, ho utilizzato il suggerimento di Kevin Hale per ottenere qualcosa di più carino della visualizzazione standard.
Passo 2: Impostiamo il form
Creiamo il nostro form utilizzando del codice XHTML standard. Ho usato il tag <fieldset> per raggruppare i campi, il tag <legend>per dare un titolo al gruppo e il tag <label>per assegnare delle etichette ai campi di testo:
<form id="login" method="post" action="" enctype="text/plain" >
<fieldset>
<legend>Sign in to our account</legend>
<label for="username">User: </label>
<input class="text" type="text" name="username" id="username" size="15" tabindex="1" /><br />
<label for="password">Password: </label>
<input class="text" type="password" name="password" id="password" size="15" tabindex="2" /><br />
<input type="submit" value="Log in" name="send" tabindex="3" />
</fieldset>
</form>
Lasciando vuoto l’attributo action del form, esso viene inviato a se stesso.
UPDATE: 23/06/2008 1) Come fa giustamente notare Miki nel commento n. 18, il tag <label> va a collegarsi all’attributo id.
UPDATE: 23/06/2008 2) Il validatore del W3C mi ricorda cortesemente che l’attributo name non esiste più in XHTML 1.0 Strict.
Passo 3: Colleghiamo gli eventi
Come si può notare, nel codice HTML del form non è presente nessun collegamento a funzioni Javascript. Il collegamento è stato realizzato nel file validation.js.
Inizializzazione
Alla pagina viene associata una funzione Javascript da eseguire al caricamento. Il vecchio codice HTML <body onload="init()"> è stato sostituito dal codice non intrusivo window.onload = init; nel file Javascript esterno.
La funzione init() a sua volta associa all’evento onsubmit dell’elemento <form> la funzione canSubmit(this), alla quale viene passato il form stesso tramite il parametro this:
function init() {
//Attaching the onSubmit event to the login form
loginForm = document.getElementById('login');
loginForm.onsubmit = function () {
return canSubmit(this);
}
//Setting focus to the user field
loginForm.username.focus();
}
Validazione
La funzione canSubmit svolge poi tutto il lavoro di verifica del form e restituisce il valore true in caso di successo (il form viene quindi inviato) o false altrimenti (il form non viene inviato).
In questo esempio verifichiamo solamente che i due campi contengano del testo, ma è possibile verificare anche altre informazioni come la lunghezza del testo contenuto e la sua conformità a formati specifici come per esempio gli indirizzi di posta elettronica.
Facile no?
Questa soluzione ha due vantaggi principali: l’indipendenza da Javascript e la separazione tra i livelli di contenuto, presentazione e comportamento.
E’ indipendente da Javascript perchè il form viene spedito anche se nel browser dell’utilizzatore il supporto Javascript è assente o disabilitato. In tal caso ci si affida alla convalida eseguita dal server, che deve essere sempre eseguita.
E’ possibile modificare uno qualsiasi dei tre componenti (file HTML, foglio stile CSS, codice JS) indipendentemente dagli altri due.
Inoltre il codice utilizzato è compatibile con i browser più diffusi che supportano gli standard: è stato testato su Windows XP con IE5.01, IE5.5, IE6 e Firefox 1.5.0.1 e su Mac OS X Tiger con Safari, Camino 1.0, Firefox 1.5.0.1 e Opera 9 preview.
9 Maggio 2006, 20:20
It’s good to see standard compliant methods getting out, there are too many examples of bad javascript validation floating around now…
Anyone using this example in production should strongly consider using an addevent routine to push init into the onload event rather than using the straight assignment. Otherwise you may spend a few hours trying to figure out why your other onload events aren’t firing.
*
9 Maggio 2006, 22:00
Thanks Toby.
In effect the first example I wrote used the Scott Andrew’s
addEventroutine, but I wanted to keep this first script straight and simple.However you’re right: in a production enviroment the best choice is an addEvent function.
5 Luglio 2006, 15:00
Ciao molto bello il sistema di login,ma come funziona,cioeè come si fa ad inserire un user e una password che si colleghino poi alla pagina riservata. grazie anticipate a chi mi saprà rispondere!!!!!!(è urgente perche è da mesi che cerco un sistema di login….GRAZIE)
5 Luglio 2006, 15:22
helmut: questo esempio è solo una parte del sistema di login. Per farlo funzionare devi collegare il form ad uno script lato server (PHP, perl, ecc) utilizzando l’attributo
action, per esempio<form method="post" action="validate_user.php">.Sarà lo script a controllare se i dati inseriti sono giusti secondo un metodo che decidi tu, tramite un database o altro sistema.
18 Novembre 2006, 18:39
Veloce e compatto, lo ho trvato ottimo per svolgere lezioni di informatica a non esperti. Ottima la presentazione didattica.
24 Novembre 2006, 17:51
Thanks for this, I’m new to JavaScript and want to learn the correct way from the beginning.
One question – why when you submit the form, you get the alert saying “please enter your user name”, but then the form submits anyway. It doesn’t seem to stop the form from submitting if you leave it blank. Shouldn’t the “return false;” bit after the “alert()” and “focus()” do that?
27 Novembre 2006, 10:48
Thanks Stephen, you caught a little bug!
The code should be:
I’ll fix it soon
27 Novembre 2006, 15:16
Excellent - thanks…
Think I’m starting to understand this now. I’m about half way though Jeremy Keith’s DOM Scripting book which is really easy to understand, just like this post.
Thanks again.
1 Dicembre 2006, 20:46
sei grande continua cosi
19 Febbraio 2007, 16:13
good article.
if (field.value == “” || field.value == null)
should be:
if (field.value == null || field.value == “”)
so you’ll never check the value of a null variable.
20 Febbraio 2007, 12:08
Thanks Palzo.
I did some test on recent browsers (IE6, Firefox 2 win/mac, and Safari) and they all catch only the ‘empty’ value.
In effect the ‘null test’ is there to take care of some unpredictable behaviour I experienced with old browsers and old versions of Javascript.
29 Maggio 2007, 16:42
Salve. ho apprezzato molto il vostro articolo, e l’ho subito applicato a delle prove che sto effettuando per il mio futuro sito web. Avrei però alcune domande da fare.
Essendo agli inizi del Java Script, desidererei sapere come fare per inserire dei messaggi di avviso anche per delle selezioni e non solo campi di testo. E’ inoltre possibile validare il campo indirizzo mail?
Per entrambe le domande, quale codice devo inserire nel vostro esempio?
31 Maggio 2007, 18:43
Ciao Giuseppe,
per le select puoi fare così (es. di una select provincia):
Per convalidare le email ci sono tantissimi esempi più o meno validi o complicati. Uno che mi piace molto è la funzione
checkEmail()a http://developer.apple.com/internet/webcontent/validation.htmlBuon lavoro
9 Ottobre 2007, 23:09
I know most people would probably disagree, but this is dumb, and here’s why…
I get why we want to do js unobtrusively. However, there is a certain point where the unobtrusive js becomes more intensive than simply inserting a return confirm() or something in the onsubmit. Why write/store/load up a whole new function with a whole new event handler just to attach a quick validator? I’m not saying this idea is bad. I have a custom ajax library that locates
<
form class=”ajax”> and dynamically attaches on submit that will serialize the form inputs into a string and post it with AJAX. Furthermore, it will check if that form object already has an onsubmit property. If so, it will run that function prior to submitting with ajax. This preserves the simplicity of doing something like…
<
form onsubmit=”return confirm(‘Are you sure?’);” class=”ajax”>
which basically means that it will confirm you want to send before submitting it with ajax. Could it be any easier? I just don’t see why you would want to write a whole new function and event handler just to do something like return canSubmit(). Unobtrusive js is great when you use it to increase efficiency, but a little one liner isn’t going to hurt anybody…
11 Ottobre 2007, 17:11
Hi JJMay,
I agree with you. My approach in this post is very simple, not the best solution for a medium web application. I recommend the use of a valid JS library instead and yours seems very interesting.
However in certain situations, where you need just two or three functions for your script to run, this is maybe better than including a 96Kb JS file.
There’s also a nice article by Dustin Diaz on this subject: http://www.dustindiaz.com/roll-out-your-own-interface/
Good work
26 Marzo 2008, 13:37
hi, i’m pretty new with javascript and this is the sort of script i’ve been looking for. But i’ve read somewhere that you should try and avoid alert boxes. I was wondering if you could edit the script in which instead of alert prompts the script highlights the input boxes in red and show a message beside them. Is that possible ?
I’ll use this script now but would much appreciate any help on the above question …
thanx
22 Aprile 2008, 14:33
Hi dev,
as an example, you can use the following code as a starting point to replace the alert statement.
It adds a CSS class to the username input field and adds a paragraph with class error containing a message.
Hope that helps
6 Maggio 2008, 07:27
Complimenti, solo un appunto, il tag label con for va a puntare l’ID di un elemento e non l’attributo name.