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!
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.
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.
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.
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.
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.
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 ( ).
This page now has a Bulgarian translation, with thanks to Albert Ward.