Introduction

The most monotonous entities in the known universe, forms, are a staple of every web programmer’s balanced diet. Whether we like them or not, forms are the gatekeepers to our site’s goodies and often their design alone determines whether a user will try what you’re selling or simply walk away. Without pomp or circumstance, here are ten tips to transform your plain vanilla into double chocolate chunk with marshmallows.

The Code

The code examples below will not work “as is.” They are dependant on an external library, prototype.js with addEvent included. Additionally, the functions below need to be attached to events, such as onclick or onmouseover . Check back for a downloadable example file.

1. Remember Your Markup

We’ve notice a lot of people forgetting to use the tools that are already made accessible to them by the very medium that they work in. And so we’ve highlighted a few HTML elements below that are made especially for forms. Just to refreshen the ol’ web noggin.

Label

A label is used to attach information to a control. If you focus on a label, its associated control will gain focus. This is useful when a user clicks on a label name and the associated field gains focus.

<label for="email">Email: </label> <input type="text" id="email">

or

<label>Email: <input type="text" id="email"></label>

Fieldset

“The FIELDSET element allows authors to group thematically related controls and labels. Grouping controls makes it easier for users to understand their purpose while simultaneously facilitating tabbing navigation for visual user agents and speech navigation for speech-oriented user agents. The proper use of this element makes documents more accessible.” W3C Recommendation

Legend

“The LEGEND element allows authors to assign a caption to a FIELDSET. The legend improves accessibility when the FIELDSET is rendered non-visually.” W3C Recommendation

Tabindex

“This attribute specifies the position of the current element in the tabbing order for the current document. This value must be a number between 0 and 32767. User agents should ignore leading zeros.The tabbing order defines the order in which elements will receive focus when navigated by the user via the keyboard. The tabbing order may include elements nested within other elements.” W3C Recommendation

Accesskey

“This attribute assigns an access key to an element. An access key is a single character from the document character set. Note. Authors should consider the input method of the expected reader when specifying an accesskey.” W3C Recommendation

Password

By adding type=”password” to your input field, characters entered will be transformed into a series of asterisks.

“Application designers should note that this mechanism affords only light security protection. Although the password is masked by user agents from casual observers, it is transmitted to the server in clear text, and may be read by anyone with low-level access to the network.” W3C Recommendation

2. CSS

This isn’t new, but CSS can turn your eye sore of a form into something negative fugly. There is no need to reinvent the wheel here, so check out the following sources on enhancing your form with some CSS and a little Javascript.

Style Those Buttons - The Man In Blue shows us how to make those buttons not look so cheap.

Niceforms - Niceforms does a great job of turning that ugly form into something much more tolerable using a little CSS action.

Hide Optional Fields - In this example, a little CSS and Javascript is used to make a form better looking and more usable.

CSS Forms - Jeff Howdens shows us how to create a well layed out and styled form without using tables.

3. AutoTab

When navigating through a form, the user traditionally presses the tab button in order to advance to the next form control. This AutoTab function automatically sets the focus to the next control after the control’s maxlength is reached. This allows for the user to no longer manually tab through fields with a maxlength. This function is particularly useful for fields such as social security or phone numbers containing a character limit for each input field. For example, after a user enters the area code of a phone number, the form automatically tabs to the next input box allowing the user to continue entering their phone number without interruption.

To flag an input element to be autotabbed, you only need to include three things in your markup: tabindex, className of autoTab and maxlength.

<input type="text" name="areacode" class="autoTab" tabindex="1" maxlength="3" />

On page load, it’ll attach the events to input fields for autotabbing. If a field has a maxlength and that maximum is reached, the focus is automatically set to the control with the next highest tabindex value. Here’s a quick look at our function, autoTab() :

function autoTab(e) { if(this.value.length == this.getAttribute("maxlength") && e.KeyCode != 8 && e.keyCode != 16 && e.keyCode != 9) { new Field.activate(findNextElement(this.getAttribute("tabindex"))); } }function findNextElement(index) { elements = new Form.getElements('shippingInfo'); for(i = 0; i < elements.length; i++) { element = elements[i]; if(parseInt(element.getAttribute("tabindex")) == (parseInt(index) + 1)) { return element; } } return elements[0]; }

Two things worth noting:

You could also use input.form[(getIndex(input)+1)].focus() , but that causes a weird javascript error when using Firefox. An example of this can be seen at The Javascript Source.

When a user presses shift-tab, the previous element should still get focus, and autotab with automatically disable.

4. Field Information

It’s always good policy to provide information describing a field’s requirements and restrictions. How else is the user going to know a password must have 3 capital letters, an exclamation point and be somewhere between 6 and 17 characters long? Inspired by the forms used over at Tangent, we came up with some additional suggestions.

Store all related information in a fields label tag. You can place a className of required, an accesskey, and a descriptive title in there, so that all information is in one place. This makes it easier to roganize, and easier for JavaScript to pull from.

We choose to use onfocus instead of onmouseover when displaying information to the user. While mostly personal preference, it is still nice to know that the proper information will be displayed on the field with focus rather than where the mouse is.

It is easier to give labels an id similar to the field they related to. For example, if a field is named fname , call the label lfname . It makes things much easier on the JavaScript side to pull information. You can see the labels title being accessed below: p = document.createElement("p"); p.innerHTML = $("l" + this.id).title; span.appendChild(p);

5. Error Displays

When a user makes a mistake, it’s your duty to show them errors quickly and efficiently. Here are some ideas to make your forms display errors better:

Don’t just show the user one error. If they left 3 required fields blank, make sure that you tell them they have three errors, this way they can correct them all in one fell swoop.

Provide as much information to the user beforehand as possible. Examples of this would be marking a field as required, or explaning the minimum password length (See #2 above).

Be aware of the three validation options at your disposal: 1) you can give responsive feedback straight from the JavaScript. The user benefits from instant feedback, but you will have to duplicate your validation functions on the client and server. 2) You can provide Degradable Ajax Validation that gets rid of the duplicated code, but increases the server load. 3) You may validate only on form submit which leaves you with no duplicated code, no additional server load, and unfortunately, no instant feedback.

Put some effort into the display of your error messages. Make them bold, noticable, and throw in a bit of creativity. It is also best to stick with colors that the user is comfortable with:red for errors, yellow for warnings, green for success. Obviously you can switch those up based on your evaluation, but going to far and making an error message pink could cause some confusion.

6. Postbacks

There is nothing worse than filling out a form, encountering an error, and having to retype all of your information all over again. In order to save your users from needless frustration, we need to ensure that all data is preserved. This means if there is an error, the fields should be repopulated. If we have a multistep form, back and forward navigation should also keep the form populated. A common approach is to set a form’s action to it’s current URL. That way, you can read in the form value and populate the fields immediately if there is an error. For example, just set the value to the post:

<input type="text" name="fname" value="<?=$_POST["fname"] ?>" />

And the field will be populated. If there is no error, just redirect the page to the form completion page.

7. onFocus

Visual cues, such as changing a field’s border color, help show the user which field has focus. CSS provides an easy solution for adding borders with the border selector, but this feature isn’t currently supported in IE and doesn’t work at all with select elements. Our solution creates custom borders and backgrouds by adding a span to each form element using a little J-Juice.

The concept here is that by enclosing our form element within a span, we can produce a unique effect. Don’t worry, you don’t need to hand code the span — this unobtrusive JavaScript function will dynamically add and remove it automatically. The nice part is that the span can have background images, borders and any other desired combination of the two to create an effect that will work on text, textarea, and select elements. Here is how everything looks when it is done:

<span class="focus"> <input type="text" id="fname" name="fname" /> </span>function showFocus() { this.parentNode.className = "focusHover";function hideFocus() { this.parentNode.className = "focus"; }

The reason a state is needed for the span when the field does not have focus is to prevent shifting of the page. For example, if our custom span has 3 pixels of padding onfocus , we need 3 pixels of transparent padding when there is no focus, so that we do not see form elements “jumping” as the user navigates them.

8. Label Click

When a label receives focus, whether it be through onclick or through accessKeys, the associated element specified in the labels for attribute should receive focus also.

When a LABEL element receives focus, it passes the focus on to its associated control. W3C Recommendation

Unfortunately, this is not guaranteed in all browsers. To remedy the situation, a simple JavaScript function will do the trick:

function initLabels() { labels = document.getElementsByTagName("label"); for(i = 0; i < labels.length; i++) { addEvent(labels[i], "click", labelFocus); } }function labelFocus() { new Field.focus(this.getAttribute('for')); }

9. Double Submit

Nooo! Our user has submitted the form twice, probably because the site did not respond fast enough. Not only will the data be processed twice, but the last submission will be the active submission which often will provide errors that will confuse the user even more. Three things to keep in mind for this situation:

If JavaScript is enabled, use it to submit the form. After one submission, disable the button.

If JavaScript is not enabled, provide your users with a clear message asking them not to submit critical data more than once.

Do what you can on the server to prevent the processing duplicate information. Track payments, accounts, etc and flag them when an action has occured. This way, the second round of processing will just be ignored.

10. Leftovers

And we’re going to close this off by highlighting some awesome links to some features people have already implemented, or could implement. You may not need them in your particular situation, but they’re definitely lifesavers when you do.

Mini Calendar - Whenever there is a date field, it is always best to provide a popup calendar. Ideally, this calendar will not open in a new window, and will be responsive. To get started, Dynarch has the best solution.

Combo boxes - The element that missed the HTML cut is the half select, half text input breed known as the combo box. This concept allows the user to type in their own option if they can’t find what they’re looking for in the drop down. Take a look at Upgrade Your Select Element to a Combo Box to see how we approached a solution.

Visual Maps - Just like the popup calendar, popup maps can also be effective. Take a look at Orbitz, and click on airport code. That takes you to a text listing of all airports. This could easily be a dynamic in page popup that displays a clickable map, which in turn popualtes the field when clicked.

These are some ideas to get you started. Please let us know if you have more to add to the list.