dtree常见用法与变形。dTree是个很方便在页面生成树的 js 控件,使用简单。如果你已经大致了解了dtree的使用方法,相信你很容易在页面上显示一颗树来。但是不同的项目需求,造成菜单树的各种变化,因此在介绍dTree的同时,本文着重讲述如何改造dTree,以达到为不同项目所用的目的。
dtree使用方式:
①引入dtree.js : dtree功能脚本
②引入 dtree.css : 样式文件
③引入 img文件夹 : 存放dtree使用的图标
④d = new dTree( ‘d’ ) ; //创建树,名称为’d’(注意和树的对象变量名称要一致)
d.add ( 0 ,-1 ,‘My example tree’ ) ; //在树中增加节点。节点id是0,父节点是-1(根节点),节点文字’My example tree’
⑤最后将树生成到页面中即可。document.write(d);
注意:慧眼的你肯定已经发现这棵树就是用来展示的,我们可以看到每一层的层级关系,但是不能进行操作,而且这些数据都是写死的,当数据量大时不可能在页面上重复写d.add () ; 动态数据我们又该如何注入?
先来实现数据动态注入
jsp页面版,主要代码如下:
<p id="tree"> <script> d = new dTree("d","${ctx}/static/dtreebox/"); //${ctx}/static/dtreebox/为图片存储的路径 var mark = ''; <c:if test="${!empty wBaseInfos}"> <c:forEach items="${wBaseInfos}" var="tree"> var mark = ''; d.add("${tree.id}","${tree.fid}","${tree.cName}","","${tree .id}","","","","","",mark); </c:forEach> </c:if> document.write(d); </script> </p> //后台将这棵树的信息封装到了${wBaseInfos}对象中,这样这棵树就显示在了id为tree的标签元素内ajax请求获取动态数据版,关键代码如下:
function getBaseInfo(userId,productId,bxPlan){ $.post('/bg/qyLocalGrade/getBaseInfo',{userId:userId,productId:productId,bxPlan:bxPlan},function(data){ if(data==null||data==''){ $("#order_number_error").html("无城市信息!"); }else{ $('#tree').css('display','block'); d = new dTree("d","/static/dtreebox/"); var mark = ''; for(var i=0;i<data.wBaseInfos.length;i++){ if(i>0){ stateTree.push(data.wBaseInfos[i].localgrade.status); } var mark = ''; d.add(data.wBaseInfos[i].id,data.wBaseInfos[i].fid,data.wBaseInfos[i].cName,"",data.wBaseInfos[i].id,"","","","","",mark); } window.d=d; $("#tree").html(d.toString()); //以上两行代码是为了确保树可以放到id为tree的标签内展示 } });
数据已经动态注入,如果想在每一项前面加上单选按钮/复选按钮/下拉框如何实现?
含有复选框的树,查看源码可发现,页面是有字符串拼接而成,需要改变dtree.js中的代码,关键代码如下:1、config中需要配置check : true;
2、在dTree.prototype.node方法中拼接字符串,一般放在img拼接后; if(this.config.check==true){ str+= '<input type="checkbox" '+node.disabled+' '+node.defaultBox+' id="c'+ this.obj + nodeId + '" onclick="javascript:'+this.obj+'.cc('+nodeId+');javascript:'+this.obj+'.SetValue('+nodeId+');"/>'}含有单选框的树,需要改变dtree.js中的代码,关键代码如下:
1、config中需要配置useRadio: true,
2、在dTree.prototype.node方法中拼接字符串,一般放在img拼接后; if(this.config.useRadio && node.id != 436){ //node.id为根文件的id,一般不会对根文件进行操作,这个id值由后台传值 str +='<input type="radio" class="radioState" name="chk" id="r'+ this.obj + nodeId + '" value="'+node.id+'"/>'; }含有下拉框的树,需要改变dtree.js中的代码,关键代码如下:
1、在dTree.prototype.node方法中拼接字符串,下拉框一般要放在文字之后了,在else if ((!this.config.folderLinks || !node.url) && node._hc && node.pid != this.root.id)str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');" class="node">';str += node.name;if (node.url || ((!this.config.folderLinks || !node.url) && node._hc)) str += '</a>';代码之后就行; if(node.id != 436){ str+='<select name="selectNode" class="selectCheck input-small" ><option value="1">一级省</option><option value="2">二级省</option><option value="6">直辖市</option><option value="7">特级市</option><option value="3">一级市</option><option value="4">二级市</option><option value="5">三级市</option></select>'; }
相应的样式都有了,我们也可以点击操作了,但是聪明的你应该已经发现,现在的页面循环出来的是同样的内容,我们如何出现差异化的内容呢?
拿下拉框举个例子,关键代码如下:<p id="tree"> <script> d = new dTree("d","${ctx}/static/dtreebox/"); //${ctx}/static/dtreebox/为图片存储的路径 var mark = ''; var regionTree=[]; <c:if test="${!empty wBaseInfos}"> <c:forEach items="${wBaseInfos}" var="tree"> regionTree.push(${tree.localgrade.loclaGrade}); //这个为每一个下拉框需要展示的值 var mark = ''; d.add("${tree.id}","${tree.fid}","${tree.cName}","","${tree .id}","","","","","",mark); </c:forEach> </c:if> document.write(d); </script>
等到页面加载完成后,遍历所有下拉框,赋值为数组中的对应值
$(function(){ $('.selectCheck').each(function(index){ $(this).val(regionTree[index]); $(this).siblings('.oldSelect').val($(this).val()); }); });
做到这里的时候,感觉已经可以了,但是产品经理又提出来,当我下拉框值发生变化时,先提示用户是否要改变,改变的话调接口值改变,取消的话还为旧值,这时需要改动一下dtree.js中的代码了
if(node.id != 436){ str+='<input type="hidden" class="oldSelect" name="authorityId" value=""/><select name="selectNode" class="selectCheck input-small" onchange="saveSelect(this.value,'+node.id+',this)"><option value="1">一级省</option><option value="2">二级省</option><option value="6">直辖市</option><option value="7">特级市</option><option value="3">一级市</option><option value="4">二级市</option><option value="5">三级市</option></select>'; } 再在dtree.js加入对应的方法: function saveSelect(element,Id,that){ oldSelect=$(that).siblings('.oldSelect').val(); //这时就需要页面加载完成的时候将初始值赋给class为oldSelect的元素 var r=confirm("您确定要修改吗?"); if (r==true) { $.get('/bg/qyLocalGrade/update/'+Id+'/'+element,function(data){ if(data){ $(that).siblings('.oldSelect').val(element); alert('修改成功!'); }else{ $(that).val(oldSelect); alert('修改失败!'); } }); } else { $(that).val(oldSelect); return false; } }
终于搞定啦,从页面的制作到最后的数据交互都已ok,类似的功能差不多都能按照这种方式实现,大家可以进行尝试。
缺陷:想必大家也发现,实现了三种页面,我重写了3次dtree.js,这样dtree.js公用性就不高,那么大家就试着在dtree.js中加条件判断进行选择使用吧!