Web Matters

Javascript form validation – doing it right

When using Javascript for form validation, there is a right way, a wrong way, a very wrong way, and a suicidally wrong way! Unfortunately many sites use one of the wrong ways, including even some which claim to be form-validation tutorials. This page tries to help people in the right direction.

The essence is thus that Javascript validation is always optional. Since the validation must be on the server anyway, it is silly to insist that the user must have Javascript. Adding Javascript validation should help some readers and hinder nobody.

Having said that, there are actually two right ways, of which the better one is hardly ever used!

  1. Acceptable: validate the entered data when the submit button is pressed.
  2. Better in most cases, especially with large forms: validate on a field-by-field basis, and revalidate the whole form when the submit button is pressed. This also makes it easy to alert the user in cases where entered data is perhaps, but not certainly, incorrect – for example unusual characters in an e-mail address, or a birth year of 1907.

Example

Here is an example of how Javascript validation should work. (Note that this just a demonstration; it isn’t intended as a drop-in script, and anything you do will doubtless have its own requirements.)

It doesn't actually have any server script, so anything you type will be discarded on submission. Try it both with Javascript enabled and disabled.


Required
Required
 
Required. You can use spaces or hyphens if you wish.
   

How it works

I'm not going to describe all the workings in detail, as they are commented in reasonable detail in the code. If you aren't familiar with the basics of Javascript and forms, there are plenty of sites on the Web which can help. Instead I will point out the key features of this approach.

  1. It uses a standard submit button and onsubmit handler; therefore the submission still works if the user has no Javascript available.
  2. Validation is done by onchange handlers, so the user gets immediate feedback on each field. (Not onblur, which can lead to premature validation if e.g. a pop-up fires off, or the user wants to copy data from elsewhere.) The calls to the validation routines are repeated in the onsubmit handler, in case the user skipped over some fields.
  3. It makes minimal use of alert boxes: errors are written into the HTML. The user is not driven up the wall by alert boxes for every error, and the error message remains visible until he/she has finished the correction of the field.
    A single alert pops up if the user clicks 'Send' while there are still errors. This is necessary to give positive feedback.
  4. The script checks for older browsers and less well-endowed browsers. This is not to exclude them; on the contrary, it is to ensure that users of these browsers can also use the form – they just have to wait for the validation to be performed by the server.
  5. The detection of these older browsers is done by feature detection, not browser sniffing – this is much more reliable (and simpler as well!). For example, the script checks whether methods such as document.getElementById are defined, rather than checking whether the browser claims to be Firefox.
  6. The formatting of error and alert messages is done by setting the CSS class of the element concerned. This is both simpler and more maintainable than using FONT tags or setting CSS properties directly.

One thing I have not done is put up a positive OK indication by fields when they pass validation. My feeling is that this could be misleading, as one only really knows the field is OK after the server validation is complete. But in some circumstances it might be a good idea.

One other thing I have not done, which is rarely if ever a good idea, is to force the user to complete fields in a particular order, or to prevent him/her from leaving a field until it is correct. I do use the focus function to assist the user, but he/she is free to move to a different field if desired.

Auto-completion problem

There is one small problem that a couple of correspondents have pointed out to me. There is a bug in Internet Explorer (all versions, as far as I know) whereby the onChange event does not fire if the user makes use of auto-completion. There doesn't seem to be a good way around this. (I have found a couple of sites referring to the non-standard onPropertyChange event, but this fires on every keystroke, so is not of any use.)

The only option seems to be, if in a particular case this is likely to be seriously confusing to the user, to switch auto-completion off with the non-standard autocomplete attribute on the form. Or perhaps one could use IE Conditional Comments to at least give IE users a warning message.

How much validation?

Exactly how detailed client-side validation should be is a debatable point. There is little point in trying to make it really rigorous, since some aspects can typically only be validated on the server anyway. And since the aim is quick response to the user, it rather defeats the object to load the form down with many kilobytes of Javascript. On the other hand, if one is for example validating an e-mail address, I think one can do rather better than simply checking that an '@' is present somewhere in the string, as I have seen a couple of times.

On only one point do I have strong feelings: input should never be rejected due to the presence of leading or trailing white-space. It may be difficult for the user to see that the white-space is present, and failing to strip it off before validation is pure laziness on the part of the programmer. (This includes line-breaks, which may inadvertently be included if the user copies text from elsewhere; using ‘\s’ within a regular expression will look after this.)

There is of course much more to be said about validation in general. Witness the site designers who insist that credit-card start-date is a compulsory field, although some credit cards (including mine) do not have a start date. But this page concentrates specifically on the client-side aspects, so I'll leave the rest for another time.

Conclusion

Following the principles here will result in forms that are both more widely usable and more user-friendly than many of the forms on the Web today. Let's try to make the Web a better place.


Update, November 2004: another user requested an example of how to handle checkboxes. That seemed a good idea, so I have added a sequel page on that subject.

Update, June 2005: I've finally found a work-around for the fact that Internet Explorer doesn't (always/ever?) set the focus correctly. It turns out to be a timing bug in IE. I've inserted a 0.1 second delay in the focus setting and now it works correctly.

Update, February 2006: I’ll just mention here a point which confused a couple of correspondents: the table cell which receives the error message must always contain some text (otherwise it doesn’t get constructed properly in the DOM). If you don’t want to display any text, insert a non-breaking space ( ).

Acknowledgements:

thanks to the various subscribers to the newsgroups comp.infosystems.www.authoring.html and comp.lang.javascript who offered suggestions and improvements, especially Richard Cornford.

This page now has a Bulgarian translation, with thanks to Albert Ward.