JQuery zTree树特殊需求及解决方案

稿件来源: 阳光企业网站管理系统   撰稿作者: 太阳光   发表日期: 2013-09-15   阅读次数: 1131   查看权限: 游客查看

最近因公司使用到jquery ztree解决一个大数量的机构案例,做个记录供参考。

总需求:属于权限分配,以树形结构显示机构层级,勾选的机构表示拥有指定的权限,并能进行编辑。

技术需要:要求有联动选择与取消选择,如果子分部全部选择,只需要保存上级机构ID。

开始考虑到机构数比较多,有成千上万,而且后继还可能继续增加。所以初期用的是ajax形式多次加载树,但发现问题很多:

1、呈现效果不理想:假如起初在第三级下选择了一个机构,编辑时看到一级机构时全是没选择,也没有呈现半选择状态。直到ajax加载到第三级时,一级二级才突然出现半选状态。而且子节点子子节点无法出现选择效果,还没考虑以后再添加或者删除子节点情况。

2、编辑时丢失数据:假如开始选择了二级某个节点立刻保存,编辑时进入二级时再ajax第三级机构,二级机构就会因三级机构全部末选择而自动变成半选状态,又因半选状态机构是不会保存。

3、数据重叠:假如开始选择第三级某个节点,编辑时ajax到它的第二级父节点并选择,因无法判断它们是父子关系而保存了重叠节点。

4、取消操作无法还原数据:因为机构树是以弹窗选择的,弹出后可任意选择树,如果“确定”就显示对应选择的节点,如果“取消”后再弹出机构数无法取消这次选择的节点(这里操作全是前端操作,并没存入数据库,而树又是一次生成,又不可能从节点的点击事件去判断那些操作,太复杂了。)

……还有其他没考虑到的问题等,结果那一夜第一次加班直到晚上九点才回去

解决方案:一次加载所有机构数,查询过数据库所有机构暂时为四千左右,预计未来三年也不会超过万数。保存时不再从已经选择的节点中循环读取,而是从所有根节点中循环读子节点,直到判断本节点是全选状态。每次弹出树都先取消所有节点的选择。然后从已选值中判断哪些节点已经选择,然后循环所有子节点让其选择,并循环所有父节点让其呈现半选择状态。

<script type="text/javascript" src="../../js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="../../js/jquery.ztree.core-3.5.js"></script>
<script type="text/javascript" src="../../js/jquery.ztree.excheck-3.5.js"></script>
<link rel="stylesheet" href="../../css/zTreeStyle/zTreeStyle.css" type="text/css"/>
<SCRIPT type="text/javascript" >
   var setting = {
        check: {
            enable: true, //可选择状态
            chkboxType: { "Y" : "ps", "N" : "ps" }//选择取消时联动
        },
        data: {
            simpleData: {
                enable: true
            }
        }
    };
	var treeObj,//树对象
		tree_nodes,//所有树节点
		rootNodesArray=[],//树根节点集合
		getval={name:",",id:","};//已选择的节点名称与ID

	//打开树\确定\取消按钮函数
	function funTree(t){
		if(t=="open"){
			if(!tree_nodes){
				$.getJSON("json.asp",function(a){
					$.fn.zTree.init($("#tree"), setting,a);
					treeObj = $.fn.zTree.getZTreeObj("tree");
					//treeObj.expandAll(true);//打开所有节点
					tree_nodes = treeObj.transformToArray(treeObj.getNodes());//获取所有节点	
					reset_tree(true);
				});
			}else{
				treeObj.checkAllNodes(false);//取消所有节点选择
				reset_tree(false);
			}
		}else{
			if(t=="ok"){
				getval.id=getval.name=","
				for(var l=0;l<rootNodesArray.length;l++){
					get_checkNodeValue(rootNodesArray[l]);
					console.log(rootNodesArray[l]);
				}
				$("#id").val(getval.id);
				$("#name").val(getval.name);
			}
			$("#tree_div").hide();
		}
	}
	//重载树结构
	function reset_tree(root){
		for(var i=0;i<tree_nodes.length;i++){
			var node=tree_nodes[i];
			if(root&&node.parentTId==null){
				rootNodesArray.push(node);//获取所有根节点
			}
			if(getval.id.indexOf(","+node.id+",")!=-1){
				node.checked=true;
				node.halfCheck=false;
				node.check_Child_State=2;
				treeObj.updateNode(node);
				tree_checkAndUpdate(node,"s");//循环勾选子节点并更新
				tree_checkAndUpdate(node,"p");//循环半勾选父节点并更新
			}
		}
		treeObj.refresh();//刷新整个树
		$("#tree_div").show();//弹出树窗口
	}
	//循环勾选节点并更新函数
	function tree_checkAndUpdate(node,ps){
		if(ps=="s"){
			if(node.children){
				var c=node.children;
				for(var n=0;n<c.length;n++){
					c[n].checked=true;
					treeObj.updateNode(c[n]);
					tree_checkAndUpdate(c[n],ps);
				}
			}
		}else{
			var p=node.getParentNode();
			if(p){
				p.checked=true;
				p.check_Child_State=1;
				treeObj.updateNode(p);
				tree_checkAndUpdate(p,ps);
			}
		}
	}
	//循环读取已经选择的节点值
	function get_checkNodeValue(node){
		if(!node){
			return false;//不存在的节点
		}
		if(node.check_Child_State==1){
			var c=node.children;//如果部分子节点已选择就进入循环子节点
			for(var i=0;i<c.length;i++){
				get_checkNodeValue(c[i]);
			}
		}else if(node.checked){//本节点已经选择,赋值并终止循环
			getval.id  +=node.id+",";
			getval.name+=node.name+",";
		}
	}
  </SCRIPT>
<div>
	<p>选择树的名称:<input type="text" id="name" name="name" style="width:400px" /></p>
	<p>选择树的I D:<input type="text" id="id" name="id" style="width:400px" /></p>
	<button type="button" onclick="funTree('open')">打开树</button>
</div>
<div id="tree_div" style="display:none;border:1px solid #ddd;width:300px;">
	<ul id="tree" class="ztree" style="width:300px; overflow:auto;"></ul>
	<button type="button" onclick="funTree('ok')">确定</button>
	<button type="button" onclick="funTree('colse')">关闭</button>
</div>

演示效果:点击这里浏览

关键词: jquery,ztree,树形菜单   编辑时间: 2013-09-15 13:30:37

  • 感到高兴

    0

    高兴
  • 感到支持

    1

    支持
  • 感到搞笑

    0

    搞笑
  • 感到不解

    0

    不解
  • 感到谎言

    0

    谎言
  • 感到枪稿

    1

    枪稿
  • 感到震惊

    0

    震惊
  • 感到无奈

    0

    无奈
  • 感到无聊

    0

    无聊
  • 感到反对

    0

    反对
  • 感到愤怒

    0

    愤怒
100%(2)
0%(0)
共有0 条评论 发言请遵守【相关规定

网友评论

会员头像
发 表同步腾讯微博    验证码:  点击更新请先登陆
  • 暂无评论
关闭模块文章图片 article Pictrue
  • 我的妈妈爸爸
  • 基于koa2+mysql+vue2.0+Element阳光内容管理系统
  • 代码覆盖率工具 Istanbul 入门教程
  • 全栈工程师的武器——MEAN
  • 9款超炫的 CSS3 复选框(Checkbox)
  • 微信开发在线翻译功能
  • CSS3那些不为人知的高级属性
  • 给easyui的datebox添加清空事件
  • flash写字效果
  • kendoUI系列教程之DropDownList下拉菜单
  • kendoUI系列教程之datetimepicker日期时间选择
  • kendoUI系列教程之datepicker日期选择
  • kendoUI系列教程之combobox下拉列表框
  • kendoUI系列教程之colorpicker
  • kendoUI系列教程之calendar日历表
  • kendoUI系列教程之autocomplete自动补齐