Netscape DevEdge

Skip to: [content] [navigation]

Standards-Based Collapsible Table of Contents Widget (CTOCWidget)

Introduction

Recently, while developing the new table of content widget for the JavaScript references in the DevEdge MultiBar Sidebar Tab, I found the need for a tree-based collapsible list. This article chronicles my experience creating a tree-based table of contents widget using XML and the W3C DOM.

Design

I had a choice of either reusing an existing solution or starting from scratch. The old xbCollapsibleList which was ported from a script written for 4.x generation browsers or the newer xbTreeWidgetStatic were obvious candidates. xbCollapsibleList was not seriously considered due to its obsolete design. However, xbTreeWidgetStatic provided a good basis to start from; however its reliance upon a procedural means of defining the tree was undesirable.

Since the table of contents widget would be hosted inside a sidebar tab in either Netscape 7.x or Mozilla based browsers, cross-browser compatibility was not an issue and I decided to implement a pure standards-based widget for simplicity sake. This widget would use the same presentational markup used in xbTreeWidgetStatic but would generate its content from an external XML document which described the table of contents.

Markup

XML Description

I decided that the simplest approach would be to use an XML document composed of two elements: toc and item. The document element toc would contain the table of contents definition while a set of nested item elements would provide the hierarchical description of the items in the table of contents.

toc and item would each have a title attribute which would serve as a label for each entry. item elements would have an additional attribute url which would point to the location of the document to be loaded when the item was activated. item elements would be nested to represent the hierarchal nature of a table of contents.

Example
<toc title="Table of Contents title">
  <item title="Item1 Title" url="url1" />
  <item title="Item2 Title" url="url2">
    <item title="Subitem 1 Title" url="url3"/>
  </item>
</toc>

HTML Representation

The tree would be contained in an overall DIV which would allow the table of contents widget to be styled. Each contained item would be contained in its own DIV which contained a handle DIV and an optional children DIV. The handle would contain the descriptive text for each table of contents entry along with an image depicting whether the item is in an open or closed state. Event handlers attached to the handle open (display child items) or close (hide child items).

<DIV class = "CTOCWidget_view">
  <DIV class = "CTOCWidget_item">
    <DIV class = "CTOCWidget_itemhandle" style = "cursor: pointer;">
      <IMG style = "height: 12px; width: 16px;" src = "closed.gif">
      <A href = "url1" target = "_content">
        Item1 Title
      </A>
    </DIV>
  </DIV>
  <DIV class = "CTOCWidget_item">
    <DIV class = "CTOCWidget_itemhandle" style = "cursor: pointer;">
      <IMG style = "height: 12px; width: 16px;" src = "closed.gif">
      <A href = "url2" target = "_content">
        Item2 Title
      </A>
    </DIV>
    <DIV class = "CTOCWidget_itemchildren" style = "display: none; position: relative; left: 1em;">
      <DIV class = "CTOCWidget_item">
        <DIV class = "CTOCWidget_itemhandle" style = "cursor: pointer;">
          <IMG style = "height: 12px; width: 16px;" src = "open.gif">
          <A href = "url3" target = "_content">
            Subitem 1 Title
          </A>
        </DIV>
      </DIV>
    </DIV>
  </DIV>
</DIV>

Script

CTOCWidget.js implements a JavaScript Object CTOCWidget which is used to manage creating the table of contents from the corresponding XML document.

Constructor
CTOCWidget(Node domTOCModel, String target)

Constructs an instance of the widget from the XML document domTOCModel containing the table of contents which will activate its links in the window target named target.

Class Properties
CTOCWidget._handleImages

_handleImages is an object which specifies the images to be displayed in the open or closed state of a node in the table of contents tree. You can override the default values before constructing the table of contents.

CTOCWidget._classPrefix

_classPrefix is a string which is used to prefix the class names used in the HTML to represent the table of contents. The default is "CTOCWidget".

Properties
Node model

model holds a reference to the XML Document which contains the table of contents.

String target

target is the value of the target attribute on all generated hyperlinks and is used to activate links in specific windows or frames.

HTMLDivElement view

view contains a reference to the outer-most DIV containing the table of contents widget.

Methods
_createItemView(Node modelItem, String target

_createItemView is an internal method used to create a view corresponding to a specific item in the table of contents model. The DOM Level 2 Core and DOM Level 2 HTML APIs are used to create the HTML markup which represents the widget.

toggleHandle(Event e)

An event handler attached to the widget to handle clicks on the item's view handle. The DOM Level 2 Events API is used to attach click event handlers to the handle while the DOM Level 2 CSS API is used to hide/show an item's children by setting its style.display property.

Examples

Creating the table of contents widget requires two steps:

  1. Load the external XML document describing the table of contents. In the examples below I used the DOM Level 3 Load API to asynchronously load the XML document and the DOM Level 2 Events API to process the loaded document when the load event fires.

  2. Create the HTML markup to represent the table of contents.

var domTOCModel;

function loadToc()
{
  // get XML document file name from the query string
  var tocFile = document.location.search.substring(1);

  // create an XML document and load the file using
  // W3C DOM 3 Load and W3C DOM 2 Events
  domTOCModel = document.implementation.createDocument('', '', null);
  domTOCModel.addEventListener('load', onLoadToc, false);
  domTOCModel.load(tocFile);
}

function onLoadToc()
{
  // when the XML document is loaded, create the 
  // table of contents view and insert into the HTML document

  var title = domTOCModel.documentElement.getAttribute('title');
  var h1 = document.createElement('h1');
  h1.appendChild(document.createTextNode(title));
  var tocWidget = new CTOCWidget(domTOCModel, '_content');
  document.body.appendChild(h1);
  document.body.appendChild(tocWidget.view);
}

You can see the CTOCWidget in action by clicking the following links in Netscape 7.0x or Mozilla.

Notes

CTOCWidget is currently written to use the W3C Standards for the DOM directly without work-arounds for other browsers which do not support the appropriate standards. As a result, CTOCWidget is not supported by Internet Explorer, Opera or other browsers.

A+R