时间不稳定,写东西都是断断续续的,今天来的早,继续写昨天没写完的ztree,昨天还差一个callback没写,其实这个才是最重要的。废话不多说,开始。
callback
callback: { onClick : showInfo, onRightClick: showMenu, beforeRemove : isRemove, beforeRename : isRename, onRemove : remove, onRename : rename, beforeCheck : zTreeBeforeCheck, onCheck : zTreeOnCheck, },
onClick:用于捕获节点被点击的事件回调函数;如果设置了 setting.callback.beforeClick 方法,且返回 false,将无法触发 onClick 事件回调函数。默认值为null
/** * @param event * @param treeId * @param treeNode */ function showInfo(event, treeId, treeNode){ if(treeNode.type == "f"){// 无需统计叶子节点 return; } else if(treeNode.type == "m"){// 统计模块 addUpForModule(treeNode.id); } else if(treeNode.type == "s"){// 统计系统 addUpForSystem(treeNode.id); } showTable(requireCount); showChart(requireCount); }
注:event js event对象,treeId String类型,对应ztree的treeid,便于用户操作;treeNode JSON类型,被点击的节点的JSON数据对象,clickFlag number 节点被点击后的选中操作类型。
onRightClick:用于捕获 zTree 上鼠标右键点击之后的事件回调函数,默认值为null;
如果设置了 setting.callback.beforeRightClick 方法,且返回 false,将无法触发 onRightClick 事件回调函数。
只要将 function 的引用赋给 onRightClick 属性,则右键点击 zTree 时,将屏蔽浏览器的右键菜单。
/** * 右键菜单显示 * show the action menu while right click the node * @param event * @param treeId * @param treeNode */ function showMenu(event, treeId, treeNode){ currNode = treeNode; $("#rightClickMenu").css({ "top" : event.clientY + "px", "left" : event.clientX + "px", }).show(); }
参数和上面的onclick参数类似,不在解释了;唯一要说的就是treeNode,如果右键点击不在节点上,那么返回null;
beforeRemove:用于捕获节点被删除之前的事件回调函数,并且根据返回值确定是否允许删除操作,默认值为null;返回值为true/false,如果返回false,ztree将不删除节点,也无法触发onremove事件回调函数;
/** * action before remove a node * @returns {Boolean} */ function isRemove(treeId, treeNode){ if(confirm("要删除该节点吗? ")){ return true; } return false; }
beforeRename:用于捕获节点编辑名称结束(Input 失去焦点 或 按下 Enter 键)之后,更新节点名称数据之前的事件回调函数,并且根据返回值确定是否允许更改名称的操作;默认值为null.
/** * action before rename a node * @returns {Boolean} */ function isRename(treeId, treeNode, newName, isCancel){ if(isCancel){ return false; } if(confirm(" rename to " + newName)){ return true; } return false; }
注:newName为修改后的名称,isCancel boolean类型,是否取消操作,isCancel = true 表示取消编辑操作(按下 ESC 或 使用 cancelEditName 方法),isCancel = false 表示确认修改操作,回调函数的返回值为true/false。
如果返回 false,zTree 将保持名称编辑状态,无法触发 onRename 事件回调函数,并且会导致屏蔽其它事件,直到修改名称使得 beforeRename 返回 true
如果返回 false,不会让 input 输入框获取焦点,避免由于警告信息而导致反复触发 beforeRename。 请在关闭提示警告信息后,利用 editName 方法让 input 重新获取焦点。
beforeCheck:用于捕获 勾选 或 取消勾选 之前的事件回调函数,并且根据返回值确定是否允许 勾选 或 取消勾选,默认值:null;
/** * @param treeId * @param treeNode * @returns {Boolean} */ function zTreeBeforeCheck(treeId, treeNode) { return true; };
返回值是 true / false;如果返回 false,将不会改变勾选状态,并且无法触发 onCheck 事件回调函数;
onCheck:用于捕获 checkbox / radio 被勾选 或 取消勾选的事件回调函数,如果设置了 setting.callback.beforeCheck 方法,且返回 false,将无法触发 onCheck 事件回调函数。默认值:null
/** * @param event * @param treeId * @param treeNode */ function zTreeOnCheck(event, treeId, treeNode) { var datas = { ‘id‘ : treeNode.id, ‘type‘ : treeNode.type, ‘checked‘ : treeNode.checked }; $.ajax({ url : stateURL, data : datas, error : function(mes) { alert("请检查网络" + mes); } }); };
其实就是记录节点的选中状态,我这里是选中之后将结果记录在数据库了,所以有后台操作。treeNode是选中节点的JSON对象,因此可以使用treeNode拿到节点对应的值,传到后台进行修改。
后台代码:
private Integer id; private String type; private boolean checked; public String updateState(){ nodeService.updateTreeState(id, type, checked); this.reply("1"); return null; }
--------------------------------------华丽分割线------------------------------------------------------------------------------------------------------------------
上面的基本就是翻译了一下API,没什么卵用,下面其实也没什么用,但是做了这个功能就加上吧。什么呢,就是树的下面有一个一次加载全部的按钮,点击按钮,展示树的全部节点,下面上代码:
首先是页面:
<button id="btn_loadAll" class="btn btn-primary btn-sm"> 加载全部 <i class="glyphicon glyphicon-download"></i> </button>
JS事件:
$("#btn_loadAll").on(‘click‘, function(){ $.post(getAllUrl, { ‘pid‘ : 0 }, function(msg) { if (msg) { var nodeArr = eval("(" + msg + ")"); var len = nodeArr.length; for ( var i = 0; i < len; i++) { if(nodeArr[i].type != "f"){ nodeArr[i].open = true; } } $.fn.zTree.init($("#tree"), setting, nodeArr); } } ); });
后台代码:
public String getAll(){ Integer rid = SessionUtils.getCurrentRequireFromSession(request).getId(); List<SystemModule> list = nodeService.getWholeTree(rid); String json = new Gson().toJson(list); try { response.setContentType("text/plain"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); out.print(json); } catch (IOException e) { e.printStackTrace(); } return null; }
注:得说明一点,JS事件异步加载数据的时候传递了一个pid是0,但是在后台代码里面没有用到,但是却用到了另外一个获取到的pid,这个是有其他原因吧,大家看的时候就把id看成0就是了,当然你要查出来数据的话就需要在数据库里面把pid改成0。
具体的查询代码:
public List<SystemModule> getSystems(Integer pid) { List<SystemModule> allArr = new ArrayList<SystemModule>(); // get the system level List<SystemModule> list = getNodeChildren(pid); // get the module level for(SystemModule module : list){ allArr.add(module); if(!module.getType().equals("f")){ allArr.addAll(getSystems(module.getId())); } } return allArr; }
这里呢,用到了递归,虽然递归的效率不高,但是这里没有那么多数据,递归就递归吧,注意一下就是了。
--------------------------------------华丽分割线------------------------------------------------------------------------------------------------------------------
这次的总结暂时就这样吧,本来想多写点做的功能,但是JS代码太多,一直贴代码也不是事,以后写总结的时候还是得改变改变风格。