janDOMTree is a DOM based treeview for Internet Explorer 5+, Mozilla 1.4+ and Opera 7+1. The tree model is defined in javascript either within the document or imported using the src attribute of the script tag. Because nodes are only rendered when needed the treeview works also very fast with a large number of nodes. It is also possible to load a javascript definition file dynamically or reload the Document outline.
If you want you can download the demo files.
Notes: 1Opera has a bug: when setting the display attribute of a table the cellPadding and cellSpacing is ignored and extra space added causing the lines to break.
Before you read any further you may want to play with the treeview first.
Making a treeview work in more than one browser implies compromises. Ideally I would have used a XML data island within HTML to store the definition of the treeview. But Mozilla does not support XML data islands. I wanted to use the onload event of the SCRIPT tag to signal that a dynamically loaded javascript is ready for use. But Internet Explorer contains a serious bug: It simply ignores the onload event of the script tag. Therefore the current implementation of janDOMTree has the following work-arounds.
You can select a node in the treeview by clicking on it. This will generate a nodeClicked event. If you want to handle this event you must provide an onTreeNodeClicked function
function onTreeNodeClicked(pNode) { }
The pNode parameter is a reference to the data node. Using the getAttribute method of the data Node you can retrieve the data you need. See the source of this page for an example.
You can select a node from within your javascript application by calling the treeSelectNode function.
function treeSelectNode(pId) { }
The pId parameter must a valid node id. If the node can not be found then nothing will happen. If the node is found then it will be selected and the treeview will open the treeview for the selected node and scroll it into view.
function treeAddChildNode(pLabel,pId) { }
You can omit both parameters. In that case the label text will default to "new label" and a unique id will be generated. You can provide pLabel and omit pId, but if you provide pId, you must also provide pLabel.
function treeDeleteNode() { }
If you try to delete the root node then you will get an error message.
Within your javascript application you can always get the selected node by calling the treeSelectedNode function that will return a reference to the selected data node, or will return null if no node was selected.
function checkSelected() { var xnode xnode=treeSelectedNode() if (xnode==null) return alert(xnode.getAttribute("id")+": "+xnode.nodeName) }
You define the tree in javascript with a series of function calls.
function demodata() } x=n("JanSoft") xx=x.c("Editors","id:x1000") xxx=xx.c("BackEdit") xxx=xx.c("Word 2000") xx=x.c("Graphics") xxx=xx.c("Painter 24") xxx=xx.c("Movies 12") xx=x.c("Internet") xx=x.c("Database") xx=x.c("Delphi") return x } treeDataLoaded()
The n(nodeName,data) function returns a new node. The nodeName parameter is required, the data parameter is optional.
The data parameter is a string consisting of one or more name:value separated by a semi-colon.
"id:1000;price:123.45"
The c(nodeName,data) method of a node object creates and adds a new child node to the node object and returns the child node.
The nodeName is displayed as the label in the treeview. If you omit the id attribute then the treeview will generate an id itself. It is recommended to provide the id attribute when you want to select nodes from within script.
The definition of the tree must be embedded within a function that has the same name as javascript file (without the .js), and return the root node.
After the function you must add a call to the treeDataLoaded() function, to signal the calling page that the data has been loaded.
Provide a onload event handler in the body tag.
<body onload="main()">
In the main() function you will call the treeLoad() function as follows:
function main() { treeLoad("tree","demotoc") }
tree is the id of the html element (usually a DIV element) that will hold the treeview. demotoc is the name of the tree definition.
You can load a tree dynamically by calling treeLoad()
function dynaLoad() { var treedef treedef="demodata" treeLoad("tree", treedef) }
The treeLoad function will try to execute a function named demodata. If that is not possible then the demodata.js script will be loaded.
Please note that the definition of a dynamically loaded tree must also end with the treeDataLoaded() call.
Using the treeview as a navigation menu is not difficult. You place the treeview in a frame or iframe element. In the onTreeNodeClicked function you retrieve the value of the href and possibly target attributes that you have defined as data. You then use the regular method of navigating to a document.
Suppose you have a frameset with 2 frames. The treeview to the left and the content frame to the right. In your frames defining document you include a generic navigation function:
function dispatch(pHref,pTarget) { if (pTarget) { frames[pTarget].location.href=pHref } else { frames.main.location.href=pHref } }
In the above it is assumed that your right side content frame is named main.
From within the onTreeNodeClicked function in the left frame you call the dispatch function.
function onTreeNodeClicked(pNode) { var href, target href=pNode.getAttribute("href") target=pNode.getAttribute("target") if (target) { top.dispatch(href,target) } else { top.dispatch(href) } }
You can also use the treeview for local navigation in the document as is done with the Document Outline definition.
You can add custom content to the treeview by assigning the onTreeRenderNode event handler. This event is fired before the label is rendered.
onTreeRenderNode=myRenderNode function myRenderNode(pNode,pRow) { var cell cell=pRow.insertCell(-1) cb=document.createElement("INPUT") cb.type="checkbox" cb.name="cbtree" cb.value=pNode.getAttribute("id") cell.appendChild(cb) }
The pRow parameter is the current row. In the treeview each node is rendered in separate table. Every part of the node: line images and the label itself are put in their own cell. You also have to put any custom content is its own cell as shown in the example above. If you do not assign onTreeRenderNode then it is ignored.
onTreeRenderNode