Click here to Skip to main content
15,868,349 members
Articles / Programming Languages / Javascript
Alternative
Article

Easy DHTML treeview

Rate me:
Please Sign up or sign in to vote.
2.22/5 (2 votes)
23 May 2012CPOL2 min read 12.6K   8   3
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. 

JavaScript
<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>
CSS
<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> 
XML
<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:

XML
<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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Question[My vote of 2] Explanation Pin
Tim Corey23-May-12 4:22
professionalTim Corey23-May-12 4:22 
QuestionReally? Pin
Dewey22-May-12 13:45
Dewey22-May-12 13:45 
AnswerRe: Really? Pin
HaBiX22-May-12 23:03
HaBiX22-May-12 23:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.