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页面版,主要代码如下:
<div 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>
</div>
//后台将这棵树的信息封装到了${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>';
}
相应的样式都有了,我们也可以点击操作了,但是聪明的你应该已经发现,现在的页面循环出来的是同样的内容,我们如何出现差异化的内容呢?
- 拿下拉框举个例子,关键代码如下:
<div 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中加条件判断进行选择使用吧!