O'Reilly logo

JavaScript Cookbook by Shelley Powers

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

13.5. Creating Collapsible Form Sections

Problem

You have a large form that takes up a lot of space. You only want to display sections of the form as they are needed.

Solution

Split the form into display blocks using div elements, and then change the block’s styling to control the display of the form section. When the page is loaded, hide all of the form blocks by changing the display value to none using JavaScript:

theformblock.setAttribute("style","display: none");

or:

theformblock.style.display="none";

To expand the section, change the display setting to block using setAttribute:

theformblock.setAttribute("style","block");

or set the value directly:

theformblock.style.display="block";

Discussion

There are multiple ways you can prevent form elements from taking up page space. For one, you can clip the element by setting the clipping area. Another approach is to resize the element to zero height. The best approach, though, and the one most applications use, is to employ a collapsible section.

A collapsible section is a form of widget—a set of elements, CSS, and JavaScript packaged together and generally considered one object. The typical implementation consists of one element that acts as a label that is always displayed, another element that holds the content, and all contained within a third, parent element.

The collapsible section may or may not be used with other collapsible sections to form a higher level widget, the accordion. The accordion widget is a grouping of collapsible sections with an additional behavior: depending on preference, any number of collapsible sections can be expanded, or only one section can be expanded at a time.

To demonstrate how collapsible sections can be used with forms, Example 13-2 shows a form that’s split into two sections. Notice that each form block has an associated label that expands the collapsed form section when clicked. When the label is clicked again, the form section is collapsed again.

Example 13-2. Collapsed form element

<!DOCTYPE html>
<head>
<title>Collapsed Form Elements</title>
<style>
.label
{
  width: 400px;
  margin: 10px 0 0 0;
  padding: 10px;
  background-color: #ccccff;
  text-align: center;
  border: 1px solid #ccccff;
}
.elements
{
  border: 1px solid #ccccff;
  padding: 10px;
  border: 1px solid #ccccff;
  width: 400px;
}
button
{
   margin: 20px;
}
</style>
</head>
<body>
<form>
  <div>
    <div id="section1" class="label">
      <p>Checkboxes</p>
    </div>
    <div id="section1b" class="elements">
      <input type="checkbox" name="box1" /> - box one<br />
      <input type="checkbox" name="box1" /> - box one<br />
      <input type="checkbox" name="box1" /> - box one<br />
      <input type="checkbox" name="box1" /> - box one<br />
      <input type="checkbox" name="box1" /> - box one<br />
     </div>
    </div>
  <div>

  <div id="section2" class="label">
    <p>Buttons</p>
  </div>
  <div class="elements">
    <input type="radio" name="button1" /> - button one<br />
    <input type="radio" name="button1" /> - button one<br />
    <input type="radio" name="button1" /> - button one<br />
    <input type="radio" name="button1" /> - button one<br />
    <input type="radio" name="button1" /> - button one<br />
    <button>Submit</button>
  </div>
</div>
</form>
<script type="text/javascript">

var elements = document.getElementsByTagName("div");

// collapse all sections
for (var i = 0; i < elements.length; i++) {
  if (elements[i].className == "elements") {
    elements[i].style.display="none";
  } else if (elements[i].className == "label") {
    elements[i].onclick=switchDisplay;
  }
}

//collapse or expand depending on state
function switchDisplay() {

  var parent = this.parentNode;
  var target = parent.getElementsByTagName("div")[1];

  if (target.style.display == "none") {
    target.style.display="block";
  } else {
    target.style.display="none";
  }
  return false;
}
</script>
</body>

There are numerous ways you can map the click activity in one element by changing the display in another. In Example 13-2, I wrapped both the label and the content elements in a parent element. When you click on a label, the parent to the label element is accessed in JavaScript and its children returned as an HTML collection. The second element’s display toggles—if the element’s display is none, it’s changed to block; if block, changed to none. Figure 13-2 shows the page, with one form section expanded.

Form split over collapsible accordion sections, with one section expanded

Figure 13-2. Form split over collapsible accordion sections, with one section expanded

In the example, notice that the form elements are displayed when the page loads, and only collapsed after the elements are loaded. The reason for this is if JavaScript is turned off, the form elements are displayed by default.

See Also

See Recipe 14.5 for how to make a collapsible section/accordion widget accessible with ARIA attributes.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required