Simple Tree in Javascript : Tree « GUI Components « JavaScript DHTML






Simple Tree in Javascript

 <html> <head> <title>:: Tree Sample ::</title> <style type="text/css"> body { padding: 0; margin: 0; } .tree ul, .tree li { list-style-type: none; margin: 0 0 0 2px; padding: 0; display: block; } .tree ul ul { margin-left: 16px; } .tree a.selected { background-color: lavender; } .tree .collapsed ul, .tree .collapsed span { display: none; } .tree span { display: block; margin: 0 0 0 16px; padding: 0; color: Gray; cursor: default; font-size: smaller; } .tree img { border: none; text-align: left; vertical-align: middle; margin-right: 2px; } .tree img.plusminus { width: 9px; height: 9px; } .tree a, .tree a:link, .tree a:visited, .tree a:active { font-size: 10pt; color: navy; font-family: Verdana; text-decoration: none; text-align: left; margin: 0 2px 0 2px; } .tree a:hover { text-decoration: underline; color: Blue; } </style> <script type="text/javascript"> /* _______________________ ______________________ XML DOM Tree Component Browsers support: Version 1.5 -> Internet Explorer -> Mozilla _____________________________ -> Opera Features: -> Firefox -> Server Side Independency -> Konqueror -> Cross Browser Support -> Dynamic Loading -> XML Source -> Easy Customization ______________________________ Serghei Egoricev (c) 2006 egoricev [at] gmail.com */// CSS import  Tree = function() {} /* Use double click for navigate, single click for expand */ Tree.useDblClicks = true; // NOT IMPLEMENTED Tree.saveNodesStateInCookies = true; /* CSS classes */ Tree.expandedClassName = ""; Tree.collapsedClassName = "collapsed"; Tree.selectedClassName = "selected"; Tree.plusMinusClassName = "plusminus"; Tree.treeClass = "tree"; /* Images */ Tree.collapsedImage = "treeimg/collapsed.gif"; Tree.expandedImage = "treeimg/expanded.gif"; Tree.noChildrenImage = "treeimg/treenochild.gif"; /* Xml Attributes */ Tree.xmlCaption = "caption"; Tree.xmlUrl = "url"; Tree.xmlTarget = "target"; Tree.xmlRetreiveUrl = "retreiveUrl"; Tree.xmlIcon = "icon"; Tree.xmlExpanded = "expanded"; /* Text for loading */ Tree.loadingText = "Loading ..."; /* Private members */ Tree.obj = null; Tree.instanceCount = 0; Tree.instancePrefix = "alder"; Tree.cookiePrefix = "alder"; Tree.dwnldQueue = new Array; Tree.dwnldCheckTimeout = 100; /* Interval handler. Ckecks for new nodes loaded. Adds loaded nodes to the tree. */ Tree.checkLoad = function () { var i, httpReq; for (i = 0; i<Tree.dwnldQueue.length; i++) if ((httpReq = Tree.dwnldQueue[i][0]).readyState == 4 /*COMPLETED*/) { var node = Tree.dwnldQueue[i][1]; // unqueue loaded item  Tree.dwnldQueue.splice(i, 1); Tree.appendLoadedNode(httpReq, node); if (Tree.saveNodesStateInCookies) Tree.openAllSaved(Tree.getId(node)); } // if // will call next time, not all nodes were loaded if (Tree.dwnldQueue.length != 0) window.setTimeout(Tree.checkLoad, Tree.dwnldCheckTimeout); } /* Adds loaded node to tree. */ Tree.appendLoadedNode = function (httpReq, node) { // create DomDocument from loaded text  var xmlDoc = Tree.loadXml(httpReq.responseText); // create tree nodes from xml loaded  var newNode = Tree.convertXml2NodeList(xmlDoc.documentElement); // Add loading error handling here must be added  Tree.appendNode(node, newNode); } /* Event handler when node is clicked. Navigates node link, and makes node selected. */ Tree.NodeClick = function (event) { var node = event.srcElement /*IE*/ || event.target /*DOM*/; // <li><a><img> - <img> is capturing the event while (node.tagName != "A") node = node.parentNode; node.blur(); node = node.parentNode; Tree.obj = Tree.getObj(node); Tree.expandNode(node); Tree.selectNode(node); } /* Event handler when plus/minus icon is clicked. Desides whenever node should be expanded or collapsed. */ Tree.ExpandCollapseNode = function (event) { var anchorClicked = event.srcElement /*IE*/ || event.target /*DOM*/; // <li><a><img> - <img> is capturing the event while (anchorClicked.tagName != "A") anchorClicked = anchorClicked.parentNode; anchorClicked.blur(); var node = anchorClicked.parentNode; // node has no children, and cannot be expanded or collapsed if (node.empty) return; Tree.obj = Tree.getObj(node); if (Tree.isNodeCollapsed(node)) Tree.expandNode(node); else Tree.collapseNode(node); // cancelling the event to prevent navigation. if (event.preventDefault == undefined) { // IE  event.cancelBubble = true; event.returnValue = false; } // if else { // DOM  event.preventDefault(); event.cancelBubble = true; } // else } /* Determines if specified node is selected. */ Tree.isNodeSelected = function (node) { return (node.isSelected == true) || (Tree.obj.selectedNode == node); } /* Determines if specified node is expanded. */ Tree.isNodeExpanded = function (node) { return (Tree.expandedClassName == node.className) || (node.expanded == true); } /* Determines if specified node is collapsed. */ Tree.isNodeCollapsed = function (node) { return (Tree.collapsedClassName == node.className) || (node.collapsed == true); } /* Determines if node currently selected is at same level as node specified (has same root). */ Tree.isSelectedNodeAtSameLevel = function (node) { if (Tree.obj.selectedNode == null) // no node currently selected return false; var i, currentNode, children = node.parentNode.childNodes; // all nodes at same level (li->ul->childNodes) for (i = 0; i < children.length; i++) if ((currentNode = children[i]) != node && Tree.isNodeSelected(currentNode)) return true; return false; } /* Mark node as selected and unmark prevoiusly selected. Node is marked with attribute and <a> is marked with css style to avoid mark <li> twise with css style expanded and selected. */ Tree.selectNode = function (node) { if (Tree.isNodeSelected(node)) // already marked return; if (Tree.obj.selectedNode != null) {// unmark previously selected node.  Tree.obj.selectedNode.isSelected = false; // remove css style from anchor  Tree.getNodeAnchor(Tree.obj.selectedNode).className = ""; } // if // collapse selected node if at same level if (Tree.isSelectedNodeAtSameLevel(node)) Tree.collapseNode(Tree.obj.selectedNode); // mark node as selected  Tree.obj.selectedNode = node; node.isSelected = true; Tree.getNodeAnchor(node).className = Tree.selectedClassName; } /* Expand collapsed node. Loads children nodes if needed. */ Tree.expandNode = function (node, avoidSaving) { if (node.empty) return; Tree.getNodeImage(node).src = Tree.expandedImage; node.className = Tree.expandedClassName; node.expanded = true; node.collapsed = false; if (Tree.areChildrenNotLoaded(node)) Tree.loadChildren(node); if (Tree.saveNodesStateInCookies && !avoidSaving) Tree.saveOpenedNode(node); } /* Collapse expanded node. */ Tree.collapseNode = function (node, avoidSaving) { if (node.empty) return; Tree.getNodeImage(node).src = Tree.collapsedImage; node.className = Tree.collapsedClassName; node.collapsed = true; node.expanded = false; if (Tree.saveNodesStateInCookies && !avoidSaving) Tree.saveClosedNode(node); } /* Returns plus/minus <img> for node specified. */ Tree.getNodeImage = function (node) { return node.getElementsByTagName("IMG")[0]; } /* Returns retreiveUrl for node specified. */ Tree.getNodeRetreiveUrl = function (node) { return node.getElementsByTagName("A")[0].href; } /* Returns node link <a> element (<li><a><img></a><a>) */ Tree.getNodeAnchor = function (node) { return node.getElementsByTagName("A")[1]; } /* Cancel loading children nodes. */ Tree.CancelLoad = function (event) { var i, node = event.srcElement /*IE*/ || event.target /*DOM*/; while (node.tagName != "LI") node = node.parentNode; // search node in queue for (i = 0; i<Tree.dwnldQueue.length; i++) if (Tree.dwnldQueue[i][1] == node) { // remove from queue  Tree.dwnldQueue.splice(i, 1); // collapse node  Tree.collapseNode(node); } // if } /* Loads text from url specified and returns it as result. */ Tree.loadUrl = function (url, async) { // create request object  var httpReq = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); // prepare request  httpReq.open("GET"/* method */, url /* url */, async == true /* async */, null /* login */, null /* password */); // send request  httpReq.send(null); return async == true? httpReq : httpReq.responseText; } /* Creates XmlDom document from xml text string. */ Tree.loadXml = function (xmlString) { var xmlDoc; if (window.DOMParser) /*Mozilla*/ xmlDoc = new DOMParser().parseFromString(xmlString, "text/xml"); else { if (document.implementation && document.implementation.createDocument) xmlDoc = document.implementation.createDocument("","", null); /*Konqueror*/else xmlDoc = new ActiveXObject("Microsoft.XmlDom"); /*IE*/ xmlDoc.async = false; xmlDoc.loadXML(xmlString); } // else return xmlDoc; } /* Determines if children are loaded for node specified. */ Tree.areChildrenNotLoaded = function (node) { return Tree.getNodeSpan(node) != null; } /* Finds loading span for node. */ Tree.getNodeSpan = function (node) { var span = node.getElementsByTagName("SPAN"); return (span.length > 0 && (span = span[0]).parentNode == node) ? span : null; } /* Enqueue load of children nodes for node specified. */ Tree.loadChildren = function (node) { // get url with children  var url = Tree.getNodeRetreiveUrl(node); // retreive xml text from url  var httpReq = Tree.loadUrl(url, true); // enqueue node loading if (Tree.dwnldQueue.push(new Array (httpReq, node)) == 1) window.setTimeout(Tree.checkLoad, Tree.dwnldCheckTimeout); } /* Creates HTML nodes list from XML nodes. */ Tree.convertXml2NodeList = function (xmlElement) { var ul = document.createElement("UL"); var i, node, children = xmlElement.childNodes; var index = 0; for (i = 0; i<children.length; i++) if ((node = children[i]).nodeType == 1 /* ELEMENT_NODE */) ul.appendChild(Tree.convertXml2Node(node)).nodeIndex = index++; return ul; } /* Adds event handler */ Tree.addEvent = function (obj, fn, ev) { if (ev == undefined) ev = "click"; // defaulting event to onclick if (obj.addEventListener) obj.addEventListener(ev, fn, false); elseif (obj.attachEvent) obj.attachEvent("on"+ev, fn); else obj.onclick = fn; } /* Determines if xml node has child nodes inside. */ Tree.hasXmlNodeChildren = function (xmlElement) { var i, children = xmlElement.childNodes; for (i = 0; i<children.length; i++) if ((node = children[i]).nodeType == 1 /* ELEMENT_NODE */) return true; return false; } /* Appends newly created node to node specified. Simply replace loading <span> at new node. */ Tree.appendNode = function (node, newNode) { node.replaceChild(newNode, Tree.getNodeSpan(node)); } /* Creates tree object. Loads it content from url specified. */ Tree.prototype.Create = function (url, obj) { var div = document.createElement("DIV"); div.id = Tree.instancePrefix + Tree.instanceCount++; div.className = Tree.treeClass; var xml = Tree.loadUrl(url, false); var xmlDoc = Tree.loadXml(xml); var newNode = Tree.convertXml2NodeList(xmlDoc.documentElement); div.appendChild(newNode); if (obj != undefined) { if (obj.appendChild) // is node  obj.appendChild(div); elseif (document.getElementById(obj)) // is node id  document.getElementById(obj).appendChild(div); } // if else document.body.appendChild(div); if (Tree.saveNodesStateInCookies) Tree.openAllSaved(div.id); } /* Creates HTML tree node (<li>) from xml element. */ Tree.convertXml2Node = function (xmlElement) { var li = document.createElement("LI"); var a1 = document.createElement("A"); var a2 = document.createElement("A"); var i1 = document.createElement("IMG"); var i2 = document.createElement("IMG"); var hasChildNodes = Tree.hasXmlNodeChildren(xmlElement); var retreiveUrl = xmlElement.getAttribute(Tree.xmlRetreiveUrl); // plus/minus icon  i1.className = Tree.plusMinusClassName; a1.appendChild(i1); Tree.addEvent(a1, Tree.ExpandCollapseNode); // plus/minus link  a1.href = retreiveUrl != null && retreiveUrl.length != 0 ? retreiveUrl : "about:blank"; li.appendChild(a1); // node icon  i2.src = xmlElement.getAttribute(Tree.xmlIcon); a2.appendChild(i2); // node link  a2.href = xmlElement.getAttribute(Tree.xmlUrl); a2.target = xmlElement.getAttribute(Tree.xmlTarget); a2.title = xmlElement.getAttribute(Tree.xmlCaption); a2.appendChild(document.createTextNode(xmlElement.getAttribute(Tree.xmlCaption))); Tree.addEvent(a2, Tree.NodeClick); li.appendChild(a2); // loading span if (!hasChildNodes && retreiveUrl != null && retreiveUrl.length != 0) { var span = document.createElement("SPAN"); span.innerHTML = Tree.loadingText; Tree.addEvent(span, Tree.CancelLoad); li.appendChild(span); } // if // add children if (hasChildNodes) li.appendChild(Tree.convertXml2NodeList(xmlElement)); if (hasChildNodes || retreiveUrl != null && retreiveUrl.length != 0) { if (xmlElement.getAttribute(Tree.xmlExpanded)) Tree.expandNode(li, true); else Tree.collapseNode(li, true); } // if else { i1.src = Tree.noChildrenImage; // no children  li.empty = true; } // else return li; } /* Retreives current tree object. */ Tree.getObj = function (node) { var obj = node; while (obj != null && obj.tagName != "DIV") obj = obj.parentNode; return obj; } Tree.getId = function (node) { var obj = Tree.getObj(node); if (obj) return obj.id; return""; } /* Retreives unique id for tree node. */ Tree.getNodeId = function (node) { var id = ""; var obj = node; while (obj != null && obj.tagName != "DIV") { if (obj.tagName == "LI" && obj.nodeIndex != null) id = "_" + obj.nodeIndex + id; obj = obj.parentNode; } // while // if (obj != null && obj.tagName == "DIV") // id = obj.id + "_" + id; return id; } /* Saves node as opened for reload. */ Tree.saveOpenedNode = function (node) { var treeId = Tree.getId(node); var state = Tree.getAllNodesSavedState(treeId); var nodeState = Tree.getNodeId(node) + ","; if (state.indexOf(nodeState) == -1) { state += nodeState; Tree.setAllNodesSavedState(treeId, state); } // if } /* Saves node as closed for reload. */ Tree.saveClosedNode = function (node) { var treeId = Tree.getId(node); var state = Tree.getAllNodesSavedState(treeId); state = state.replace(new RegExp(Tree.getNodeId(node) + ",", "g"), ""); Tree.setAllNodesSavedState(treeId, state); } Tree.getAllNodesSavedState = function (treeId) { var state = Tree.getCookie(Tree.cookiePrefix + "_" + treeId); return state == null ? "" : state; } Tree.setAllNodesSavedState = function (treeId, state) { Tree.setCookie(Tree.cookiePrefix + "_" + treeId, state); } /* Enques list of all opened nodes */ Tree.openAllSaved = function(treeId) { var nodes = Tree.getAllNodesSavedState(treeId).split(","); var i; for (i=0; i<nodes.length; i++) { var node = Tree.getNodeById(treeId, nodes[i]); if (node && Tree.isNodeCollapsed(node)) Tree.expandNode(node); } // for } Tree.getNodeById = function(treeId, nodeId) { var node = document.getElementById(treeId); if (!node) return null; var path = nodeId.split("_"); var i; for (i=1; i<path.length; i++) { if (node != null) { node = node.firstChild; while (node != null && node.tagName != "UL") node = node.nextSibling; } // if if (node != null) node = node.childNodes[path[i]]; elsebreak; } // for return node; } Tree.setCookie = function(sName, sValue) { document.cookie = sName + "=" + escape(sValue) + ";"; } Tree.getCookie = function(sName) { var a = document.cookie.split("; "); for (var i=0; i < a.length; i++) { var aa = a[i].split("="); if (sName == aa[0]) return unescape(aa[1]); } // for return null; } </script> </head> <body> <div id="tree"></div> <hr/> <script type="text/javascript"> new Tree().Create("tree.xml", "tree"); new Tree().Create("tree.xml"); </script> </body> </html> 








SimpleTree.zip( 7 k)

Related examples in the same category

1.Explorer based on tree
2.Yahoo! UI Library - Tree Control
3.Yahoo! UI Library - Tree Control 2
4.Tree Control
5.Dynamic TreeView Example
6.Yahoo! UI Library - Tree Control 3
7.Yahoo! UI Library - Tree Control 4
8.Yahoo! UI Library - Tree Control 5
9.Build a tree in JavaScript
10.Delete, insert items in a tree
11.Tree selection action handler
12.Expand, Collapse, Close, Open selected Tree item and branch
13.Change Tree Node Color and Icon
14.Checkbox tree node: checked, unchecked, get the checked items
15.Change tree expand and collapse icons
16.Drag and Drop between trees
17.Build tree from xml
18.Tree navigation bar
19.Navigation Tree
20.Navigation Tree menu based on XML
21.XML Tree
22.Building Collapsible Trees
23.Nano Tree
24.Tree which accepts drag and drop event in JavaScript (IE)
25.Elegant simple tree
26.folder tree static
close