惯例,先上图:
这是在一个项目中,为了满足样式美观、多级菜单以及多选而将zTree插件更改过后的效果。
在实际的开发过程中,本来zTree也是可以满足需求的,但是zTree多选的话需要checkbox选择框,这样导致样式风格和项目总体不一致。下面是根据ztree所修改的内容。
如上图 这是个outlook样式的菜单。
我们只需要简单的右键,查看代码,就可以把源码拿下来看看。
我们需要的源码如下:
<SCRIPT type="text/javascript"> <!-- var curMenu = null, zTree_Menu = null; var setting = { view: { showLine: false, showIcon: false, selectedMulti: false, dblClickExpand: false, addDiyDom: addDiyDom }, data: { simpleData: { enable: true } }, callback: { beforeClick: beforeClick } }; //这里就是下拉列表的格式,通过id和pid控制所属的节点和级别 var zNodes =[ { id:1, pId:0, name:"文件夹", open:true}, { id:11, pId:1, name:"收件箱"}, { id:111, pId:11, name:"收件箱1"}, { id:112, pId:111, name:"收件箱2"}, { id:113, pId:112, name:"收件箱3"}, { id:114, pId:113, name:"收件箱4"}, { id:12, pId:1, name:"垃圾邮件"}, { id:13, pId:1, name:"草稿"}, { id:14, pId:1, name:"已发送邮件"}, { id:15, pId:1, name:"已删除邮件"}, { id:3, pId:0, name:"快速视图"}, { id:31, pId:3, name:"文档"}, { id:32, pId:3, name:"照片"} ]; function addDiyDom(treeId, treeNode) { var spaceWidth = 5; var switchObj = $("#" + treeNode.tId + "_switch"), icoObj = $("#" + treeNode.tId + "_ico"); switchObj.remove(); icoObj.before(switchObj); if (treeNode.level > 1) { var spaceStr = "<span style='display: inline-block;width:" + (spaceWidth * treeNode.level)+ "px'></span>"; switchObj.before(spaceStr); } } function beforeClick(treeId, treeNode) { if (treeNode.level == 0 ) { var zTree = $.fn.zTree.getZTreeObj("treeDemo"); zTree.expandNode(treeNode); return false; } return true; } $(document).ready(function(){ var treeObj = $("#treeDemo"); $.fn.zTree.init(treeObj, setting, zNodes); zTree_Menu = $.fn.zTree.getZTreeObj("treeDemo"); curMenu = zTree_Menu.getNodes()[0].children[0].children[0]; zTree_Menu.selectNode(curMenu); treeObj.hover(function () { if (!treeObj.hasClass("showIcon")) { treeObj.addClass("showIcon"); } }, function() { treeObj.removeClass("showIcon"); }); }); //--> </SCRIPT>
如上 这是我们需要的源码 但是有些并不需要,经过修改后如下:
var zNodes = []; //数据的格式已经在上一段代码中表示了 这里我就去掉了 //人员列表 $.ajax({ url:"searchPeopleJson", async:false, success: function(resultData){ var result= eval("("+resultData+")"); zNodes=result; //这是获取下拉列表的数据 因为我的是在数据库中获取的 } }); function listShow(divid,btnId,btnIndex) { var ulId=""; value=""; pIndex=""; selectCount=false; $("#"+btnId).attr("value", ""); $("#"+btnIndex).attr("value", ""); if(divid=="div1personTree1"){ ulId="personTree1"; }else if(divid=="div2personTree2"){ ulId="personTree2"; } var curMenu = null, zTree_Menu = null; var setting = { view: { showLine: false, showIcon: false, selectedMulti: true, dblClickExpand: true, addDiyDom: addDiyDom }, data: { simpleData: { enable: true } }, callback: { beforeClick: beforeClick } }; function addDiyDom(treeId, treeNode) { var spaceWidth = 5; var switchObj = $("#" + treeNode.tId + "_switch"), icoObj = $("#" + treeNode.tId + "_ico"); switchObj.remove(); icoObj.before(switchObj); if (treeNode.level > 1) { var spaceStr = "<span style='display: inline-block;width:" + (spaceWidth * treeNode.level) + "px'></span>"; switchObj.before(spaceStr); } } function beforeClick(treeId, treeNode) { if (treeNode.isParent) { var zTree = $.fn.zTree.getZTreeObj(ulId); zTree.expandNode(treeNode); return false; } return true; } $(document).ready(function () { var treeObj = $("#"+ulId); $.fn.zTree.init(treeObj, setting, zNodes); zTree_Menu = $.fn.zTree.getZTreeObj(ulId); //curMenu = zTree_Menu.getNodes()[0].children[0].children[0]; // zTree_Menu.selectNode(curMenu); treeObj.addClass("showIcon"); }); /* if($("#"+btnId).attr("readonly")=="readonly"){ return false; } */ //$("#"+divid).css("display", "block"); showMenu(divid,btnId); return false; } function showMenu(divid,btnId) { var cityObj = $("#"+btnId); var cityOffset = $("#"+btnId).offset(); $("#"+divid).css("display", "block").slideDown("fast"); $("body").bind("mousedown",{btnId:btnId,divid:divid}, onBodyDown); } function hideMenu(divid,btnId) { $("#"+divid).fadeOut("fast"); $("body").unbind("mousedown", onBodyDown); } function onBodyDown(event) { if (!(event.target.id == event.data.btnId || event.target.id == event.data.divid || $(event.target).parents("#"+event.data.divid).length>0)) { hideMenu(event.data.divid,event.data.btnId); } }
这是我根据项目实际情况而更改的 我们将原来的鼠标浮动到上面之后显示图标给改成一直显示 然后将除第一级以外的菜单需要点击图标才能展开和关闭改成点击标题就可以展开和关闭了 方便用户的操作。 下面的三个方法是用来显示和隐藏下拉列表的,当文本框失去焦点的时候触发。
我们的html代码如下:
<label for="txtChargePersonS" class="col-sm-2 control-label">第二负责人</label> <div id="cyPersonDiv" class="col-sm-4"> <input type="hidden" id="txtHiddenSPerson" name="tpj.cyLeader" /> <input id="txtChargePersonS" readonly personIndex="0" onfocus="listShow('div2personTree2','txtChargePersonS','txtHiddenSPerson');" type="text" class="form-control zTreeDemoBackground" placeholder="第二负责人"> <div id="div2personTree2" style="display:none;z-index:1000; position:absolute; " name="province" type="selectbox" class="zTreeDemoBackground"> <ul id="personTree2" style=" height:175px;" class="ztree"></ul> </div> </div>
因为我的项目里面多处用到这个下拉菜单,因此我通过参数传递的方式将id传递到方法内部。
如此,我们就可以通过点击文本框显示下拉列表 当文本框失去焦点之后隐藏下拉列表。
那么数据有了 显示没问题了 怎么才能让下拉列表在点击的时候将点击的值放到文本框中呢?
我们在使用zTree的时候需要下载ztree的几个js文件,我们可以在jquery.ztree.core-3.5.js中去实现。
在jquery.ztree.core-3.5.js中有个_setting的初始化代码,显示属性的初始化还有事件的初始化等等,如下图:
这是下拉列表的点击事件,我们写上自己的事件。
请看下面的代码:
var value=""; //文本框中显示的值 例:张三,李四,王五 var pIndex=""; //选择值得id 例:1,2,3 var selectCount=false; //表示是否为第一次选择 用于清除拼接的逗号 function OnListClick(event, treeId, treeNode, clickFlag) { if (treeNode.isParent) { return; } value+=","+treeNode.name; pIndex+=","+treeNode.id; if(selectCount==false){ //这里清除第一个逗号 value=value.substr(1,value.length); pIndex=pIndex.substr(1,pIndex.length); selectCount=true; } var valueObj=""; var pIndexObj=""; if(treeId=="personTree1"){ $("#div1personTree1").css("display","none"); $("#txtChargePerson").attr("value", treeNode.name); $("#txtHiddenPerson").attr("value", treeNode.id); }else if(treeId=="personTree2"){ valueObj=$("#txtChargePersonS"); pIndexObj=$("#txtHiddenSPerson"); valueObj.attr("value", value); //选择多项的时候拼接的值 pIndexObj.attr("value",pIndex);//选择多项的时候拼接的id }else if(treeId=="personTree3"){ $("#div3personTree3").css("display","none"); $("#txtChargePersonItem").attr("value", treeNode.name); $("#txtHiddenCPerson").attr("value", treeNode.id); }else if(treeId=="personTree4"){ valueObj=$("#txtExaminePerson"); pIndexObj=$("#txtHiddenEPerson"); valueObj.attr("value", value); pIndexObj.attr("value",pIndex); }else if(treeId=="personTree5"){ valueObj=$("#txtDesignPerson"); pIndexObj=$("#txtHiddenDPerson"); valueObj.attr("value", value); pIndexObj.attr("value",pIndex); } }
如上代码 因为我的是多个地方使用 所有if else 弄了多个 需要的话 参照其中一个就可以了
修改就是这么简单,如果有更好的方案欢迎分享和讨论。
技术交流群:94234450
不管你遇到了什么问题,我们绝不会让你独自去面对!