Easy DHTML treeview
This is an alternative for "Easy DHTML treeview"
Introduction
This code is an HTML/JavaScript tree based on the Easy DHTML treeview.
Take a look at the original first to get an idea of what the code is doing and how the tree is organized: there.
It uses div instead of tables in order to simplify the HTML code and make it a bit more readable. The downside is that the JavaScript is slightly more convoluted as the tree hierarchy is a bit more complex: at each level, the parent div contains two or more children the first one for the title bar and image, the second for the first sub-item and so on. The event is triggered by clicking on the title bar.
CSS styles are used to set the appearance of the tree elements at every level.
Using the code
The code can be pasted into a stand-alone HTML file.
Create a subfolder named "images" to store the images from the original version.
<script type="text/javascript">
//Expands/collapses a node's children and sets appropriate image
function Toggle(node)
{
//paths to images used in tree
var IMG_MINUS = "images/minus.gif";
var IMG_PLUS = "images/plus.gif";
var IMG_LEAF = "images/leaf.gif";
//find the elements to modify or test relatively to node clicked
//image to modify
var img = node.children.item(0).children.item(0);
//parent of items to show or hide
var parent = node.parentNode;
//first item to hide is second child of parent - first child is the node clicked
var firstItem = parent.children.item(1);
//is this first item to hide/show an empty div?
var bHasChildren = parent.children.item(1).childElementCount > 0;
// Unfold the branch if it isn't visible
if (firstItem.style.display == 'none')
{
//if this level has children the image shown in a minus sign, otherwise leaf image
img.src = bHasChildren ? IMG_MINUS : IMG_LEAF;
//show all the children
for(i=1;i<parent.children.length;i++)
{
parent.children.item(i).style.display = '';
}
}
// Collapse the branch if it IS visible
else
{
// Change the image to a plus sign if this level has children otherwise leaf image
img.src = bHasChildren ? IMG_PLUS : IMG_LEAF;
//hide all the children
for(i=1;i<parent.children.length;i++)
{
parent.children.item(i).style.display = 'none';
}
}
}
</script>
<style>
#tree
{
height:500px;
width: 200px;
border:1px solid black;
padding-left:2px;
padding-right:2px;
padding-top:1px;
padding-bottom:1px;
}
.tl1, .tl2, .tl3
{
border:1px solid blue;
background-color:yellow;
width: 100%;
height:20px;
position:relative;
margin-bottom:1px;
}
.tl1_, .tl2_, .tl3_
{
position:relative;
text-align:left;
-moz-user-select: none;
-webkit-user-select: none;
}
.tl1
{
height:20px;
left:-1px;
}
.tl2
{
left:-1px;
}
.tl3
{
left:-1px;
}
.tl1_
{
left:10px;
font-size:14pt;
}
.tl2_
{
left:20px;
font-size:12pt;
}
.tl3_
{
left:30px;
font-size:10pt;
}
.imgNode
{
margin-right:5px;
}
</style>
<div id="tree">
<div id="lvl1_1">
<div onClick="Toggle(this)" class="tl1" >
<div class="tl1_" onselectstart="return false;"><img
class="imgNode" src="leaf.gif" />Level 1</div>
</div>
<div id="lvl2_1">
<div onClick="Toggle(this)" class="tl2" >
<div class="tl2_" onselectstart="return false;"><img
class="imgNode" src="leaf.gif" />Level 2</div>
</div>
<div id="lvl3_1">
<div onClick="Toggle(this)" class="tl3" >
<div class="tl3_" onselectstart="return false;"><img
class="imgNode" src="leaf.gif" />Level 3</div>
</div>
<div></div>
<!--dummy subitem-->
</div> <!--level 3-->
<div id="lvl3_2">
<div onClick="Toggle(this)" class="tl3" >
<div class="tl3_" onselectstart="return false;"><img
class="imgNode" src="leaf.gif" />Level 3</div>
</div>
<div></div>
<!--dummy subitem-->
</div> <!--level 3-->
</div> <!--level 2-->
<div id="lvl2_2">
<div onClick="Toggle(this)" class="tl2" >
<div class="tl2_" onselectstart="return false;"><img
class="imgNode" src="leaf.gif" />Level 2</div>
</div>
<div id="lvl3_3">
<div onClick="Toggle(this)" class="tl3" >
<div class="tl3_" onselectstart="return false;"><img
class="imgNode" src="leaf.gif" />Level 3</div>
</div>
<div></div>
<!--dummy subitem-->
</div> <!--level 3-->
<div id="lvl3_4">
<div onClick="Toggle(this)" class="tl3" >
<div class="tl3_"
onselectstart="return false;"><img class="imgNode"
src="leaf.gif" />Level 3</div>
</div>
<div></div>
<!--dummy subitem-->
</div> <!--level 3-->
</div> <!--level 2-->
</div> <!--lvl 1-->
</div><!--tree-->
Code description
Here is a description of the div structure for each level:
<div id="lvlX_N">
<div onClick="Toggle(this)" class="tlX" >
<div class="tlX_" onselectstart="return false;">
<img class="imgNode" src="leaf.gif" />
Level X
</div>
</div>
<div ...> <!--firstItem: div containing a child or empty-->
</div>
<div ...> <!--another child...-->
</div>
...
</div> <!--level X-->
The main div for each level as an id like lvlX_N - where X is the level (1,2,3) and N is sequential so that IDs are unique.
The second div supports the OnClick calling the Toggle function and is the node sent to the function.
From this node the code goes up one level to find the parent:
var parent = node.parentNode;
And we dig down to find the image:
var img = node.children.item(0).children.item(0);
This second div also supports the style showing the "title bar", the styles tl1, tl2, tl3 in my css. Finally it contains another div with the image and text, with the text style defined by the styles tl1_, tl2_, tl3_.
From the parent node we can go down to the second div which contains the first child. If this level does not have children then this firstChild is an empty div. Additional divs may define other children:
var firstItem = parent.children.item(1); var bHasChildren = firstItem.childElementCount > 0;
The rest of the code sets the image and shows or hides the children by setting the display property of the divs which shows or hides all of their content.
Points of Interest
The code for switching the images does not work in IE8. This is not a problem since my HTML code will be dynamically generated by script and set to a div tree inner HTML with the proper images set on each click. However I would be interested in finding a solution for making this work properly in IE8. I tested on chrome 15 and Firefox 3.6.