Trimming form fields

Web forms often ask users for both essential and non-essential (marketing purposes and research) information. Long and complicated forms can often slow down the progress through a web site and in the case of e-commerce, can seriously hinder the sales process.

Wouldn’t it be a cool idea to give users the option to hide these optional fields at their own discretion, and with a clever use of Javascript, the DOM and some CSS we can.

In this tutorial, I’ll make an accessible form with only a sprinkling of additional mark-up. I’ll add minimal CSS to maximum effect and provide users with a method for removing optional fields. I’ll also ensure that the form ‘works’ for users whose browsers or user-agents do not support Javascript or CSS, ensuring that the form is as accessible as possible. The form will also have a complete separation of content, presentation and behaviour. Before we crack on, here a sneaky peak at the finished result.

Mark-up

First I’ll set up a basic contact form:

<form id="example-form" method="post" action="">
<label></label>
<input />
<br />

Etc.

</form>

To enable the field toggling, I’ll enclose optional fields and respective labels in divs with a class="fm-optional":

<div class="fm-optional">
<label for="fm-forename">First name</label>
<input type="text" name="fm-forename" id="fm-forename" />
<br />
</div>

I’ll now add an empty paragraph with a unique ID above the form which will become a toggle switch later on.

<p id="linkContainer"></p>

What about required fields?

Visually ndicating whether a field is required isn’t useful for people who use text browsers or screen-readers so I’ll add “(Required)” to required fields’ labels:

<div>
<label for="fm-surname">Surname (Required)</label>
<input type="text" name="fm-surname" id="fm-surname" />
</div>

That’s it! A contact form that contains only a smattering of additional mark-up and where the class and ID names relate to content, rather than presentation or behaviour.

Adding behaviour

First I’ll make use of that empty place holder <p id="linkContainer"></p>. The cool part about my script is that by using the DOM, the anchor and link text that toggle optional fields are only created if Javascript is available. The script first generates the text that is displayed as the page loads:

toggle.appendChild(document.createTextNode('Remove optional fields?'));

Then it generate the “Display” and “Remove” fields link text:

this.firstChild.nodeValue = (linkText == 'Remove optional fields?') ?
'Display optional fields?' : 'Remove optional fields?';

Finally I’ll set the class name for all optional fields to 'fm-optional'.

if(tmp[i].className == 'fm-optional') {
tmp[i].style.display = (tmp[i].style.display == 'none') 
? 'block' : 'none'; }

Voila! A highly usable and accessible—it even works in JAWS—form which enables users to switch off optional fields, speeding up online transactions. Take another look at the completed form.


Replies

  1. #1 On July 6, 2004 11:04 PM Ryan Brill said:

    Very nice. Definitly enhances the usability of long forms, as people can quickly see what they need to fill out and what is optional.

  2. #2 On July 6, 2004 11:07 PM andrew said:

    Very impressive, user-friendly, and useful. This can really come in handy with the super-beefy "Review Your Case" form for lawyers or a contact form with additional optional survey information.

    Btw, the 'Download' links on the finished results page are pointing incorrectly to... (ed: Fixed, thanks Andrew)

  3. #3 On July 6, 2004 11:10 PM Justin French said:

    You can possibly hear my applause from way down here in Australia right now. Very nice work.

    Of course, it could be argued that if it's all optional information, it could just be removed from the form forever, saving everyone a lot of grief, but this technique has a lot of other applications, like a "show full posts" or "show only excerpts" button on a blog.

    The dynamic JavaScript link is the perfect icing on the cake too.

  4. #4 On July 6, 2004 11:32 PM Colly said:

    Hmm, that's going into the content management system tomorrow Andy. For most projects, users seem to want to get registration out of the way and start using a site, wishing to fill out their profiles at a later date, or once they've seen what others do. This is where such a method comes in handy.

    I've been using a DOM expand/collapse on other elements for a while, but you should see how unsemantic it was. Hey, what about a definition list for the form data - get rid of those break tags for good (guess who's reading Cederholm at the moment?!)...

  5. #5 On July 7, 2004 12:40 AM Keith said:

    That's great! I'm all about simpler forms as I find them not only one of the harder parts of my own user-experience on the Web, but also one of the harder parts of Web design and development.

    My "rule" is that if you don't use a bit of information, you shouldn't be asking the user for it.

    Then again, what I consider "essential" isn't the same as what my stakeholders and clients think is "essential."

    Techniques like this, when applied based on well thought out goals help us to achieve that hard to reach balance good Web designers strive for.

    Nice work.

  6. #6 On July 7, 2004 02:39 AM Cameron Adams said:

    I can just see my nemesis in the marketing department now:

    ""Oh yes, another form with which to deviously collect the information which our CRM database feeds on!"

    (laughs maniacally)

    "Hang on, what's this button here? ... WHAT!? Customers able to easily sidestep my malevolent collectors of personal information?"

    (rings Cameron)

    "Remove it, foul underling!"

  7. #7 On July 7, 2004 10:17 AM Tim Parkin said:

    it's very cool but getting management to sign off on 'look, we can make it easier for the customer to avoid our crm system and then we won't have to send out direct mail to them' might go down badly.

    How about a favelet that understands what form elements have been marked as essential using asterixes etc (maybe covering 90% of occurences on the web through fuzzy matching) that you can then use on ANY form. You could even use javascript to force the tab order to skip the ones you don't want.

    I'd love that on my google bar!

  8. #8 On July 7, 2004 10:52 AM Steve Potts said:

    Andy, I like this. A lot. From an accessibility perspective - and like many people here know - providing accessible content isn't just about ticking boxes or (heaven forbid) relying on running an automated evaluation tool.
    This is a solution that reduces complexity. Reducing complexity is of benefit to those visitors with cognitive disabilities just as much to those with not much time to spend on a particular task, such as form filling. Not enough time? Yes, it's a disability too.
    Indeed, the solution does work in JAWS, and it (peculiarly) fails in IBM HPR, though "gracefully" without catastrophic effect, but this is much more than covering all browsers; it's a concept, and a jolly good one at that.
    Well done.

  9. #9 On July 7, 2004 04:35 PM Richard@Home said:

    Marvelous stuff :-)

    One minor ammendment might be to chage the line:

    if(tmp[i].className == 'fm-optional')

    to

    if(tmp[i].className.indexOf("fm-optional")!=-1)

    as this will allow you to specify multiple classes in your divs:

    [div class="fm-optional additional-class another-additional-class"]

    (BTW your comment box could so with being a shade wider ;-)

  10. #10 On July 8, 2004 02:01 AM Simon Willison said:

    Very nice! I like the idea (though I doubt marketing people will) and the implementation is very clean. That said, it's possible to achieve the same effect without having to loop through all of the divs on the page: dynamically change a class on an element containing all of the divs you want to toggle, then target them and alter their visibility using a CSS rule. I've written the technique up on my SitePoint blog (using your code as a base) as it's a really powerful concept, and one I'd never really thought about much before: http://www.sitepoint.com/blog-post-view.php?id=179923

    Thanks for the inspiration!

  11. #11 On July 8, 2004 08:08 AM Jan Korbel said:

    I like this idea and it is beuty to see how simple that form looks. BUT in reality, if you want to let your users to switch off the feilds so easily, why to even put them there? I mean, most of the users will just switch them off and not fill-in them. Am I wrong?

  12. #12 On July 8, 2004 09:53 AM Colm said:

    Interesting Article... but

    One of the links returns a 404 just above the 'Adding the behavior' heading... (ed: Fixed, thanks Colm)

  13. #13 On July 8, 2004 04:54 PM Jules said:

    Andy: Pretty cool. Hmm, let's see how this adds up: Accessibility advocate and guru + XHTML guru + CSS guru + JavaScript guru = ??? damn, my calculator blew a fuse.

    Praise aside, I am not convinced though that JavaScript, however, sophisticated, and Accessibility go hand in hand in this type of scenario. If a JAWS user clicks on the "hide optional" link, will the optional entries disappear? I recall reading that JAWS buffers a page within itself: if that is true, then a JAWS user does not benefit from the code and has to read through the content to determine what or what is not required.

    I should really do a test to confirm this but in the mean time, if anyone else can confirm or deny my assumption, that would be great.

  14. #14 On July 8, 2004 05:04 PM Colly said:

    In response to Jan's comment (and Keith's not-for-client perspective), I have built a few community sites where users definitely, definitely DO go back and start playing with the other form fields - think of download communities, membership-based forums etc. Initially the user is desperate to just get on board, later going back to interact more. Or, what if at first you don't need a particular field (say an alternative billing address) but later you do need it. Oh no - you can't, because all optional fields were outlawed in the Great Formfield Prohibition of 2004!

    It really does depend on the brief and what info you require, but it's simply not possible to ONLY provide required fields across ALL builds. Give users, clients and developers some choices...

  15. #15 On July 8, 2004 06:21 PM Jan Korbel said:

    Colly: Good thoughts, thanks.

  16. #16 On July 8, 2004 09:50 PM Patrick H. Lauke said:

    good idea, but maybe a nitpicky comment: why use <div class="fm-optional"> when you could use a semantically marginally more meaningful <fieldset class="fm-optional"> instead?

  17. #17 On July 9, 2004 02:36 AM Malarkey said:

    @ Jules: Javascript guru? Thanks, but the fabulous Brothercake should take most of the credit for the Javascript parts of this column.

    @ Pat and Colly: I decided to wrap the form elements in <div>s as I wanted to 'hide' specific fields rather than whole fieldsets and <div>s seemed more semantically neutral than <dl>s.

    @ Richard: I never expected that anyone would actually want to read my humble ramblings, let alone want to comment... On the next fiddle I 'll look at the comment form again...

    @ Simon Willison: Wow, you are much cleverer than me, to be sure! But your solution has sparked a few ideas that I am going to experiment with. I'll report back here if anything useful turns up.

  18. #18 On July 11, 2004 08:21 PM SirGUI said:

    If it's not essential don't put it there. Saves your time, save my time.

  19. #19 On July 13, 2004 06:18 PM [m] said:

    Reminds me of http://www.quirksmode.org/dom/error.html and http://www.quirksmode.org/dom/usableforms.html .

  20. #20 On July 13, 2004 06:26 PM [m] said:

    And an explanation that goes with the second link:
    http://digital-web.com/articles/forms_usability_and_the_w3c_dom/

    :)

  21. #21 On July 13, 2004 07:27 PM Malarkey said:

    @ [m]: If that is in fact your *real* name ;)

    Two good articles there that I had not come across before, thanks for adding them to the discussion.

  22. #22 On July 15, 2004 06:08 AM Pintu Sharma said:

    Very Nice and very differnt approach told in a unique way.
    Keep it up.