LearnStreamline your Forms with Widgets

Jason Long
writes on February 12, 2008

Share with your friends










Submit

We all know that people don’t like filling out forms online, including the folks who design and build them. Most good web designers working today know to keep them as concise and painless as possible. A minimalist sign up process on your shiny new web app is sure to produce a higher sign up rate than one that asks for a dozen pieces of irrelevant information.

Sometimes, however, you’ll want to develop a form that truly benefits from a large number of options. Let’s design a search form for a fictional used automobile site. Presenting every option in your database would probably be messy and intimidating. Just one section might look something like this:

Messy

An Alternative Presentation

There may be times when keeping all of the available options visible makes the most sense. Let’s assume for the time being, however, that you want to package the search options into a neater display.

Neater

Using this technique, we’re able to save valuable screen real-estate and the user is, hopefully, less frightened by all those checkboxes. In addition, you’ll have much more freedom to style your dropdown controls to match the look and feel of your application.

Building the Widget

This technique doesn’t require a fancy graphics treatment. You could easily use vanilla HTML elements and wire up the interaction elements with Javascript (as we’ll discuss below) and you’ll be good to go. However, if you’re wanting that little extra flair, let’s jump into Photoshop (or your graphics editor of choice).

I’ve built my widget to a fixed width with the idea that it’ll be smart enough to grow taller to accommodate longer text. Here’s how the plain widget looked:

Plain Container

And with the dropdown “trigger”:

Container and trigger

As I mentioned, we want the widget to be able to expand vertically so that longer text doesn’t dangle outside it. We’ll split our image into top and bottom pieces and stretch the top one out so it’s tall enough to hold the fullest possible amount of text.

Top Piece

Top piece

Bottom Piece

Bottom piece

Be sure you don’t simply resize the image to be tall enough since it will distort your masterpiece. Simply select one horizontal row, copy it, paste it, and use the transform tool to create the “filler” region.

Styling and Wiring

Now it’s time to create the HTML, CSS, and Javascript needed to make your widget come to life. In its most basic form, there is a wrapper container:


<div class="dd_wrapper">
<div class="dd_bottom"></div>
</div>

The dd_wrapper class will contain our top background image and dd_bottom will contain the bottom one.


.dd_wrapper {
  color: #fff;
  width: 169px;
  background: url(../images/dd_top.gif) top left no-repeat;
  font-size: 11px;
  padding: 11px 30px 10px 14px;
  position: relative;
  line-height: 1.3em;
  min-height: 17px;
}

.dd_bottom {
  width: 213px;
  height: 18px;
  position: absolute;
  bottom: -1px;
  left: 0;
  background: url(../images/dd_bottom.gif) top left no-repeat;
  z-index: 0;
}

There’s nothing too fancy going on here. The width of dd_wrapper is accounting for the image width minus the left and right padding (213 – 30 – 14 = 169). The right padding is larger to allow room for the dropdown trigger graphic. The position attribute is set to relative so that we can absolutely position our other elements within in. The dd_bottom class is anchored to the bottom left of the parent container and its width is left at 213px since there is no padding for it. We specify a height of 18px to match that of the bottom image so that it doesn’t collapse and disappear due to having no inner content.

Next, let’s add our dropdown trigger and a span wrapper for our text label.


<div class="dd_wrapper">
<span class="inner">
Engine <span class="light">(6 cylinder, 8 cylinder)</span>
</span>
<a href="#" class="dd_toggle" title="Change">
<img src="../images/dd_toggle.gif" alt="Change" />
</a>
<div class="dd_bottom"></div>
</div>

The inner class will hold our text and the dd_toggle link is positioned on the right hand side.


.dd_wrapper .inner {
  position: relative;
  z-index: 100;
}

a.dd_toggle {
  position: absolute;
  top: 11px;
  right: 13px;
  z-index: 10;
}

.dd_wrapper .light {
  color: #a3bfe9;
}

The inner class is relatively positioned so that the z-index rule works properly. These are used to keep the text above the background image of the dd_bottom container.

Now it’s time to add our dropdown panel. It will be hidden by default and the dd_toggle link will call a Javascript function to handle the showing and hiding of the panel.


<div class="dd_wrapper">
  <span class="inner">
    Engine <span class="light">(6 cylinder, 8 cylinder)</span>
  </span>
  <a href="#" onclick="toggleDropdown('engine_options');return false;" class="dd_toggle" title="Change"><img src="../images/dd_toggle.gif" alt="Change"/></a>
  <div class="dd_bottom"></div>
  <div id="engine_options" class="dd_option_panel" style="display:none;">
    <p>Select which engine options you are interested in.</p>
    <ul>
    <li><input type="checkbox" id="engine_4" />
      <label for="engine_4">4 cylinder</label>
    </li>
    <li><input type="checkbox" id="engine_6" checked="checked" />
      <label for="engine_6">6 cylinder</label>
    </li>
    <li><input type="checkbox" id="engine_8" checked="checked" />
      <label for="engine_8">8 cylinder</label>
    </li>
    <li><input type="checkbox" id="engine_10" />
      <label for="engine_10">10 cylinder</label>
    </li>
    <li><input type="checkbox" id="engine_12" />
      <label for="engine_12">12 cylinder</label>
    </li>
    <li><input type="checkbox" id="engine_hybrid" />
      <label for="engine_hybrid">Hybrid</label>
    </li>
    <li><input type="checkbox" id="engine_elec" />
      <label for="engine_elec">Electric</label>
    </li>
    </ul>
    <p class="buttons">
      <input type="image" src="../images/save_choices.gif" onclick="toggleDropdown('engine_options');return false;"/>
    </p>
  </div>
</div>

The toggleDropdown() function will toggle the requested panel and it will also ensure that all other panels are hidden. This way, if one panel is open and the user clicks the trigger on another dropdown widget, only the newest panel will appear as open. I am using the Prototype Javascript library here, but this could easily be adapted to any other implementation.


function toggleDropdown(panel)
{
// toggle the requested one
Element.toggle(panel);

// then hide all of the others so that only
// one (at most) is open at a time
$$('body .dd_option_panel').each(function(node){
if (node != $(panel)) {
Element.hide(node);
}
});
}

The Requisite IE Hacks

You can always count on Internet Explorer to keep you on your toes. If you choose to align your dropdown widgets vertically like I have in my example, you’ll notice that the higher dropdown panels render behind the lower widgets. This is due to IE’s z-index implementation that is documented extensively elsewhere. The fix is to wrap each dropdown container with an additional div element whose sole purpose is to force a proper z-index stack.

Also, keep observers may have noticed my use of min-height for the dd_wrapper container. IE6, of course, doesn’t support this attribute but I’ve had success using Dustin Diaz’s Min-Height Fast Hack.


.dd_wrapper {
  ...
  min-height: 17px;
  /* IE6 min-height hack: http://www.dustindiaz.com/min-height-fast-hack/ */
  height: auto ! important;
  height: 17px;
}

<div style="position:relative;z-index:60;">
<div class="dd_wrapper">
...
</div>
</div>

<div style="position:relative;z-index:50;">
<div class="dd_wrapper">
...
</div>
</div>

Final Touches

My example includes a save button that could be used to make an AJAX call. This would be useful if your search updated the results on the fly as search options were changed. If your form was going to be submitted normally, this button could be removed.

Keep in mind that you aren’t limited to checkbox fields in your dropdown panels. You could use radio buttons or anything else. With these types of hidden panels, you will be able to include some additional helper text for your users when it makes sense, but try to keep it short and to the point.

The final thing you’d want to add is some code to handle the updating of the text label when the options are updated. Depending on your implementation, there are various ways to handle this. For example, the result of an AJAX request might determine how the label gets updated. You might want to have your toggleDropdown() function include some logic to update those DOM elements.

My final advice would be to put a little extra thought into making the text labels smart enough to show a concise view of the selections. For example, if your user selects all of the options for Fuel, “Any Fuel” is easier to read (and actually indicates an all-inclusive selection) than “Fuel (Gasoline, Diesel, Alternative)”.

Hopefully this article gives you some ideas that you can incorporate into your next project. The overall idea is quite simple, but there are endless ways that you could expand and improve upon it!

View the completed demo.

0 Responses to “Streamline your Forms with Widgets”

  1. Michael Monje Moran on September 7, 2009 at 4:32 pm said:

    Nice inspiration example… I really like the idea of streamlining web forms and some web 2.0 apps really succeed in doing that.

    A few comments however:

    – when presenting non mandatory fields to the users, this approach is less explicit than some “traditional” layouts for presenting multiple boxes directly on the screen. Ultimately, if the user does not see the possible options all at once, he will probably not take the time to expand each individual box in order to select different options.

    – this presentation is much neater than the traditional layout but it also involves more clicks (in some cases this is not a problem, but in others this is a relevant indicator of form performance).

    – Visually, the boxes you created look awesome. I would only adjust the border color of the popup box to a lighter blue in order to match the outer border from the title bar. I would probably try with a 1px so that it seamlessly prolongates the top bar style.

    – In your example, the last box title takes 2 lines to display, but the popup shows above the second line of text. Ideally, there should be some way to automatically adjust the offset of the popup box in order to keep the title bar readable to the user while the popup is visible.

    Yet, I really like how your example look and the idea of showing a summary of what is selected in the title bar is definitely a clever one. These kinds of nice small details are indicative of good web 2.0 apps nowadays.

    Thanks for sharing this!
    Michael.

  2. Jason
    Thank you for a great article. I am new to this whole world of website creation and your article gave me pretty good insight.

  3. Hey just superb tut, Thanks.

  4. Nice.. I've made them before. But accessible and tabbing? I think not..

  5. Nice.. I've made them before. But accessible and tabbing? I think not..

Leave a Reply

Learn to code with Treehouse

Start your 14 day free trial today and get access to hundreds of video courses in web development, design and business!

Learn more