Tree.js - Create collapsible trees from HTML lists

April 2, 2007 10:22 AM

The Tree class is designed to take a standard HTML unordered list and automatically transform it into a collapsible tree. Each list can contain one or more collapsible trees, nested to any depth. Each tree has to have a root node, which is defined as a list item (<li>) which contains an unordered list (<ul>). For example, consider the following unordered list:

<ul id='tree'>
   <li>
      Root
      <ul>  
         <li>Node 1</li>
         <li>Node 2</li>
      </ul>
   </li>
   <li>Node</li>
</ul>

In this example, there is only one Root node because only one <li> contains a <ul>.

Tree.js first traverses the list to find which <li>s should become root nodes. If it finds any, it gives them a CSS class of 'root', adds an image link, and makes the <ul> it contains collapsible. Each tree can be collapsed by clicking on the image that Tree.js adds next to each root node. By default, the collapsing is animated by Effect.BlindUp/BlindDown from the Scriptaculous library and the image is automatically changed from a minus sign to a plus sign. Take a look at the demo to see what the unordered list looks like after it has been transformed into a collapsible Tree, and view the javascript source here.

Using the Tree class is easy, to create a standard tree from the above unordered list, all one needs to do is add the following code to the HTML page.

<script type='text/javascript'>
   new Tree( 'tree' );
</script>

By default, the images 'images/plus.png' and 'images/minus.png' are used to indicate the state of the root nodes. To use custom images, simply pass in the src of each in the options parameter:

<script type='text/javascript'>
   new Tree( 'tree', { more: 'myPlus.png', less: 'myMinus.png' );
</script>

If you wanted special behavior from the tree nodes, you could extend the default Tree.Node class, change or add any function you wanted, then pass in your new class as an option parameter, for example:

<script type='text/javascript'>
   Tree.Node.Special = Class.create();
   Object.extend( 
      Object.extend( Tree.Node.Special.prototype, Tree.Node.prototype ),
   {
      ...
   } );
 
   new Tree( 'tree', { element: Tree.Node.Special );
</script>