CSS/DHTML Toggled Text

Not a program/tool per se, but an explanation of how I achieved hide/reveal toggled text blocks using CSS and Javascript in six easy steps. This is probably not a degrades-gracefully feature...
  1. Create a block of 'subtext' that you intend to toggle. We will label this <div> (or <span>) as CLASS=toggle-subtext and identify the specific subtext block as ID=XXX_subtext. Example...
    <div class="toggle-subtext" id="Example_subtext">
  2. Decide on the method of hide/reveal:
  3. If using the widget method, preload the "collapse" image somewhere on the page. FireFox is fine, but IE will not properly display this secondary image unless it has been pre-loaded. Note that you have to invoke the image, but not necessarily display it. Example...
    <img src="/images/down.gif" border="0" style="display:none">
  4. Define a Javascript no-op function to receive the click event, yet do nothing. Example...
    function noop() {}
  5. Wrap the widget or text-control with a link using the no-op function, and an onMouseDown() action invoking the toggleSubText('XXX') function. Example...
    <a href="javascript:noop()" onMouseDown="toggleSubText('Example')">
  6. Establish CSS attributes for the toggle-* classes that define initial invisibility. Example...
    <style type="text/css">
      .toggle-subtext {display: none;}
      .toggle-text {visibility: visible;}
      .toggle-widget {visibility: visible;}
    </style>
The simple idea is that when the toggleSubText() is called with an "Example" argument, then the visibility attribute of the "Example_subtext" block is toggled. At the same time, the state of "Example_toggle" is flipped, whether that means twiddling the visibility of the toggle-text or changing the image source of the toggle-widget.

Now you are ready for the toggleSubText() function itself.

  
function toggleSubText(id) {
  //
  // SubText is a hide/reveal block as identified by CLASS=toggle-subtext ID=<ID>_subtext
  //
  // The SubText block is controlled by either...
  // ...a text layer with CLASS=toggle-text ID=<ID>_toggle
  // ...or a collapse/expand image with CLASS=toggle-widget NAME=<ID>_toggle
  //
  var subtext; var toggle; var widget; 
  //
  if (document.getElementById) {
    toggle = document.getElementById(id + '_toggle');
    subtext = document.getElementById(id + '_subtext');
  }
  else if (document.layers) {
    toggle = document.layers[id + '_toggle'];
    subtext = document.layers[id + '_subtext'];
  }
  if (document.images[id + '_toggle']) {
    widget = document.images[id + '_toggle']
  }
  if (! subtext.style) {
    if (subtext.display == 'block') {
      subtext.display = 'none';
      if (toggle) {
        toggle.visibility = 'visible';
      }
      if (widget) {
        widget.src = "/images/right.gif";
      }
    }
    else {
      subtext.display = 'block';
      if (toggle) {
        toggle.visibility = 'hidden';
      }
      if (widget) {
        widget.src = "/images/down.gif";
      }
    }
  }
  else {
    if (subtext.style.display == 'block') {
      subtext.style.display = 'none';
      if (toggle) {
        toggle.style.visibility = 'visible';
      }
      if (widget) {
        widget.src = "/images/right.gif";
      }
    }
    else {
      subtext.style.display = 'block';
      if (toggle) {
        toggle.style.visibility = 'hidden';
      }
      if (widget) {
        widget.src = "/images/down.gif";
      }
    }
  }
}