I had a need to implement several different types of tree controls in ASP lately. I looked around, did not find exactly what I wanted. There was no short supply of tree type controls for DHTML - my problem was that most were really complex and tended to do way more than what I required. The other problem (that I had) was that some of the more simple ones took a lot of code on the ASP side for even a semi-simple looking tree.
I decided that I wanted a tree that could be built with a single server-side include, no components, and was reasonably fast. So here is my first version of a tree control usable in ASP.
I will state that originally I was working with an example I found somewhere (I honestly cannot remember where), all that is left from that example are some of the images for displaying the tree, and a couple of
DIV element and you give it an ID like:
<DIV id=myDIV style="DISPLAY: none"></DIV>
var oMyDiv = document.getElementById("myDIV");
That was a really simple example - but it demonstrates exactly how trees and other DHTML widgets work. You can manipulate all the attributes and so forth on an element all in script.
In my tree control I use
DIV's to encapsulate the different parts of the tree (each branch), then when you click to expand a branch, I change the
DIV's style depending on whether I want to expand (show the child
DIV), or collapse (hide the child
DIV). You can look at the source to see how all the elements are manipulated to create the tree control - it really is all based on hiding/showing and changing a few attributes.
The real crux of spitting a tree control out from ASP (in my opinion) happens in the tree construction (ASP side of things). This part was where some of the ASP examples out there really were confusing. I had a hard time believing that 3 pages of code were necessary to render a tree. I am not saying my solution is the best - but it is rather short on the code needed to do it (which I am proud of).
There are a couple of assumptions about a tree that can be made without even knowing what is going to go into it.
- All trees have branches and leaves
- A tree (when drawn) is drawn one line at a time
Number 1 makes creating a little tree API pretty simple - you are either adding leaves or starting a new branch.
Number 2 is where we can do some optimizations in the code and take out most of the logic that would normally be needed to draw a tree. Instead of using a tree-structure to draw a tree, I only track what depth branch you are on (this will become clear in a minute).
The solution for selection/de-selection/keys is to use a hidden
SPAN element which will contain each items key (any value you want to give it), and its selection state. You are probably wondering where I am storing the selection state. I am taking advantage of the fact that these
SPANs containing the item keys will never be visible - so I can stuff variables into the element's
style attributes with no effect on the actual page display. I put a 0 or 1 into the
zIndex attribute to tell the script whether the item is selected or not (thanks CSS!).
bReselect is whether or not the item was just re-selected
bSelected whether or not the item was selected
sKey the items key (you assign this)
Using the code
Let's get down to business and see how all this information fits together into something (hopefully) useful.
To even be able to create a tree using the scripts, you will need to include it between the
tags of your ASP page.
if(bSelected || bReslect)
alert("You clicked - " + sKey);
TreeItemDispatch = myTreeItemDispatch;
We are almost ready to spit out a tree. One thing that I added to my tree implementation was the ability to customize the icons of each node. For this to work efficiently, you register them using a number - before you start your tree. Here is an example (in ASP)
I set up the potential for 10 different types of each (probably overkill). If you want to add more - just change the numbers.
We are now ready to start our tree, the tree-top in my implementation is static (i.e.: it can not be collapsed). I did this because every tree I have to make only needs the top as a description of what's in the tree. So to kick off a tree we would have some ASP that looks like this:
tree_Start "Personal Folders","images/tree/openfoldericon.gif"
This tells the tree API to start building a tree with a top item named "Personal folders" and using the specified icon.
Now we are free to add branches and leaves to our tree - the only thing we really need to keep track of is, if we are adding the last item in a branch or the tree itself - another note is that I have defined a constant (for ASP use) called
tFALSE, so when adding branches and leaves we use the constant for yes/no values. To add a branch we use the
tree_StartBranch function. It takes several parameters - here is an example:
tree_StartBranch 0,tFALSE,"Test Folder","tst"
The first parameter is the branch type (which we registered above), the second parameter tells the tree if this is the last branch in the current branch (or tree), third is the caption, and the last parameter is a key you can assign to implement custom behavior on the client side.
Once we start a branch we can add leaves to it like this:
tree_AddLeaf 0,tFALSE, "Child 1","tst1"
The parameters are the same as those for
tree_StartBranch with the exception that the first parameter is a leaf type (which we registered above).
Once you have added leaves to your branch you have to end it using the
Once you have added all the branches to a tree you call the
tree_End function which writes the tree out.
The usage of the API lets you easily build up a tree using only a few functions. Look in the included example and you will see it is pretty straightforward.
What happens once someone clicks on an item, is for you to implement. I wanted this to be a good little framework for tree generation - I hope you find it useful.
If you use it in something interesting - let me know.