I recently had the displeasure of being handed a rather large HTML document containing one large form,which I was to make look a little better and which needed validation. Seeing it almost make me cry, however. The main document looked like this:
]]>
I shortened it a bit, the original contains 14 Sections. The general Idea behind it, is to embed it into a Mapbender Application. For each section a piece of javascript fetches a HTML file similar to the following:
Section Heading
subheading
label

label

]]>
It would then be added beneath it's corresponding div. After that the jQuery UI Tabs plugin would make jumping to each section possible.
Apart form the fact that the Tabs plugin was broken and only showed the current tab for some reason,
I think a number of things are wrong with this approach and it's execution.
I try to be constructive
Validity
There is invalid markup in this form. That's completely unacceptable. Period. I spent the better
part of an afternoon fixing it.
Layout
This form uses tables for layout. That's a Sin.
The controls have no label. Instead the controls are paired with text via sibling <td> elements, which really makes no sense semantically.
Note the use of <br /> and - in a good layout the are usually unnecessary
The image "info_on.png" is used to provide some kind of information in an 'onclick' event. Which breaks if there's no javascript available - see below.
Obtrusive javascript
If the user has no javascript enabled the form does not work at all. One could argue that nowadays everyone has javascript enabled, so that's not a problem. And I would agree if it were essential for some functionality.
In this case however, you don't even get the form without executing some script. All you get is a form template. And even if the form was there, you could not submit it, because it is gutted and does not even have an URL it could POST to. All that is handled by javascript, without a fallback.
Sometime javascript is fundamental. For just submitting a form it is not. There might be advantages in helping the user fill out a form, and to perform client side validation to alert the user to errors she might have made.
If a form becomes unusable because javascript is not available, that's just flawed design. The way to avoid this, is to create without javascript, and then add it to enhance the form afterwards.
Form Control Naming
If you noticed, the "name" attribute if each control looks like an xpath. That's because on the serverside
an XML document is constructed from the form, and each control value is inserted at the specified xpath.
As a consequence, I can instruct the server to create arbitrary XML documents by modifying what I send to it.
This in itself is probably not bad, but it's a side effect one needs to be aware of.
It does however overload the name attribute by giving it functionality instead of just being a key in a key-value-pair. I am not sure that's a good thing.
Validation
For validation the jQuery validation plugin is used.
The first and largest problem is of course: it's client side only. The form is not validated on the server, the user is only notified with an alertbox if there's a problem with the database. This means users without javascript don't get their form validated at all (that's a moot point here though, see above). It also means that a malicious user could send whatever he wished to the server, bypassing the validation completely. As noted above this includes not only control values, but also control names. After all, the server only gets a message like this:
So as far as the server is concerned that's still unverified data.
Because the validation plugin was added after the form was already written. It doesn't fit 100% with the existing form. For example it depends on the form actually being submitted, instead our form grabs the values from the controls and sends the, via AJAX. The proper solution to this, is to override the forms' submit event.
All in all, I think this form is unnecessarily complex
Fixing it
To clear my conscience, the next day I decided to rewrite the whole form to the best of my ability. I am quite pleased with the Result.
Separating design and content
That means to create a document structure first and then style it.
This is the structure of one input element as it was:
Name

]]>
I converted it:
Name
Enter your name here
]]>
It does away with the tables, and it's less markup.
Applied to the whole document, it becomes something like this:
A Form
]]>
The labels use the 'for' attribute. When the label is clicked, focus shifts to the appropriate control, and because the label is wrapped around the control the user may click anywhere near the control.
Each fieldset has an id, that means we can link to it and use the menu to skip to the section.
This form is already usable without any added CSS, though the controls are not laid out very well.
Having a good element structure, makes adding some styling to it pretty easy, though.
I positioned the <ul> fixed, made the <label> display: block and the <label>'s child elements display: inline-block. This takes care of the most important layout issues. Read the source of the example to see the details.
Note how this technique allows the window- and font-size to be variable and still stay usable without the need for horizontal scrolling. I also moved the images that denote a field as 'required' to a style rule and made the information image a clickable link with target="_new".
No Javascript!
I used no javascript in the design of this form, it simply does not require it. The areas which in which it could provide some benefit here, however, are the following.
Validation
One obvious application is to validate the form before sending it, saving time and bandwith. It's also possible add incremental validation
Style
The jQuery tabs plugin can be used to convert the form from being scrollable to tab-style layout. This doesn't change the functionality very much, but provides a different look'n feel . I personally don't care for it. Note also how the design of the plugin requires a document structure like my form above.
Complex Data
If there are fields that contain data that requires a certain format, a piece of script can help the user enter it correctly. A datepicker is good example.
Summary
The original form isn't completely horrible. It gets a lot of things right:
- The basic structure is not that bad
- Client side validation is a good thing
- It gives users visual clues about required fields
But the execution is somewhat messy and more complex and not as nice as it could be. It also leaves the form inaccessible to anyone not using a normal webbrowser, say someone using a screenreader.
I tried to show a way to make the form have more semantic value and look similar, while doing all styling in a seperate stylesheet. I did not address validation and one feature the old other form has (duplicating sections of the form) and I will write something up about those issues later.
Comments? Questions? Tell me: karim+blog@malhas.de