dtree.js
// Node object function text2Html_View(strText) { if(strText==undefined) { return ''; } strText =strText.replace(/&/g,"&"); strText =strText.replace(/>/g,">"); strText =strText.replace(/</g,"<"); return strText; } function html_View2Text(strText) { if(strText==undefined) { return ''; } strText = strText.replace(/</g,"<"); strText = strText.replace(/>/g,">"); strText = strText.replace(/&/g,"&"); return strText; } function Node(id, pid, name, value, url, title, target, icon, iconOpen, open, isChecked, isType, isDisabled) { name=text2Html_View(name); this.id = id; this.pid = pid; this.name = name; this.url = url || null; this.title = title || null; this.target = target || null; this.icon = icon || null; this.iconOpen = iconOpen || null; this._io = open || false; this._is = false; // 是否展开 this._ls = false; // 在兄弟中是否为最后一个 this._hc = false; // 是否有子节点 this._ai = 0; // 绝对id编号 this._p; // 存储父节点对象 this.isChecked = isChecked || false; // 节点是否被用户选中 this.isType = isType || false; // 节点是否为类型 this.isDisabled = isDisabled || false; // 节点控件是否不可以被操作 this.value = value; // 保存节点的实际值,如数据库id }; // Tree object function dTree(objName,contextPath) { this.config = { target : null, folderLinks : true, // 选择节点的同时是否收缩展开或收缩节点, 文件夹是否带连接,当带链接时点击不会收缩或展开子节点 useSelection : true, // 选择某个节点是是否高亮显示 useCookies : false, useLines : true, useIcons : true, useStatusText : false, //状态条显示Name值,如果Name中有特殊字符报错。 closeSameLevel : false, //当点开同级其它节点,会关闭同级其它展开的节点。为True时只能查看某级下一个节点子目录。 inOrder : false, //当父节点总是加载在子节点前,设置为true可以加快树的生成速度,保险方式是保持默认false。 useControl : false, // 是否使用选择控件 controlType : 'checkbox', // 选择控件的类型input控件的type类型列表默认为checkbox isRootUseControl : false, // 根节点是否使用控件 isDisplay : true, // 树是否显示,默认为显示 typeIdArrayName : 'typeIdArray', // 封装类型选择id列表变量名 nodeIdArrayName : 'nodeIdArray', // 封装普通节点选择id列表变量名 cssLink : '<link href=/yourContextPath/usergroup/css/dtree.css type=text/css rel=StyleSheet>', // dTree所使用的css文件 strSplitNameSeparator : ';', // 用户选择的结点名称的分割符号 strSplitIdSeparator : ',', // 用户选择的database id列的分割符号 //如果设置正向或反向级联,一定要检查setSSS(id,isChecked) 是否定义,参看文档末尾函数 isCorrelateSelect : false, // 正向、向下级联选 如果控件的类型为checkbox,当选中类型时是否级联选择其下类型及节点,默认为false 不级联选择 isReverseCorrelateSelect : false, // 反向、向上级联选 如果控件的类型为checkbox,当选中类型或节点时是否级联选择其上类型直至根,默认为false 不向上级级联选择 isSingleCorrelateLayer : false, // 是否为单层级联选择。既只选择该类型下一级的类型及节点。默认为false无穷级级联选择 isSingleReverseCorrelateLayer : false, // 反向、向上级联选时,是否为单层级联选择。既只选择该类型或节点的上一级的类型。默认为false无穷级级联选择直至根节点 correlateSelectType : 'all', // 当选中类型节点时级联选择的类型。默认为all类型和节点一起选择。type只选择类型。node只选择节点。 isEventOnOk : false, // 用户选择确定后是否触发事件 isLockDisabledNodeChecked : false, // 锁定被设置为isDisabled==true结点控件的isChecked选择状态。false不锁定。true锁定。默认为false isDelayBuild : false //延迟加载 } this.icon = { root : '/yourContextPath/usergroup/images/dtree/root.gif', folder : '/yourContextPath/usergroup/images/dtree/folder.gif', folderOpen : '/yourContextPath/usergroup/images/dtree/folderopen.gif', node : '/yourContextPath/usergroup/images/dtree/page.gif', empty : '/yourContextPath/usergroup/images/dtree/empty.gif', line : '/yourContextPath/usergroup/images/dtree/line.gif', join : '/yourContextPath/usergroup/images/dtree/join.gif', joinBottom : '/yourContextPath/usergroup/images/dtree/joinbottom.gif', plus : '/yourContextPath/usergroup/images/dtree/plus.gif', plusBottom : '/yourContextPath/usergroup/images/dtree/plusbottom.gif', minus : '/yourContextPath/usergroup/images/dtree/minus.gif', minusBottom : '/yourContextPath/usergroup/images/dtree/minusbottom.gif', nlPlus : '/yourContextPath/usergroup/images/dtree/nolines_plus.gif', nlMinus : '/yourContextPath/usergroup/images/dtree/nolines_minus.gif' }; this.obj = objName; this.aNodes = []; this.aIndent = []; this.root = new Node(-1); this.selectedNode = null; this.selectedFound = false; this.completed = false; if(contextPath != undefined && contextPath != null){ this.config.cssLink = replaceAll(this.config.cssLink,"/yourContextPath",contextPath); this.icon.empty = replaceAll(this.icon.empty,"/yourContextPath",contextPath); this.icon.folder = replaceAll(this.icon.folder,"/yourContextPath",contextPath); this.icon.folderOpen = replaceAll(this.icon.folderOpen,"/yourContextPath",contextPath); this.icon.join = replaceAll(this.icon.join,"/yourContextPath",contextPath); this.icon.joinBottom = replaceAll(this.icon.joinBottom,"/yourContextPath",contextPath); this.icon.line = replaceAll(this.icon.line,"/yourContextPath",contextPath); this.icon.minus = replaceAll(this.icon.minus,"/yourContextPath",contextPath); this.icon.minusBottom = replaceAll(this.icon.minusBottom,"/yourContextPath",contextPath); this.icon.nlMinus = replaceAll(this.icon.nlMinus,"/yourContextPath",contextPath); this.icon.nlPlus = replaceAll(this.icon.nlPlus,"/yourContextPath",contextPath); this.icon.node = replaceAll(this.icon.node,"/yourContextPath",contextPath); this.icon.plus = replaceAll(this.icon.plus,"/yourContextPath",contextPath); this.icon.plusBottom = replaceAll(this.icon.plusBottom,"/yourContextPath",contextPath); this.icon.root = replaceAll(this.icon.root,"/yourContextPath",contextPath); this.icon.nlMinus=replaceAll(this.icon.nlMinus,"/yourContextPath",contextPath); } }; dTree.prototype.initTreeContextPath = function(contextPath) { this.config.cssLink = replaceAll(this.config.cssLink,"/yourContextPath",contextPath); this.icon.empty = replaceAll(this.icon.empty,"/yourContextPath",contextPath); this.icon.folder = replaceAll(this.icon.folder,"/yourContextPath",contextPath); this.icon.folderOpen = replaceAll(this.icon.folderOpen,"/yourContextPath",contextPath); this.icon.join = replaceAll(this.icon.join,"/yourContextPath",contextPath); this.icon.joinBottom = replaceAll(this.icon.joinBottom,"/yourContextPath",contextPath); this.icon.line = replaceAll(this.icon.line,"/yourContextPath",contextPath); this.icon.minus = replaceAll(this.icon.minus,"/yourContextPath",contextPath); this.icon.minusBottom = replaceAll(this.icon.minusBottom,"/yourContextPath",contextPath); this.icon.nlMinus = replaceAll(this.icon.nlMinus,"/yourContextPath",contextPath); this.icon.nlPlus = replaceAll(this.icon.nlPlus,"/yourContextPath",contextPath); this.icon.node = replaceAll(this.icon.node,"/yourContextPath",contextPath); this.icon.plus = replaceAll(this.icon.plus,"/yourContextPath",contextPath); this.icon.plusBottom = replaceAll(this.icon.plusBottom,"/yourContextPath",contextPath); this.icon.root = replaceAll(this.icon.root,"/yourContextPath",contextPath); this.icon.nlMinus=replaceAll(this.icon.nlMinus,"/yourContextPath",contextPath); }; // Adds a new node to the node array dTree.prototype.add = function(id, pid, name, isType, isChecked, isDisabled, url, title, target, icon, iconOpen, open) { // 转换字符型为boolean型,便于统一,也防止jsp程序输出到页面为''产生js脚本错误 if(isChecked=='true' || isChecked==true) { isChecked = true; } else { isChecked = false; } if(isType=='true' || isType==true) { isType = true; } else { isType = false; } if(isDisabled=='true' || isDisabled==true) { isDisabled = true; } else { isDisabled = false; } var valueTemp = id; // 为id,pid添加特制字头 if(isType==true) { id = 't' + id; if((pid!='-1') && (pid!=-1)) { pid = 't' + pid; } } else { id = 'n' + id; if((pid!='-1') && (pid!=-1)) { pid = 't' + pid; } } this.aNodes[this.aNodes.length] = new Node(id, pid, name, valueTemp, url, title, target, icon, iconOpen, open, isChecked, isType, isDisabled); }; // Open/close all nodes dTree.prototype.openAll = function() { this.oAll(true); }; dTree.prototype.closeAll = function() { this.oAll(false); }; // 生成树html dTree.prototype.toString = function() { // shield useCookies this.config.useCookies = false; var str = '<div class="dtree" style="padding:3px;" '; if(this.config.isDisplay==false) { str += 'style="display:none"'; } str += '>\n'; if (document.getElementById) { if (this.config.useCookies) this.selectedNode = this.getSelected(); str += this.addNode(this.root); //alert(str); } else str += 'Browser not supported.'; str += '</div>'; if (!this.selectedFound) this.selectedNode = null; this.completed = true; return str; }; // Creates the tree structure // 添加pNode下所有子节点结构。(一层) dTree.prototype.addNode = function(pNode) { var str = ''; var n=0; if (this.config.inOrder) n = pNode._ai; var sss=new StringBuffer(''); for (n; n<this.aNodes.length; n++) { if (this.aNodes[n].pid == pNode.id) { var cn = this.aNodes[n]; cn._p = pNode; cn._ai = n; this.setCS(cn); if (!cn.target && this.config.target) cn.target = this.config.target; if (cn._hc && !cn._io && this.config.useCookies) cn._io = this.isOpen(cn.id); if (!this.config.folderLinks && cn._hc) cn.url = null; if (this.config.useSelection && cn.id == this.selectedNode && !this.selectedFound) { cn._is = true; this.selectedNode = n; this.selectedFound = true; } //str += this.node(cn, n); sss.append(this.node(cn, n)); if (cn._ls){str=sss.toString(); break;} } } return str; }; function StringBuffer(){this.b=[];} StringBuffer.prototype.append=function(a) { //this.b.push(a); this.b[this.b.length]=a; } StringBuffer.prototype.toString=function(){return this.b.join("");} StringBuffer.prototype.clear=function(){var count=this.b.length;for(var i=count;i>0;i--){this.b.pop();}} var strBuf={ b:[], append:function(a) { //this.b.push(a); this.b[this.b.length]=a; }, toString:function(){return this.b.join("");}, clear:function(){for(var i=this.b.length;i>0;i--){this.b.pop();}} }; // Creates the node icon, url and text dTree.prototype.node = function(node, nodeId) { var str=new StringBuffer(''); str.append('<div class="dTreeNode">'); str.append(this.indent(node, nodeId)); //var str = '<div class="dTreeNode">' + this.indent(node, nodeId); // 判断是否使用控件 if(this.config.useControl==true) { if(this.root.id!=node.pid || this.config.isRootUseControl==true) {// 不为根节点或设置了根节点使用控件生成控件 // 使用控件,生成html代码 //str += '<input id="ctrl' + this.obj + nodeId + '" name="'; str.append('<input id="ctrl'); str.append(this.obj); str.append(nodeId); str.append('" name="'); // 根据类型生成控件名称 if(node.isType==true) { //str += this.config.typeIdArrayName; str.append(this.config.typeIdArrayName); } else { //str += this.config.nodeIdArrayName; str.append(this.config.nodeIdArrayName); } //str += '" type="' + this.config.controlType + '" value="' + node.value + '" '; str.append('" type="'); str.append(this.config.controlType); str.append('" value="'); str.append(node.value); str.append('" '); // 根据操作表示设置控件可操作状态 if(node.isDisabled==true) {// 控件不可见 //str += ' style="display:none" '; str.append(' style="display:none" '); } // 判断是否为checkbox 或 radio if(this.config.controlType=='checkbox' || this.config.controlType=='radio') { //str += ' style="width:15px; height:15px" '; str.append(' style="width:15px; height:15px" '); // 是选择类型控件根据节点的选择状态设置控件状态 if(node.isChecked==true) { //str += ' checked="checked" '; str.append(' checked="checked" '); } // 用户改变页面控件选择状态时同时改变相应节点选择状态 if(node.isDisabled==false) { //str += ' onClick="javascript: try{setSSS(this.id,this.checked);}catch(e){}' + this.obj + '.setChecked(' + nodeId + ', this.checked);" '; str.append(' onClick="javascript: try{setSSS(this.id,this.checked);}catch(e){}'); str.append(this.obj); str.append('.setChecked('); str.append(nodeId); str.append(', this.checked);" '); } } //str += ' />'; str.append(' />'); } } if (this.config.useIcons) { if (!node.icon) node.icon = (this.root.id == node.pid) ? this.icon.root : ((node._hc || node.isType) ? this.icon.folder : this.icon.node); if (!node.iconOpen) node.iconOpen = (node._hc || node.isType) ? this.icon.folderOpen : this.icon.node; if (this.root.id == node.pid) { node.icon = this.icon.root; node.iconOpen = this.icon.root; } //str += '<img id="i' + this.obj + nodeId + '" src="' + ((node._io) ? node.iconOpen : node.icon) + '" align="absmiddle" /> '; str.append('<img id="i'); str.append(this.obj); str.append(nodeId); str.append('" src="'); str.append(((node._io) ? node.iconOpen : node.icon)); str.append('" align="absmiddle" /> '); } if (node.url) { //str += '<a id="s' + this.obj + nodeId + '" class="' + ((this.config.useSelection) ? ((node._is ? 'nodeSel' : 'node')) : 'node') + '" href="' + node.url + '"'; str.append('<a id="s'); str.append(this.obj); str.append(nodeId); str.append('" class="'); str.append(((this.config.useSelection) ? ((node._is ? 'nodeSel' : 'node')) : 'node')); str.append('" href="'); str.append(node.url); str.append('"'); if (node.title) {str.append(' title="');str.append(node.title);str.append('"');}//str += ' title="' + node.title + '"'; if (node.target) {str.append(' target="');str.append(node.target);str.append('"');}//str += ' target="' + node.target + '"'; if (this.config.useStatusText) { str.append(' onmouseover="window.status=\''); str.append(node.name); str.append('\';return true;" onmouseout="window.status=\'\';return true;" '); } //str += ' onmouseover="window.status=\'' + node.name + '\';return true;" onmouseout="window.status=\'\';return true;" '; if (this.config.useSelection && ((node._hc && this.config.folderLinks) || !node._hc)) { str.append(' onclick="javascript: '); str.append(this.obj); str.append('.s('); str.append(nodeId); str.append(');"'); } //str += ' onclick="javascript: ' + this.obj + '.s(' + nodeId + ');"'; //str += '>'; str.append('>'); } else if ((!this.config.folderLinks || !node.url) && node._hc && node.pid != this.root.id) { //str += '<a style="cursor:hand" onClick="javascript: ' + this.obj + '.o(' + nodeId + ');" class="node">'; str.append('<a style="cursor:hand;text-decoration:none;color:black" onClick="javascript: '); str.append(this.obj); str.append('.o('); str.append(nodeId); str.append(');" class="node">'); } //str += node.name; str.append(node.name); if (node.url || ((!this.config.folderLinks || !node.url) && node._hc)) str.append('</a>');//str += '</a>'; //str += '</div>'; str.append('</div>'); if (node._hc) { //str += '<div id="d' + this.obj + nodeId + '" class="clip" style="display:' + ((this.root.id == node.pid || node._io) ? 'block' : 'none') + ';">'; str.append('<div id="d'); str.append(this.obj); str.append(nodeId); str.append('" class="clip" style="display:'); str.append(((this.root.id == node.pid || node._io) ? 'block' : 'none')); str.append(';">'); if(this.config.isDelayBuild==undefined || this.config.isDelayBuild==false || (this.config.isDelayBuild==true && node._p.id==this.root.id)) { //str += this.addNode(node); str.append(this.addNode(node)); } //str += '</div>'; str.append('</div>'); } this.aIndent.pop(); return str.toString(); }; // Adds the empty and line icons dTree.prototype.indent = function(node, nodeId) { var str = new StringBuffer('');; if (this.root.id != node.pid) { for (var n=0; n<this.aIndent.length; n++) { //str += '<img src="' + ( (this.aIndent[n] == 1 && this.config.useLines) ? this.icon.line : this.icon.empty ) + '" align="absmiddle" />'; str.append('<img src="'); str.append(( (this.aIndent[n] == 1 && this.config.useLines) ? this.icon.line : this.icon.empty )); str.append('" align="absmiddle" />'); } (node._ls) ? this.aIndent.push(0) : this.aIndent.push(1); if (node._hc) { str.append('<img id="j'); str.append(this.obj); str.append(nodeId); str.append('" style="CURSOR:hand" onClick="javascript: '); str.append(this.obj); str.append('.o('); str.append(nodeId); str.append(');" src="'); //str += '<img id="j' + this.obj + nodeId + '" style="CURSOR:hand" onClick="javascript: ' + this.obj + '.o(' + nodeId + ');" src="'; if (!this.config.useLines) str.append((node._io) ? this.icon.nlMinus : this.icon.nlPlus);//str += (node._io) ? this.icon.nlMinus : this.icon.nlPlus; else str.append(( (node._io) ? ((node._ls && this.config.useLines) ? this.icon.minusBottom : this.icon.minus) : ((node._ls && this.config.useLines) ? this.icon.plusBottom : this.icon.plus ) )); //str += ( (node._io) ? ((node._ls && this.config.useLines) ? this.icon.minusBottom : this.icon.minus) : ((node._ls && this.config.useLines) ? this.icon.plusBottom : this.icon.plus ) ); //str += '" align="absmiddle" />'; str.append('" align="absmiddle" />'); } else { str.append('<img src="'); str.append(( (this.config.useLines) ? ((node._ls) ? this.icon.joinBottom : this.icon.join ) : this.icon.empty)); str.append('" align="absmiddle" />'); } //str += '<img src="' + ( (this.config.useLines) ? ((node._ls) ? this.icon.joinBottom : this.icon.join ) : this.icon.empty) + '" align="absmiddle" />'; } return str.toString(); }; // Checks if a node has any children and if it is the last sibling dTree.prototype.setCS = function(node) { var lastId; for (var n=0; n<this.aNodes.length; n++) { if (this.aNodes[n].pid == node.id) node._hc = true; if (this.aNodes[n].pid == node.pid) lastId = this.aNodes[n].id; } if (lastId==node.id) node._ls = true; }; // Returns the selected node dTree.prototype.getSelected = function() { var sn = this.getCookie('cs' + this.obj); return (sn) ? sn : null; }; // Highlights the selected node dTree.prototype.s = function(id) { if (!this.config.useSelection) return; var cn = this.aNodes[id]; if (cn._hc && !this.config.folderLinks) return; if (this.selectedNode != id) { if (this.selectedNode || this.selectedNode==0) { eOld = document.getElementById("s" + this.obj + this.selectedNode); eOld.className = "node"; } eNew = document.getElementById("s" + this.obj + id); eNew.className = "nodeSel"; this.selectedNode = id; if (this.config.useCookies) this.setCookie('cs' + this.obj, cn.id); } }; // Toggle Open or close dTree.prototype.o = function(id) { var cn = this.aNodes[id]; if(this.config.isDelayBuild==true && cn._io==false) { var childrenDIV = document.getElementById('d' + this.obj + id); if(childrenDIV!=null && childrenDIV.innerHTML=="") { var nodeTemp = cn; var indentArray = new Array(); while(nodeTemp._p.id!=this.root.id) { indentArray[indentArray.length] = (nodeTemp._ls) ? 0 : 1; nodeTemp = nodeTemp._p; } for(var i = indentArray.length - 1; i>=0; i--) { this.aIndent.push(indentArray[i]); } childrenDIV.innerHTML = this.addNode(cn); for(var i = 0; i < indentArray.length; i++) { this.aIndent.pop(); } } } this.nodeStatus(!cn._io, id, cn._ls); cn._io = !cn._io; if (this.config.closeSameLevel) this.closeLevel(cn); if (this.config.useCookies) this.updateCookie(); var lId=cn.id; /*for (var n=0; n<this.aNodes.length; n++) { if (this.aNodes[n]._hc && this.aNodes[n].pid == lId) { this.o(this.aNodes[n]._ai); } }*/ }; dTree.prototype.oSelect = function(id) { var cn = this.aNodes[id]; if(this.config.isDelayBuild==true && cn._io==false) { var childrenDIV = document.getElementById('d' + this.obj + id); if(childrenDIV!=null && childrenDIV.innerHTML=="") { var nodeTemp = cn; var indentArray = new Array(); while(nodeTemp._p.id!=this.root.id) { indentArray[indentArray.length] = (nodeTemp._ls) ? 0 : 1; nodeTemp = nodeTemp._p; } for(var i = indentArray.length - 1; i>=0; i--) { this.aIndent.push(indentArray[i]); } childrenDIV.innerHTML = this.addNode(cn); for(var i = 0; i < indentArray.length; i++) { this.aIndent.pop(); } } } this.nodeStatus(!cn._io, id, cn._ls); cn._io = !cn._io; if (this.config.closeSameLevel) this.closeLevel(cn); if (this.config.useCookies) this.updateCookie(); var lId=cn.id; for (var n=0; n<this.aNodes.length; n++) { if (this.aNodes[n]._hc && this.aNodes[n].pid == lId) { this.oSelect(this.aNodes[n]._ai); } } }; // Open or close all nodes dTree.prototype.oAll = function(status) { for (var n=0; n<this.aNodes.length; n++) { if (this.aNodes[n]._hc && this.aNodes[n].pid != this.root.id) { this.nodeStatus(status, n, this.aNodes[n]._ls) this.aNodes[n]._io = status; } } if (this.config.useCookies) this.updateCookie(); }; // Opens the tree to a specific node dTree.prototype.openTo = function(nId, bSelect, bFirst) { if (!bFirst) { for (var n=0; n<this.aNodes.length; n++) { if (this.aNodes[n].id == nId) { nId=n; break; } } } var cn=this.aNodes[nId]; if (cn.pid==this.root.id || !cn._p) return; cn._io = true; cn._is = bSelect; if (this.completed && cn._hc) this.nodeStatus(true, cn._ai, cn._ls); if (this.completed && bSelect) this.s(cn._ai); else if (bSelect) this._sn=cn._ai; this.openTo(cn._p._ai, false, true); }; // Opens the tree to a specific node by logic id dTree.prototype.openToAndHighlightSelectedNode = function(nId, isType, bSelect) { for(var i = 0; i < this.aNodes.length; i++) { if(this.aNodes[i].value==nId && this.aNodes[i].isType==isType) { break; } } if(i < this.aNodes.length) { this.openTo(this.aNodes[i]._ai, bSelect, true); } }; // Closes all nodes on the same level as certain node dTree.prototype.closeLevel = function(node) { for (var n=0; n<this.aNodes.length; n++) { if (this.aNodes[n].pid == node.pid && this.aNodes[n].id != node.id && this.aNodes[n]._hc) { this.nodeStatus(false, n, this.aNodes[n]._ls); this.aNodes[n]._io = false; this.closeAllChildren(this.aNodes[n]); } } } // Closes all children of a node dTree.prototype.closeAllChildren = function(node) { for (var n=0; n<this.aNodes.length; n++) { if (this.aNodes[n].pid == node.id && this.aNodes[n]._hc) { if (this.aNodes[n]._io) this.nodeStatus(false, n, this.aNodes[n]._ls); this.aNodes[n]._io = false; this.closeAllChildren(this.aNodes[n]); } } } // Change the status of a node(open or closed) dTree.prototype.nodeStatus = function(status, id, bottom) { eDiv = document.getElementById('d' + this.obj + id); eJoin = document.getElementById('j' + this.obj + id); if (this.config.useIcons) { eIcon = document.getElementById('i' + this.obj + id); eIcon.src = (status) ? this.aNodes[id].iconOpen : this.aNodes[id].icon; } eJoin.src = (this.config.useLines)? ((status)?((bottom)?this.icon.minusBottom:this.icon.minus):((bottom)?this.icon.plusBottom:this.icon.plus)): ((status)?this.icon.nlMinus:this.icon.nlPlus); eDiv.style.display = (status) ? 'block': 'none'; }; // [Cookie] Clears a cookie dTree.prototype.clearCookie = function() { var now = new Date(); var yesterday = new Date(now.getTime() - 1000 * 60 * 60 * 24); this.setCookie('co'+this.obj, 'cookieValue', yesterday); this.setCookie('cs'+this.obj, 'cookieValue', yesterday); }; // [Cookie] Sets value in a cookie dTree.prototype.setCookie = function(cookieName, cookieValue, expires, path, domain, secure) { document.cookie = escape(cookieName) + '=' + escape(cookieValue) + (expires ? '; expires=' + expires.toGMTString() : '') + (path ? '; path=' + path : '') + (domain ? '; domain=' + domain : '') + (secure ? '; secure' : ''); }; // [Cookie] Gets a value from a cookie dTree.prototype.getCookie = function(cookieName) { var cookieValue = ''; var posName = document.cookie.indexOf(escape(cookieName) + '='); if (posName != -1) { var posValue = posName + (escape(cookieName) + '=').length; var endPos = document.cookie.indexOf(';', posValue); if (endPos != -1) cookieValue = unescape(document.cookie.substring(posValue, endPos)); else cookieValue = unescape(document.cookie.substring(posValue)); } return (cookieValue); }; // [Cookie] Returns ids of open nodes as a string dTree.prototype.updateCookie = function() { var str = ''; for (var n=0; n<this.aNodes.length; n++) { if (this.aNodes[n]._io && this.aNodes[n].pid != this.root.id) { if (str) str += '.'; str += this.aNodes[n].id; } } this.setCookie('co' + this.obj, str); }; // [Cookie] Checks if a node id is in a cookie dTree.prototype.isOpen = function(id) { var aOpen = this.getCookie('co' + this.obj).split('.'); for (var n=0; n<aOpen.length; n++) if (aOpen[n] == id) return true; return false; }; // If Push and pop is not implemented by the browser if (!Array.prototype.push) { Array.prototype.push = function array_push() { for(var i=0;i<arguments.length;i++) this[this.length]=arguments[i]; return this.length; } }; if (!Array.prototype.pop) { Array.prototype.pop = function array_pop() { lastElement = this[this.length-1]; this.length = Math.max(this.length-1,0); return lastElement; } }; dTree.prototype.setTreeNodeChecked = function(id, checked) { this.aNodes[id].isChecked = checked; var elementTemp = document.getElementById('ctrl' + this.obj + id); if(elementTemp!=null) { elementTemp.checked = checked; } }; // 以数组中id绝对号的节点为根,如果是类型节点深度优先,如果是节点广度优先。级联选择类型及节点 dTree.prototype.setCorrelateSelect = function(id, checked) { // 设置当前类型节点选择状态 this.setTreeNodeChecked(id, checked); // 级联选择其下类型及节点选择状态 for(var i=0; i < this.aNodes.length; i++) {// 循环级联选择类型及节点 if(this.aNodes[i].pid==this.aNodes[id].id) {// 循环当前节点为根节点下一级子类型或节点 if(this.aNodes[i].isType==false) {// 是节点 if(this.config.correlateSelectType=='all' || this.config.correlateSelectType=='node') { this.setTreeNodeChecked(this.aNodes[i]._ai, checked); } } else { // 类型节点 // 判断级联层次 if(this.config.isSingleCorrelateLayer==false) {// 无穷级联选择 this.setCorrelateSelect(this.aNodes[i]._ai, checked); } else {// 一层 if(this.config.correlateSelectType=='all' || this.config.correlateSelectType=='type') { this.setTreeNodeChecked(this.aNodes[i]._ai, checked); } } } } } }; // get lId(its parentId = 0) from the tree for a specific node dTree.prototype.getBranchRootId = function(nId, isType) { for(var i = 0; i < this.aNodes.length; i++) { if(this.aNodes[i].value==nId && this.aNodes[i].isType==isType) { break; } } if(i < this.aNodes.length) { return this.getParentRootId(this.aNodes[i]._ai, true); } }; dTree.prototype.getParentRootId = function(nId, bFirst) { if (!bFirst) { for (var n=0; n<this.aNodes.length; n++) { if (this.aNodes[n].id == nId) { nId=n; break; } } } var cn=this.aNodes[nId]; if(cn._p._ai == 0) { return cn.value; } else if(!cn._p) return -1; else return this.getParentRootId(cn._p._ai, true); }; // 根据数组中id,设置节点当前选择状态 dTree.prototype.setChecked = function(id, checked) { // 控件为radio类型,清除所有节点控件选择状态 if(this.config.controlType=='radio') { for(var i=0; i < this.aNodes.length; i++) { this.aNodes[i].isChecked = false; } this.setTreeNodeChecked(id, checked); } else {// 为checkbox控件 // 判断是否使用级联选择 if(this.config.isCorrelateSelect==true) {// 级联选择 if(this.aNodes[id].isType==true) { this.setCorrelateSelect(id, checked); } else { this.setTreeNodeChecked(id, checked); } } else { this.setTreeNodeChecked(id, checked); } // 判断当前节点是否是选中状态,只有选中才进行反向级联选 if(checked==true) { // 判断是否使用反向级联选 if(this.config.isReverseCorrelateSelect==true) {// 反向级联选 // 得到当前类型或节点的父亲节点对象,初始化 var parentNodeTemp = this.aNodes[id]._p; while(parentNodeTemp.pid!=undefined) {// 非根节点选中该类型节点 if(parentNodeTemp.pid!=-1 || this.config.isRootUseControl==true) { this.setTreeNodeChecked(parentNodeTemp._ai, true); } parentNodeTemp = parentNodeTemp._p; } } } } }; // 根据控件id值设置选择状态 dTree.prototype.setCheckedCtrlId = function(id, checked) { var str = ''; for(var i=0; i<id.length; i++) { var char1 = id.substr(i, 1); if(char1=='0' || char1=='1' || char1=='2' || char1=='3' || char1=='4' || char1=='5' || char1=='6' || char1=='7' || char1=='8' || char1=='9') { str += char1; } } if(str!='') { this.aNodes[str].isChecked = checked; } }; function showModalDialogTree(tree, inputCtrlId, contextPath) { var array = new Array(3); array[0] = tree; array[1] = inputCtrlId; array[2] = window; if(contextPath==null || contextPath.length==0){ contextPath = '/yourContextPath'; alert("Error,required three params,third param is contextPath!"); } window.showModalDialog(contextPath+"/jsp/common/tree.jsp", array, 'dialogWidth=350px;dialogHeight=550px;status:no;resizable:yes;help:no;scroll:no'); //window.open(contextPath+"/jsp/common/tree.jsp", array, 'dialogWidth=350px;dialogHeight=550px;status:no;resizable:yes;help:no;scroll:no'); //window.open(contextPath+"/jsp/commonTreeIframe.jsp?tree=" + tree.obj + "&ctrl=" + inputCtrlId, 'TreeWindow', 'width=350,height=550,status=no,resizable=no,help=no,scroll=no'); } function printTreeToNewWindow(tree, inputCtrlId, contextPath) { if(contextPath==null || contextPath.length==0){ contextPath = '/yourContextPath'; alert("Error,required three params,third param is contextPath!"); } showModalDialogTree(tree, inputCtrlId, contextPath); } function replaceAll(strPrimalString, strOldSubString, strNewSubString) { var str = strPrimalString; while(str.indexOf(strOldSubString) >= 0) { str = str.replace(strOldSubString, strNewSubString); } return str; } function replaceSpecialCharacter(str) { var str1 = replaceAll(str, '&', '&'); var str2 = replaceAll(str1, '<', '<'); var str3 = replaceAll(str2, '>', '>'); var str4 = replaceAll(str3, ''', '\''); var str5 = replaceAll(str4, '"', '\"'); return str5; } // 得到用户选择的节点名称,并以分号";"分割,如需要其它分割符请在config中定义 dTree.prototype.getSelectedNameList = function() { if(this.config.useControl==true) {// 使用控件 // 判断用户使用控件类型 var strName = ''; if(this.config.controlType=='radio') { var str = ''; for(var i=0; i < this.aNodes.length; i++) { if(this.aNodes[i].isChecked==true) { strName = this.aNodes[i].name; str += html_View2Text(strName) + this.config.strSplitNameSeparator + ' '; strName = ''; break; } } } else if(this.config.controlType=='checkbox') { var str = ''; for(var i=1; i < this.aNodes.length; i++) { if(this.aNodes[i].isChecked==true) { if(this.aNodes[i].isType==true) {// 类型 if(this.config.correlateSelectType=='all' || this.config.correlateSelectType=='type') { strName = this.aNodes[i].name; str += html_View2Text(strName) + this.config.strSplitNameSeparator + ' '; strName = ''; } } else {// 节点 if(this.config.correlateSelectType=='all' || this.config.correlateSelectType=='node') { strName = this.aNodes[i].name; str += html_View2Text(strName) + this.config.strSplitNameSeparator + ' '; strName = ''; } } } } } // str = replaceSpecialCharacter(str); if(str.substring(str.length - 2, str.length)==this.config.strSplitNameSeparator + ' ') { return str.substring(0, str.length - 2); } else { return str; } } }; // 得到用户选择的节点数据库id,并以分号","分割,如需要其它分割符请在config中定义 dTree.prototype.getSelectedDatabaseIdList = function() { if(this.config.useControl==true) {// 使用控件 // 判断用户使用控件类型 var str = ''; if(this.config.controlType=='radio') { for(var i=0; i < this.aNodes.length; i++) { if(this.aNodes[i].isChecked==true) { str += this.aNodes[i].value + this.config.strSplitIdSeparator; break; } } } else if(this.config.controlType=='checkbox') { for(var i=1; i < this.aNodes.length; i++) { if(this.aNodes[i].isChecked==true) { if(this.aNodes[i].isType==true) {// 类型 if(this.config.correlateSelectType=='all' || this.config.correlateSelectType=='type') { str += this.aNodes[i].value + this.config.strSplitIdSeparator; } } else {// 节点 if(this.config.correlateSelectType=='all' || this.config.correlateSelectType=='node') { str += this.aNodes[i].value + this.config.strSplitIdSeparator; } } } } } if(str.substring(str.length - 1, str.length)==this.config.strSplitIdSeparator) { return str.substring(0, str.length - 1); } else { return str; } } }; dTree.prototype.getSelectedTypeIdList = function() { if(this.config.useControl==true) {// 使用控件 // 判断用户使用控件类型 var str = ''; if(this.config.controlType=='radio') { for(var i=0; i < this.aNodes.length; i++) { if(this.aNodes[i].isChecked==true) { str += this.aNodes[i].value + this.config.strSplitIdSeparator; break; } } } else if(this.config.controlType=='checkbox') { for(var i=1; i < this.aNodes.length; i++) { if(this.aNodes[i].isChecked==true) { if(this.aNodes[i].isType==true) {// 类型 str += this.aNodes[i].value + this.config.strSplitIdSeparator; } } } } if(str.substring(str.length - 1, str.length)==this.config.strSplitIdSeparator) { return str.substring(0, str.length - 1); } else { return str; } } }; // 根据节点数据库ID和类型标志高亮显示相应单个节点 dTree.prototype.highlightSelectedNode = function(value, isType) { if(value=="") { value = 0; } if(isType=="true" || isType==true) { isType = true; } else { isType = false; } for(var i=0; i < this.aNodes.length; i++) {// 遍历这个树节点 // 判断是否存在与value和isType值相等的节点 if(this.aNodes[i].value==value && this.aNodes[i].isType==isType) { // 将相应节点加亮显示 //alert(this.aNodes[i]._ai); this.s(this.aNodes[i]._ai); break; } } }; // 根据数组中id绝对号及可操作状态,设置对应控件当前可操作状态 dTree.prototype.setNodeControlDisabled = function(id, disabled) { var elementTemp = document.getElementById('ctrl' + this.obj + id); if(elementTemp!=null) { elementTemp.disabled = disabled; } }; // 将所有树中的控件设置成disabled状态 dTree.prototype.setAllControlDisabled = function(disabled) { if(this.config.useControl==true) {// 使用控件 for(var i=0; i < this.aNodes.length; i++) {// 遍历这个树节点 // 设置状态 this.setNodeControlDisabled(this.aNodes[i]._ai, disabled); } } }; // 根据节点数据库ID和类型标志设置选中状态 dTree.prototype.setCheckedNode = function(id, isType, checked) { if(isType=="true" || isType==true) { isType = true; } else { isType = false; } for(var i=0; i < this.aNodes.length; i++) {// 遍历树节点 // 判断是否存在与value和isType值相等的节点 if(this.aNodes[i].value==id && this.aNodes[i].isType==isType) { // 将相应节点加亮显示 this.setChecked(this.aNodes[i]._ai, checked); break; } } }; dTree.prototype.reset = function() { if(this.config.useControl==true) {// 只有使用控件才设置选择状态 // 判断使用控件类型 if(this.config.controlType=='radio') { // 清除树对象选择状态 for(var i=0; i < this.aNodes.length; i++) { this.aNodes[i].isChecked = false; } // 从页面控件复制选择状态 for(var i=0; i < this.aNodes.length; i++) { var elementTemp = document.getElementById('ctrl' + this.obj + this.aNodes[i]._ai); if(elementTemp!=null) { if(elementTemp.checked==true) { // 设置选择状态 this.aNodes[i].isChecked = true; break; } } } } else if(this.config.controlType=='checkbox') { // 复制选择状态 for(var i=0; i < this.aNodes.length; i++) { var elementTemp = document.getElementById('ctrl' + this.obj + this.aNodes[i]._ai); if(elementTemp!=null) { // 设置选择状态 this.aNodes[i].isChecked = elementTemp.checked; } } } } }; //根据id取得节点名称 dTree.prototype.getNodeName = function(id, isType) { if(isType=="true" || isType==true) { isType = true; } else { isType = false; } var strName = ""; for(var i=0; i < this.aNodes.length; i++) { // 遍历树节点 // 判断是否存在与value和isType值相等的节点 if(this.aNodes[i].value==id && this.aNodes[i].isType==isType) { strName = this.aNodes[i].name; break; } } return strName; };
jsp页面:
<script language="JavaScript" type="text/JavaScript"> <!-- var myTree = new dTree('myTree','<%=request.getContextPath()%>'); myTree.config.useControl = false; myTree.config.useCookies = false; myTree.config.isEventOnOk = true; //myTree.config.controlType = ' '; myTree.config.typeIdArrayName = 'selectedTypeId'; //is or not need delayload on count of tree node //alert("<c:out value="${fn:length(myTree)}" />"); <c:if test="${fn:length(myTree)>delayBuildNodeCount}"> myTree.config.isDelayBuild = true; </c:if> //id, pid, name, isType, isChecked, isDisabled, url, title, target, icon, iconOpen, open myTree.add('0','-1','所有群组', 'true', 'false', 'true','javascript:getOrgDetail(0)'); <c:forEach var="myTreeNode" items="${myTree}" > myTree.add('<c:out value="${myTreeNode.keyId}"/>', '<c:out value="${myTreeNode.parentKeyId}"/>', <c:set var="strNameTemp" value="${myTreeNode.groupName}" /> '<%=SpecialCharUtil.formatToJavaScript((String)pageContext.getAttribute("strNameTemp"))%>', 'true', 'false','false','javascript:getOrgDetail(<c:out value="${myTreeNode.keyId}"/>)'); //javascript:alert(<c:out value="${myTreeNode.keyId}"/>); </c:forEach> function getOrgDetail(orgId) { $.ajax({ dataType: "json", type: "POST", data: "", cache: false, url: "group_getOrgDetailById.action?ssdusergroupmain.keyId=" + orgId, error: function(){ alert('加载数据出错...'); return false; }, success: function(data){ if (data != null && data.keyId != null) { parent.$("#keyid").val(data.keyId); parent.$("#orgname").val(data.groupName); parent.$("#parentname").val(parent.$("#treeFrame").contents().find("span[id='" + data.parentKeyId + "']").text()); parent.$("#orgtype").val(data.sendLevel); parent.$("#parentid").val(data.parentKeyId); parent.$("#orgtypeid").val(data.sendLevel); $.ajax({ dataType: "json", type: "POST", data: "", cache: false, url: "group_getOrgDetailById.action?ssdusergroupmain.keyId=" + data.parentKeyId, error: function(){ alert('加载数据出错...'); return false; }, success: function(data){ if (data != null && data.keyId != null) { parent.$("#parentid").val(data.keyId); parent.$("#parentname").val(data.groupName); } else { alert('没有找到群组信息'); return false; } } }); } else { alert('没有找到群组信息'); return false; } } }); } //--> </script> </head> <body style="background-color:transparent;"> <div style="width: 100%;height: 100%;padding: 3px 0px 0px 0px;"> <table align="center" width="100%" cellpadding="5" cellspacing="0" border="0" height="100%"> <tbody> <tr> <td width="40%" valign="top"><!-- 模块树 --> <div style="width: 100%;height: 100%;display:block;"> <script language="JavaScript" type="text/javascript"> document.write(myTree.toString()); document.close(); </script> </div> </td> </tr> </tbody> </table> </div> </body> </html>