工作中用到分类选择树型下拉框,只允许单选叶子节点上的分类。如此需要使用把isParent=true的node的nocheck设置成true。
可以在ztree的jquery.ztree.core-3.5.js的appendNodes中增加一个回调函数接口setting.callback.afterInitNode:
appendNodes: function(setting, level, nodes, parentNode, initFlag, openFlag) { if (!nodes) return []; var html = [], childKey = setting.data.key.children; for (var i = 0, l = nodes.length; i < l; i++) { var node = nodes[i]; if (initFlag) { var tmpPNode = (parentNode) ? parentNode: data.getRoot(setting), tmpPChild = tmpPNode[childKey], isFirstNode = ((tmpPChild.length == nodes.length) && (i == 0)), isLastNode = (i == (nodes.length - 1)); data.initNode(setting, level, node, parentNode, isFirstNode, isLastNode, openFlag); //对渲染前的数据作最后的修正 setting.callback.afterInitNode&&setting.callback.afterInitNode(node); data.addNodeCache(setting, node); } var childHtml = []; if (node[childKey] && node[childKey].length > 0) { //make child html first, because checkType ……………
在data.initNode后树节点数据已经初始化结束,接下便是创建树节点dom。所以可以afterInitNode里完成nocheck的设置,对渲染前的数据作最后的修正。
// Add semicolon to prevent IIFE from being passed as argument to concatenated code. ; // UMD (Universal Module Definition) // see https://github.com/umdjs/umd/blob/master/returnExports.js (function (root, factory) { /* global define, exports, module */ if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(factory); } else if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like enviroments that support module.exports, // like Node. module.exports = factory(); } else { // Browser globals (root is window) root.TreeDropDown = factory(); } }(this, function () { /*** * <div style="position:relative"> * <input type="text"></input> * </div> */ var TreeDropDown=function(config){ this.treeId='treeDropDown'+TreeDropDown.count++; //说明文字 this.selectType='radio'; //radio|checkbox this.checkOnlyChild=true; this.$input={}; // this.$inputValue={}; this.desc='请选择'; //空值描述的文字 this.idField='id'; this.simpleData=true; this.parentIdField='pId'; this.isParent=function(record){return record.isParent===true}, this.nameField='name'; //tree节点名称字段 this.valueField='id'; //作为值的数据字段 this.name=''; //选中的名称 this.value=''; //选中的值 this.dataUrl=''; //tree的数据url this.treeData=[]; //tree的数据 this.onAfterSelectNode=function(name,value,treeNodes){}; $.extend(true,this,config); this.$parent=this.$input.parent(); this.init(); }; TreeDropDown.count=0; TreeDropDown.prototype={ render:function(){ //初始化input this.$input.css({ "background-image": "url('/resources/images/triangle-botton-16.png')", "background-repeat": "no-repeat", "background-position": "right", "background-color": "#fff", cursor: "pointer" }); this.$input.prop('readonly',true); this.$input.attr("placeholder",this.desc); //添加下拉框div this.$parent.append('<div class="dropDiv" style="position: absolute;display:none"><ul id="'+this.treeId+'" class="ztree dropTree"></ul></div>'); //树的容器 this.$treeDiv=$('.dropDiv',this.$parent); this.$tree=$('#'+this.treeId,this.$parent); this.$treeDiv.css({ width: this.$input.outerWidth(true)-2, padding:'5px 0', "z-index": 100, "background-color": '#fff', border: '1px solid #cccccc', "border-radius": '3px' }); //初始化树 this.initTree(); }, initTree:function(){ var that=this,treeSetting = { data : { simpleData : { enable : this.simpleData } }, check:{ chkStyle:this.selectType, radioType:"all", enable: true }, view : { selectedMulti : false }, callback: { //扩张的ztree事件:appendNodes的data.initNode之后 afterInitNode:function(treeNode){ if(that.checkOnlyChild) treeNode.nocheck=treeNode.isParent; }, onClick: function(event, treeId, treeNode){ if(treeNode.nocheck) return; if(!treeNode.checked) { that.ztreeObj.checkNode(treeNode,true); (that.selectType=='radio')&&that.showOrHide(); } else that.ztreeObj.checkNode(treeNode,false); that.afterSelectNode(that.ztreeObj.getCheckedNodes(true)); return false; } } }; if(this.simpleData) treeData=$.map(this.getTreeData(),function(ele){ return { id:ele[that.idField], name:ele[that.nameField]||'', pId:ele[that.parentIdField]||0, isParent:that.isParent(ele), nocheck:that.isParent(ele), _value:ele[that.valueField], data:ele }; }); else treeData=$.map(this.getTreeData(),this.translateData.bind(this)); this.ztreeObj = $.fn.zTree.init(this.$tree, treeSetting, treeData); this.ztreeObj.expandAll(true); }, translateData:function(data){ var res={ id:data[this.idField], name:data[this.nameField]||'', pId:data[this.parentIdField]||0, isParent:this.isParent(data), nocheck:this.isParent(data), _value:data[this.valueField], data:data }; if(data.children&&data.children.length>0) res.children=$.map(data.children,this.translateData.bind(this)); return res; }, afterSelectNode:function(treeNodes){ var nameField=this.nameField,valueField=this.valueField; if(treeNodes.length==0) { this.name=''; //选中的名称 this.value=''; //选中的值 } else if(treeNodes.length==1) { this.name=treeNodes[0].data[nameField]; //选中的名称 this.value=treeNodes[0].data[valueField]; //选中的值 } else { this.name=$.map(treeNodes,function(n){return n.data[nameField];}).join(','); this.value=$.map(treeNodes,function(n){return n.data[valueField];}).join(','); } this.$input.val(this.name); this.$inputValue.val(this.value); this.onAfterSelectNode&&this.onAfterSelectNode(this.name,this.value,treeNodes); }, setValue:function(value){ if(value==null) return; var that=this, treeNodes=$.map(value.split(','),function(v){ var treeNode=that.ztreeObj.getNodeByParam("_value",v); if(treeNode==null) return; that.ztreeObj.checkNode(treeNode, true, false); return treeNode; }); this.afterSelectNode(treeNodes); }, getTreeData:function(){ var res=this.treeData; if(this.dataUrl) $.ajax(this.dataUrl,{ type:'POST', dataType:'json', async:false }).done(function(data){ res=data; }).fail(function(){ }); return res; }, bind:function(){ var that=this; this.$input.on('click',function(){ that.showOrHide(); }); }, showOrHide:function(){ if(this.$treeDiv.css('display')=='block') this.$treeDiv.css('display','none'); else this.$treeDiv.css('display','block'); }, fillData:function(){ this.value!=null&&this.setValue(this.value); }, init:function(){ this.render(); this.bind(); this.fillData(); } }; return TreeDropDown; }));