Perhaps the most important feature of forms is one that’s completely unspecified in HTML: validation.
It used to be that all problems were handled on the server. HTML and HTTP were just the go-between and didn’t interfere with anything except, for example, the maximum length of a given text field.
Forms are funny things, and people are even funnier. The longer and more complex a form gets, the more likely that something is going to be wrong with what is submitted. It’s missing a required field. A zip code field has too few digits or isn’t relevant (for the 95% of people who don’t have mailing addresses in the U.S.). Or maybe the perfectly valid credit card is perfectly out of credit.
JavaScript has made itself invaluable when it comes to most error conditions; so much so, in fact, that we consider client-side form validation more or less mandatory. What used to be a reasonable delay—the round-trip to the server to find out the results of your form—is now a real inconvenience, especially when your problem could have been fixed immediately.
Communicating error and warning conditions to users is not a standard process—but it is something that you will need to do frequently enough that you should have a plan. Here, too, we need to make sure that the plan includes the most inclusive ways of notifying users of their errors.
The first step you should take with your forms validation is to determine what could possibly break. Here are some of the obvious potential failures:
A required field is blank.
A numeric field contains letters, or vice versa.
A checkbox (for example, indicating that you have read the Terms and Conditions) has not been checked.
A credit card field does not contain the correct number of digits or fails mod-10 validation (a simple algorithm to check that a card number isn’t an obvious fake).
A credit card number doesn’t match its type (Visa starts with 4, MasterCard with 5, etc.).
There are less obvious ones to prepare for as well:
An expense report requires a decimal figure.
A date, phone number, email address, or URL field needs to be formatted.
The subject line of an email is empty.
A value is outside of a given range (e.g., a 7 on a scale of 1 to 5).
Each of these falls into one of three categories:
It’s possible to test each field after the user is done entering data, but this can cause unwanted side effects. For example, let’s say you check every field of your form each time a user hits the Tab key, and alert the user if any field is invalid—a common practice on the Web. Your validator detects that the user skipped over a field, and an error message pops up. And then another. And another. Each time the user changes fields.
Simple enough, you say. The user can just mouse back to that field and fix it. Then, what does someone who’s using only a keyboard—or a keypad—have to do? She’ll have to arrow or tab all the way back to the offending field—getting hit with an alert box every step of the way.
It’s better to validate your form just in time. When you’re about to send a message to the server is when you should inform the user of any changes he needs to make.
Required fields need to be marked somehow. In HTML 4.01, there’s
no semantic markup for that, so we have to wing it. Put an asterisk
inside the label
element of each form field that’s
required. Better yet, put the word “Required.” Or, if you’re short on space,
you could insert an image of an asterisk, and go a little bit out of the
way to inform screen-reader users of the constraint:
<img src="asterisk.gif" alt="Required field"/>
How you notify the user of errors also has an impact. JavaScript alert boxes are fine but only if there’s one of them. If you have 15 errors you want a user to solve, employ that one alert box to tell her how many things she’ll have to fix.
Another thing that you can do is set the focus on the form field containing the first error. Providing text that indicates what is wrong, in close proximity to and programmatically associated with the field, is a good approach. That way, people using smaller displays as well as those using screen readers don’t have to scroll to the top or bottom of the screen to be reminded which field is incomplete.
What about formatting issues? Fix them yourself. Users aren’t happy when they enter their phone number with dashes, only to be told they need to enter it with parentheses, or that they have to enter superfluous dashes to their credit card number. You’re the one taking the money. And you know that 10 digits add up to a valid U.S. phone number and that 16 or 17 digits make up a valid credit card number. Shouldn’t you be doing some of the work instead of raising the hackles of your customers?
Keep in mind that client-side validation doesn’t protect you from having to check user input on the server. If you don’t, you may have problems ranging from a mismatch in constraints between the JavaScript validation and your database, to security exploits attempting to bring down or take over your server. If JavaScript is off or unavailable, users may unknowingly bring about these conditions. Always check what you receive, and prepare to generate error messages matching the ones you’re creating on the client side.
Remember Postel’s Law. We opened the chapter with it: “Be conservative in what you do; be liberal in what you accept from others.” The late Jon Postel was a really smart guy, and the principle that bears his name has been reconstituted throughout the specifications that run the Internet. Another IETF Request for Comment, RFC 1122, expands on Postel’s Law in a way that syncs nicely with the needs of server-side validation:
Software should be written to deal with every conceivable error, no matter how unlikely; sooner or later a packet will come in with that particular combination of errors and attributes, and unless the software is prepared, chaos can ensue.[...] Adaptability to change must be designed into all levels of Internet host software. | ||
--http://tools.ietf.org/html/rfc1122 |