Vai al menu/Go to main navigation | Vai al contenuto/Go to main content

Unobtrusive Javascript and form validation

UPDATE: 27/11/2006 (Comments n. 5 e 6)

Unobtrusive Javascript is not so complicated. In this article, inspired by the italian magazine Hacker Journal, we’re going to validate a simple login form before it’s posted to the server.

Some weeks ago, HJ’s CookBook survey reported an example of Javascript form validation code. The original example was a self-contained HTML file with a table layout and the Javascript code was inserted directly in the HTML (eg. <form onsubmit="return canSubmit(this)">). However the idea sounded interesting to me and with some make-up I came out with the following code.

You can see it in action online or you can download the full code.

Step 1: Component separation

The first thing to do is clean the page from unnecessary code and move all non-HTML code outside. Let’s start with an empty XHTML document and add links to the CSS and the Javascript code files.

<head>
    <title>Form Validation Example</title>

    <link type="text/css" rel="stylesheet" href="style.css" />

    <script type="text/javascript" src="validation.js" ></script>

</head>

The CSS file is very simple. I used a hint by Kevin Hale to obtain something prettier than the default browser rendering.

Step 2: Creating the form

Then we create the form using standard XHTML markup. I used the <fieldset> tag to group the controls, the <legend> tag to title the group and the <label> tag to name text fields.

<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>

The form’s action property is left blank, so the form is posted back to itself

UPDATE: 23/06/2008 1) As pointed out by Miki in comment n. 18, tag <label> binds to attribute id.

UPDATE: 23/06/2008 2) W3C Validator reminds me that attribute name is no more supported in XHTML 1.0 Strict.

Step 3: Attaching the events

As you can see, the form’s markup is just basic HTML code. All the Javascript code is inside the external file validation.js.

Initialization

The init() function is applied to the page loading event. The old HTML code <body onload="init()"> it’s been replaced with the unobtrusive code window.onload = init; within the external file.

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();
}

Validation

The validation process is performed by the canSubmit function. The function returns true in case of success (the form is then sent to the server) or false otherwise (the form is not sent to the server).

In this example we only care that the text fields are not empty, but we can check for all other information such as text length or specific formatted text (eg. email addresses).

It’s easy, isn’t it?

This solution has two main advantages: independence from Javascript code and separation between content, presentation and behaviour.

The page is independent from Javascript. If a user’s agent is not JS enabled, the form is posted directly to the server and it’s processed by server-side validation code, which must be executed anyway.

Each component (the HTML page, the CSS file and the JS code) can be edited independently from the others.

Also, all the code is supported by standard-compliant browsers: it’s been tested with IE5.01, IE5.5, IE6 and Firefox 1.5.0.1 on Windows XP and with Safari, Camino 1.0, Firefox 1.5.0.1 and Opera 9 preview on Mac OS X Tiger.

18 Comments to “Unobtrusive Javascript and form validation” (Post your comment)

  1. Toby Chu wrote:

    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.

    *

  2. Ragman wrote:

    Thanks Toby.

    In effect the first example I wrote used the Scott Andrew’s addEvent routine, 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.

  3. helmut wrote:

    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)

  4. Ragman wrote:

    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.

  5. Roberto wrote:

    Veloce e compatto, lo ho trvato ottimo per svolgere lezioni di informatica a non esperti. Ottima la presentazione didattica.

  6. Stephen Last wrote:

    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?

  7. Ragman wrote:

    Thanks Stephen, you caught a little bug!

    The code should be:

    loginForm.onsubmit = function () {
        return canSubmit(this);
    }
    

    I’ll fix it soon :)

  8. Stephen Last wrote:

    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.

  9. domenico wrote:

    sei grande continua cosi

  10. Paizo wrote:

    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.

  11. Ragman wrote:

    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.

  12. Giuseppe wrote:

    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?

  13. Ragman wrote:

    Ciao Giuseppe,

    per le select puoi fare così (es. di una select provincia):

    // recupero l'oggetto select
    var state = document.getElementById('state');

    // recupero il valore dell'elemento selezionato var selectedState = state.options[state.selectedIndex].text;

    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.html

    Buon lavoro

  14. JJ May wrote:

    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…

  15. Ragman wrote:

    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

  16. dev wrote:

    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

  17. Ragman wrote:

    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.

    // edit element class
    form.username.className = 'text error';

    // create p element error = document.createElement('p'); error.className = 'error'; errText = document.createTextNode('Enter user name'); error.appendChild(errText);

    // adding message form.appendChild(error);

    Hope that helps

  18. mikilugano wrote:

    Complimenti, solo un appunto, il tag label con for va a puntare l’ID di un elemento e non l’attributo name.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>