使用 zTree 右键菜单功能的总结
一: 首先什么是zTree?
zTree 是一个依靠 jQuery 实现的多功能 “树插件”。优异的性能、灵活的配置、多种功能的组合是 zTree 最大优点。专门适合项目开发,尤其是 树状菜单、树状数据的Web显示、权限管理等等。
二:zTree的优点是什么?
1. zTree v3.0 将核心代码按照功能进行了分割,不需要的代码可以不用加载.
2. 采用了延迟加载技术,上万节点轻松加载,即使在 IE6 下也能基本做到秒杀。
3. 兼容 IE、FireFox、Chrome、Opera、Safari 等浏览器。
4. 支持 JSON 数据。
5. 支持静态和 Ajax 异步加载节点数据。
6. 支持任意更换皮肤 / 自定义图标(依靠css)。
7. 支持极其灵活的 checkbox 或 radio 选择功能。
8. 提供多种事件响应回调,灵活的编辑(增/删/改/查)功能,可随意拖拽节点,还可以多节点拖拽哟。
要想更多的了解zTree 请阅读官方API http://www.ztree.me/v3/main.php 嘿嘿!!
前言: 最近在zuo"置业管理平台"项目,其中遇到最困难的问题是:zTree右键菜单功能的实现。因为以前也没有涉及过这样的 所以说实话有点鸭梨啊 折腾了很久啊! 先看下如下图:
我具体的需求是:
1. 我右键菜单的时候 增加一个没有目录名称的 空节点 -----> 分2种情况 第一:此节点有没有父节点 一般没有父节点 父节点都为null 第二: 如果有父节点的话 那么在右侧的 父目录 显示是那个父目录下的父节点名称。
2. 在左侧只能新建一项空菜单, 不能接着新建第二项 第三项 因为如果可以新建第二项 第三项的话 然后我在右侧填好后 点击保存按钮 开发分不清那个是那个,所以我们前端需要控制只能新建一项 当点击保存按钮后 左侧没有空菜单项时候 接着可以新建第二项或第二子项。
3. 当我点击左侧已新建的项时或者点击左侧已有项时 右侧渲染相应的数据。如下图所示:
4. 每次新建一项时候 判断有没有父节点 如有的话 把父节点ID传给开发(发请求),当然参数要传入有如下四个:1.自身ID,2. 父节点ID,3.当前目录的id 是在哪个目录下的 如上图所示 是在开发类型下的,4. 是什么模式 默认情况分2种(创建:create 还是 修改:update). 当时创建的时候 自身ID肯定是没有的 是undefined,最纠结的是 每次新建一项时候 父节点ID我拿不到 纠结 纳闷就在这里。
具体的做法暂时先不讲,待会讲,首先让我们来认识下 zTree的基本功能 基本创建节点的方法。首先我们可以先做个demo 比如我想静态实现如下图demo:
父节点可以展开或者收缩 有子节点或者没有子节点,首先我们可以在页面上需要 引入:jquery1.9.1.js ztree.core.js ztree.css等
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link rel="stylesheet" href="http://www.ztree.me/v3/css/demo.css"/>
<link rel="stylesheet" href="http://www.ztree.me/v3/css/zTreeStyle/zTreeStyle.css"/>
<script src="http://www.ztree.me/v3/js/jquery.ztree.core-3.5.js?2013031101"></script>
然后需要在页面上有存放树节点的容器 我们可以如下HTML代码:
<div class="zTreeDemoBackground left">
<ul id="treeDemo" class="ztree"></ul>
</div>
接着就是我们用js对树初始化了。如下:
var setting = {};
var zNodes =[
{ name:"父节点1 - 展开", open:true,
children: [
{ name:"父节点11 - 折叠",
children: [
{ name:"叶子节点111"},
{ name:"叶子节点112"},
{ name:"叶子节点113"},
{ name:"叶子节点114"}
]},
{ name:"父节点12 - 没有子节点", isParent:true}
]},
{ name:"父节点2 - 折叠",
children: [
{ name:"父节点21 - 展开", open:true,
children: [
{ name:"叶子节点211"},
{ name:"叶子节点212"},
{ name:"叶子节点213"},
{ name:"叶子节点214"}
]}
]},
{ name:"父节点3 - 没有子节点", isParent:true} ]; $(document).ready(function(){
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
});
首先 setting对象 是提供默认配置项 不太清楚的 可以看下 API http://www.ztree.me/v3/api.php 特别是提供了丰富的回调函数等。zNodes格式 是我们希望开发 能输出这样的格式出来 然后我们可以直接调用这句 加载出来 $.fn.zTree.init($("#treeDemo"), setting, zNodes); 如果想要某一项以文件夹显示 那么设置isParent:true就可以 否则的话是以子节点文件 表现的。上面的只是静态的加载数据 不是动态的加载。这样有缺点,比如页面上有很多的节点话 那么输出一大串出来 然后js分别渲染进去 相对来说 前端性能变差了。但是我们也可以动态的去加载 也就是说 我们可以默认展开第二项父节点,当我们每次去点击某一项父节点时候 如果有子节点的话 那么去加载对应父节点下的子节点,这样相对来说 性能提高了 不必全部加载出来。那么动态的加载 我们只需要开发那边只提供输出这样如下格式:
[{ id:'011', name:'n1.n1', isParent:true},{ id:'012', name:'n1.n2', isParent:false},{ id:'013', name
:'n1.n3', isParent:true},{ id:'014', name:'n1.n4', isParent:false}]。切记:一定是这种格式,不能像这样输出
{count:[
{ id:'011',name:'n1.n1',isParent:true},
{ id:'012', name:'n1.n2', isParent:false},
{ id:'013', name:'n1.n3', isParent:true},
{ id:'014', name:'n1.n4', isParent:false}]
}
然后就想获取count 就以为可以拿到数据。据我所知,这样输出貌似不行的。动态JS初始化可以如下操作就ok了!
var setting = {
async: {
enable: true,
url:"../asyncData/getNodes.php",
autoParam:["id", "name=n", "level=lv"]
}
};
$(document).ready(function(){
$.fn.zTree.init($("#treeDemo"), setting);
});
首先 他是异步的 所以配置项 async enable: true 表示异步 false表示关闭异步加载模式。url 是我们要请求url
注意:不需要我们另外发ajax请求 只要上面这种写法就ok了 当我们一点击一项时候 代码内部已经帮我们做了点击事件了 发ajax请求了 所以我们只要这种配置就ok了! 好了 我们已经熟悉了下基本的zTree了 要想了解更多的信息 可以去官网看API 再结合自己的需求去折腾 研究了 API: http://www.ztree.me/v3/api.php 下面还是回到我刚刚上面的需求上来看看了,嘿嘿! 首先我要说的是:页面一加载时候 我也是静态的加载数据 因为开发据说用的是框架 也无法给到我动态数据那种格式,所以只能开发输出静态数据出来 然后进行初始化。 一: 右键菜单,如下图:
我这边需求有三项 分别是: 作废子目录 增加子目录 刷新子目录。先来看看 增加子目录项,首先我们得在配置里面有个回调函数:如下:
var setting = {
data : {
simpleData : {
enable : true
},
keep: {
parent: true
/*如果设置为 true,则所有 isParent = true 的节点,即使该节点的子节点被全部删除或移走,依旧保持父节点状态 */
}
},
callback : {
onRightClick : OnRightClick,
onClick : zTreeOnClick
}
};
当我们右键下时候 执行OnRightClick 函数:函数如下:
function OnRightClick(event, treeId, treeNode) { if(treeNode == null) {
var a = 1; // 什么都不做
}else if(treeNode && treeNode.name) {
curName = treeNode.name;
}else {
curName = undefined;
}
if (!treeNode && event.target.tagName.toLowerCase() != "button"
&& $(event.target).parents("a").length == 0) {
zTree.cancelSelectedNode();
$("#idCipherText").val("");
showRMenu("root", event.clientX, event.clientY);
} else if (treeNode && !treeNode.noR) {
zTree.selectNode(treeNode); if(treeNode.id) {
$("#idCipherText").val(treeNode.id);
}
showRMenu("node", event.clientX, event.clientY);
}
$("#typeIdCipherText").val($("#docType").attr("value"));
}
首先 右键回调函数 返回三个参数:event 事件 treeId 最外层容器元素ID treeNode 树节点 返回的是一个对象 如下图:
由于 是顶级的 没有pId 所以pId肯定是null或者undefined 接着代码里面做了一个判断curName 右键返回对象的 如果有name的话 那么保存到全局对象 否则 undefined 是为了下文后续操作 还有这句代码
if(treeNode.id) {
$("#idCipherText").val(treeNode.id);
} 如果有id的话 那么把他们放入form表单隐藏域去,如下:
为了开发提交,
下面我们来看这句代码 :
var newNode = {
name:"",
isParent : true,
checked : true,
elemNode: undefined
};
每次新建一个新节点时候 默认情况下 我都让他为空:如下图:
代码如下:
function addTreeNode() {
hideRMenu();
var parentId;
var selectedNodes = zTree.getSelectedNodes()[0]; if (selectedNodes) {
if(newNode.name == '') {
_publicFun(selectedNodes,newNode);
}else {
$('#parentDirName').html("");
}
} else {
if(newNode.name == '') {
_publicFun(selectedNodes,newNode);
} }
var select = $("#docType")[0],
selectVal = getSelectValue(select); var selectId = zTree.getSelectedNodes(); if(isBoolean) {
if(selectedNodes && selectedNodes.id) {
parentId = selectedNodes.id;
}
getDir(undefined,parentId,selectVal,'create');
isBoolean = false;
}
zTreeArrs = [];
}
/**
* 处理基本操作
*/
function _publicFun(selectedNodes,newNode) {
var curNode = zTree.addNodes(selectedNodes, newNode),
parentNode = $('#' + curNode[0].tId);
$('a').hasClass("curSelectedNode") && $('a').removeClass("curSelectedNode");
!$('a',parentNode).hasClass("curSelectedNode") && $('a',parentNode).addClass("curSelectedNode");
var afirst = $('a',parentNode).first();
newNode.elemNode = $('span',afirst).last();
newNode.name = 'temp';
}
每次创建一个空节点 然后进行初始化 zTree.addNodes(selectedNodes, newNode),那么页面初始化时空节点菜单,之后给name赋值为临时 temp 目的是希望用户不要老是新建空项 只能新建一项空菜单项 所以在 addTreeNode 函数里面用了 if(newNode.name == '') {}这个判断语句 当我点击保存按钮后 后台给我返回了name的话 然后我就动态的给左侧空菜单赋值操作 接着 又让newNode对象里面的name = "" 所以左侧菜单又可以新建一项了:
newNode = {
id: idCipherText,
pId: parentIdCipherText,
name:"",
isParent : true,
checked : true,
elemNode: undefined
};
接着 假如我想修改左侧菜单项名称 怎么办?首先我们可以先点击左侧菜单某一项:如下图:
代码如下:
// 修改一项名称 当我点击左侧树形菜单后 再修改name(树名称)后 值覆盖
function removeItemId (id,arrs) {
for(var i = 0, ilen = arrs.length; i < ilen; i+=1) {
if(id == arrs[i].id) {
return arrs.splice(i,1);
}
}
}
if(treeNodeArrs.id == idCipherText) {
removeItemId(idCipherText,zNodes); }else {
/**
* 点击保存后 由于左侧树目录要重新初始化下 我不知道哪个选中了 所以 右边的内容清空掉
*/
$("#loadData").load("/rocky/document/directory/directoryEditView.vm?timestate="+(new Date()).getTime());
}
最后让我们来分析下 我最纠结的问题是: 我每次右键菜单时候 我怎么样能获取父节点ID,首先我做了这么样的一个操作 当我们每次新建的时候 然后保存 我都让她们后台返回的当前id 父元素id name 放入原来数组里去 :
zNodes.push({
id: idCipherText,
pId: parentIdCipherText,
name:name,
isParent : true,
});
然后重新初始化下 : $.fn.zTree.init($("#directoryTree"), setting, zNodes); 这样树形菜单会刷新下,但是不会展开 所以接着分析用到了zTree的一个属性 expandNode 让他重新展开 代码如下:
//展开树
var url = "/rocky/document/documentDirectory/getRootId.json";
var cond = "dirCipherText=" + idCipherText; common.f.commonAjaxGet(url, cond, function(data) {
if(data && data.content) {
var node = treeObj.getNodeByParam("id", data.content, null);
if(node){
treeObj.expandNode(node, true, true, false);
}
}
},false);
但是这样做有一个缺点是 当我们展开了很多项的子项时候 我们点击保存后 只能使当前的项及所有子项展开 其他项没有展开。目前我只能想到这个方法了 如果大家有其他好方法可以分享下。通过上面的操作 当我们一增加一个节点addTreeNode时候 我们就可以拿到当前增加项 父节点id了
if(selectedNodes && selectedNodes.id) {
parentId = selectedNodes.id;
}
所有代码如下:
var setting = {
/**view : {
dblClickExpand : false
},**/
data : {
simpleData : {
enable : true
},
keep: {
parent: true
}
},
callback : {
onRightClick : OnRightClick,
onClick : zTreeOnClick
}
}; var zNodes = $.parseJSON($("#hiddenTree").val()),
zTreeArrs = [],
/*zTreeArrs2 = [],*/
zTreeObj = [],
tempVal,
treeNodeArrs = []; function OnRightClick(event, treeId, treeNode) { if(treeNode == null) {
var a = 1; // 什么都不做
}else if(treeNode && treeNode.name) {
curName = treeNode.name;
}else {
curName = undefined;
}
if (!treeNode && event.target.tagName.toLowerCase() != "button"
&& $(event.target).parents("a").length == 0) {
zTree.cancelSelectedNode();
$("#idCipherText").val("");
showRMenu("root", event.clientX, event.clientY);
} else if (treeNode && !treeNode.noR) {
zTree.selectNode(treeNode); if(treeNode.id) {
$("#idCipherText").val(treeNode.id);
}
showRMenu("node", event.clientX, event.clientY);
}
$("#typeIdCipherText").val($("#docType").attr("value"));
}
function showRMenu(type, x, y) {
$("#rMenu ul").show();
if (type == "root") {
$("#m_del").hide();
$("#m_check").hide();
$("#m_unCheck").hide();
} else {
$("#m_del").show();
$("#m_check").show();
$("#m_unCheck").show();
}
rMenu.css({
"top" : y + "px",
"left" : x + "px",
"visibility" : "visible"
}); $("body").bind("mousedown", onBodyMouseDown);
}
function hideRMenu() {
if (rMenu)
rMenu.css({
"visibility" : "hidden"
});
$("body").unbind("mousedown", onBodyMouseDown);
}
function onBodyMouseDown(event) {
if (!(event.target.id == "rMenu" || $(event.target).parents("#rMenu").length > 0)) {
rMenu.css({
"visibility" : "hidden"
});
}
}
var newNode = {
name:"",
isParent : true,
checked : true,
elemNode: undefined
};
var obj = undefined;
var isBoolean = true;
function getDir(dirId,pId,catalogId,mode) {
if(dirId == undefined) {
dirId = "";
} if(pId == undefined) {
pId = '';
}
$("#loadData").load(
"/rocky/document/directory/directoryEditView.vm?docDirIdCipher="
+ dirId+"&parentIdCipher="+pId+"×tate="+(new Date()).getTime(),function(data){
// form表单keyup时候 判断必填项是否为空
formKeyUp();
$('.btns').unbind('click');
$('.btns').bind('click',function(){
//表单验证 如果为空的话 不发请求
var code = $.trim($('#code').val()),
name = $.trim($('#name').val());
if(code == '') {
$('#errorCode').hasClass('hidden') && $('#errorCode').removeClass('hidden');
$("#errorCode").html("必选字段");
return;
}
if(name == ''){
$('#errorName').hasClass('hidden') && $('#errorName').removeClass('hidden');
$('#errorName').html('必选字段');
return;
} if(code.length > 100) {
return;
}
if(name.length > 100) {
return;
}
_request(dirId,pId,catalogId,mode);
});
});
} function zTreeOnClick(event, treeId, treeNode) {
treeNodeArrs = treeNode;
var lists = $('#' + treeId + " li");
$.each(lists,function(i,item) {
$('a',item).hasClass("curSelectedNode") && $('a',item).removeClass('curSelectedNode');
});
var treeName = $(event.target).html();
var curElem = $('#' + treeNode.tId);
!$('a',curElem).first().hasClass("curSelectedNode") && $('a',curElem).first().addClass("curSelectedNode");
//var pId = treeNode.pId;
var pId = treeNode.pId;
if(pId == null) {
pId = '';
} if(newNode.id == undefined) {
// 页面一渲染后 页面一有的数据点击 执行下面操作
getDir(treeNode.id,pId,zTreeArrs[2],'update');
}else if(newNode.id != undefined && treeNode.name != '') {
getDir(treeNode.id,pId,zTreeArrs[2],'update');
}else {
var index = currentIndex(treeName,zTreeObj);
if(index > -1 && zTreeObj.length > 1) {
var idCipherText = zTreeObj[index].idCipherText,
parentIdCipherText = zTreeObj[index].parentIdCipherText;
// 新建一项后 再新建第二项 接着点击第二项时候 执行下面操作
getDir(idCipherText,parentIdCipherText,zTreeArrs[2],'update');
}else { // 当新建一项时候 执行下面的操作
getDir(newNode.id,newNode.pId,zTreeArrs[2],'update');
} } zTreeArrs = []; }; function addTreeNode() {
hideRMenu();
var parentId;
var selectedNodes = zTree.getSelectedNodes()[0]; if (selectedNodes) {
if(newNode.name == '') {
_publicFun(selectedNodes,newNode);
}else {
$('#parentDirName').html("");
}
} else {
if(newNode.name == '') {
_publicFun(selectedNodes,newNode);
} }
var select = $("#docType")[0],
selectVal = getSelectValue(select); var selectId = zTree.getSelectedNodes(); if(isBoolean) {
if(selectedNodes && selectedNodes.id) {
parentId = selectedNodes.id;
}
getDir(undefined,parentId,selectVal,'create');
isBoolean = false;
}
zTreeArrs = [];
}
/**
* 处理基本操作
*/
function _publicFun(selectedNodes,newNode) {
var curNode = zTree.addNodes(selectedNodes, newNode),
parentNode = $('#' + curNode[0].tId);
$('a').hasClass("curSelectedNode") && $('a').removeClass("curSelectedNode");
!$('a',parentNode).hasClass("curSelectedNode") && $('a',parentNode).addClass("curSelectedNode");
var afirst = $('a',parentNode).first();
newNode.elemNode = $('span',afirst).last();
newNode.name = 'temp';
}
/**
* ajax请求
*/
function _request(dirId,pId,catalogId,mode) {
var select = $("#docType")[0],
selectVal = getSelectValue(select);
if( $("#idCipherText").attr("value")!= undefined && $("#idCipherText").attr("value")!=""){
mode='update';
dirId = $("#idCipherText").attr("value");
pId = $("#parentIdCipherText").attr("value");
}
$("input[name='mode']").attr("value",mode);
$("#idCipherText").attr("value",dirId);
$("#typeIdCipherText").attr('value',selectVal);
$("#parentIdCipherText").attr("value",pId);
$.ajax({
type:'post',
data: $("#directory").serialize(),
url: '/rocky/document/documentDirectory/createDorDir.json?timestate='+(new Date()).getTime(),
success: function(data){ if(data.content) {
var name = data.content.name,
idCipherText = data.content.idCipherText,
parentIdCipherText = data.content.parentIdCipherText,
typeIdCipherText = data.content.typeIdCipherText; $(newNode.elemNode).html(name); $("#idCipherText").attr("value",idCipherText);
$("#parentIdCipherText").attr("value",parentIdCipherText);
zTreeArrs = [];
zTreeArrs.push(idCipherText,parentIdCipherText,typeIdCipherText);
zTreeObj.push({name:data.content.name,idCipherText:data.content.idCipherText,parentIdCipherText:data.content.parentIdCipherText});
isBoolean = true;
newNode = {
id: idCipherText,
pId: parentIdCipherText,
name:"",
isParent : true,
checked : true,
elemNode: undefined
};
zNodes.push({
id: idCipherText,
pId: parentIdCipherText,
name:name,
isParent : true,
}); // 修改一项名称 当我点击左侧树形菜单后 再修改name(树名称)后 值覆盖
function removeItemId (id,arrs) {
for(var i = 0, ilen = arrs.length; i < ilen; i+=1) {
if(id == arrs[i].id) {
return arrs.splice(i,1);
}
}
}
if(treeNodeArrs.id == idCipherText) {
removeItemId(idCipherText,zNodes); }else {
/**
* 点击保存后 由于左侧树目录要重新初始化下 我不知道哪个选中了 所以 右边的内容清空掉
*/
$("#loadData").load("/rocky/document/directory/directoryEditView.vm?timestate="+(new Date()).getTime());
}
$.fn.zTree.init($("#directoryTree"), setting, zNodes);
var treeObj = $.fn.zTree.getZTreeObj("directoryTree");
//展开树
var url = "/rocky/document/documentDirectory/getRootId.json";
var cond = "dirCipherText=" + idCipherText; common.f.commonAjaxGet(url, cond, function(data) {
if(data && data.content) {
var node = treeObj.getNodeByParam("id", data.content, null);
if(node){
treeObj.expandNode(node, true, true, false);
}
}
},false); if(dirId){
$.jBox.success("修改成功", "修改确认", {
timeout : 3000,
height : 120
});
} else{
$.jBox.success("保存成功", "保存确认", {
timeout : 3000,
height : 120
});
}
}else {
$.jBox.error("目录类别代码重复", "确认", {
timeout : 3000,
height : 120
});
} //console.log(newNode);
}
});
}
/**
* 获取下拉框selelct 选中的值
*/
function getSelectValue(select) {
var idx = select.selectedIndex, //获取选中的option的索引
option,
value;
if(idx > -1) {
option = select.options[idx]; //获取选中的option元素
value = option.attributes.value;
return (value && value.specified) ? option.value : option.text;
}
return null;
};
function removeTreeNode() {
hideRMenu(); var nodes = zTree.getSelectedNodes();
if (nodes && nodes.length > 0) {
//if(nodes[0].children && nodes[0].children.length > 0) {
var id = nodes[0].id;
var url = "/rocky/document/documentDirectory/deleteDocDir.json";
var cond = "dirCipherText=" + id + "&typeIdCipherText=" + $("#typeIdCipherText").val();
common.f.ajaxPost(url,cond,function(data){
var results = data.content;
if(results=="success") {
zTree.removeNode(nodes[0]);
$("#loadData").load("/rocky/document/directory/directoryEditView.vm?timestate="+(new Date()).getTime());
$.jBox.success("删除成功", "确定",{timeout: 2000, height: 120});
} else if(results=="the_doc_dir_had_deleted") {
$.jBox.error("该目录已经被删除!", "确定",{timeout: 2000, height: 120});
$("#loadData").load("/rocky/document/directory/directoryEditView.vm?timestate="+(new Date()).getTime());
}
else if(results=="has_sub_doc_dir") {
$.jBox.error("该目录含有子目录,不能删除!", "确定",{timeout: 2000, height: 120});
} else if(results == "doc_dir_assoataion_others"){
$.jBox.error("该目录含有文档不能删除!", "确定",{timeout: 2000, height: 120});
} else if(results=="db_error") {
$.jBox.error("该目录含有文档不能删除!", "确定",{timeout: 2000, height: 120}); }
});
//} }
newNode = {
name:"",
isParent : true,
checked : true
};
}
function checkTreeNode(checked) {
var nodes = zTree.getSelectedNodes();
if (nodes && nodes.length > 0) {
zTree.checkNode(nodes[0], checked, true); }
hideRMenu();
}
/**
* 从数组里面删除一项对象 [{ id="d04ec6de791520f4d51ca1cdbc7c7c3c", name="1234", isParent=true},{},{}] 等等
* @param {name} 根据name 来删除
* @return [] 返回新的数组
*/
function removeItem(name,arrs) {
arrs = arrs || [];
var index = currentIndex(name,arrs);
if(index > -1) {
return arrs.splice(1,index);
}else {
return [];
}
}
/**
* 从数组获取当前的索引index
* @param {name arrs}
* return {index} 索引
*/
function currentIndex(name,arrs) {
if(arrs.length > 0) {
for(var j = 0, jlen = arrs.length; j < jlen; j+=1) {
var curName = arrs[j].name;
if(name == curName) {
return j;
}
}
return -1;
} }
function resetTree() {
hideRMenu();
/**newNode = {
name:"",
isParent : true,
checked : true,
elemNode: undefined
};**/
// 重新加载
$("#loadData").load("/rocky/document/directory/directoryEditView.vm?timestate="+(new Date()).getTime());
var url = "/rocky/document/documentDirectory/getDocDirTreesByTypeId.json",
select = $("#docType")[0],
selectVal = getSelectValue(select);
var cond = "dirCipherText=" + selectVal; common.f.commonAjaxGet(url, cond, function(data) {
hideRMenu();
if(data && !data.hasError) {
zNodes = $.parseJSON(data.content);
$.fn.zTree.init($("#directoryTree"), setting, zNodes);
}
});
/**
$.fn.zTree.init($("#directoryTree"), setting, zNodes);
**/ } var zTree, rMenu; $(document).ready(function() {
$("#m_add").unbind('click');
$("#m_add").bind('click',function(){
addTreeNode();
});
$.fn.zTree.init($("#directoryTree"), setting, zNodes);
zTree = $.fn.zTree.getZTreeObj("directoryTree");
rMenu = $("#rMenu");
// docType change event
$("#docType").prev().delegate("a", "click", function() { // newNode 新建的节点(没有数据情况下)清空掉
newNode = {
name:"",
isParent : true,
checked : true,
elemNode: undefined
};
// 重新加载
$("#loadData").load("/rocky/document/directory/directoryEditView.vm?timestate="+(new Date()).getTime()); var url = "/rocky/document/documentDirectory/getDocDirTreesByTypeId.json";
var cond = "dirCipherText=" + $(this).attr("value");;
common.f.commonAjaxGet(url, cond, function(data) {
hideRMenu();
if(data && !data.hasError) {
zNodes = $.parseJSON(data.content);
$.fn.zTree.init($("#directoryTree"), setting, zNodes);
}
});
});
});
使用 zTree 右键菜单功能的总结的更多相关文章
- 项目中jquery插件ztree使用记录
最近公司要求做一个关于后台的管理系统.在这个mvvm模式横行的年代,虽然这里用jquery做项目可能有点不符合时代的潮流,但是管他呢,能做出来先在说呗(公司以后要改用angular或者vue来统一前端 ...
- zTree 基本用法
[简介] zTree 是利用 JQuery 的核心代码,实现一套能完成大部分常用功能的 Tree 插件 兼容 IE.FireFox.Chrome 等浏览器 在一个页面内可同时生成多个 Tree 实例 ...
- ztreeDeptSelect 基于jquery和ztree的部门选择插件
插件介绍 首先我们来看插件的功能演示(效果): 插件准备好后.前台只需编写html: <input type="text" class="deptName" ...
- C#使用Jquery zTree实现树状结构显示_异步数据加载
JQuery-Ztree下载地址:https://github.com/zTree/zTree_v3 JQuery-Ztree数结构演示页面: http://www.treejs.cn/v3/dem ...
- 【笔记】ztree的使用
引用的js和css: <!-- zTreeJS --><script type="text/javascript" src="jquery/jquery ...
- zTree和SweetAlert插件初探
1.zTree插件简介 zTree是一个依靠 jQuery实现的多功能“树插件”.优异的性能.灵活的配置.多种功能的组合是zTree最大优点.专门适合项目开发,尤其是树状菜单.树状数据的Web显示.权 ...
- jQuery.zTree的跳坑记录
最近项目用到树型结构的交互,一开始并不打算选择zTree,为了项目进度我妥协了,这一妥协后果就是我进坑了,在2天的挣扎中,我终于跳出坑了,活了下来,有一些感慨纪录下来. 有一个业务场景需要2个树型结构 ...
- ztree + ashx +DataTable +Oracle
问题描述 好久没有使用ztree了,刚才在使用ztree做导航时遇到了几个小问题: 1.返回数据源是undefined . 2.数据出现后树结构没有出现(pIdKey单词拼写错误). 3.在使用Ora ...
- js树形控件—zTree使用总结
0 zTree简介 树形控件的使用是应用开发过程中必不可少的.zTree 是一个依靠 jQuery 实现的多功能 “树插件”.优异的性能.灵活的配置.多种功能的组合是 zTree 最大优点. 0.0 ...
随机推荐
- Java - "JUC" Semaphore源码分析
Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例 Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了 ...
- Java虚拟机 - 结构原理与运行时数据区域
http://liuwangshu.cn/java/jvm/1-runtime-data-area.html 前言 本来计划要写Android内存优化的,觉得有必要在此之前介绍一下Java虚拟机的相关 ...
- (转发)一个通用的C++ 消息总线框架
注:转自https://www.cnblogs.com/qicosmos/archive/2013/04/28/3048919.html 应用开发过程中经常会处理对象间通信的问题,一般都是对象或接口的 ...
- WebKit的Platform接口部分
转载请注明出处:http://www.cnblogs.com/fangkm/p/3787977.html WebKit中解析.渲染网页的过程中需要一些功能,比如: socket连接.URL资源请求的实 ...
- PHP中按值传递和引用传递的区别
有次跟朋友讨论对象传值的方式时提到引用传值时,在大脑中搜索五秒钟,果断确定在这两个项目当中并没有用到.今天去问了一下度娘,顺便做了个小测试: 按值传递: 引用传递: 按值传递中原来参数的值在调用其他函 ...
- JS笔记--------预编译,闭包和作用域
(一)JS预编译四部曲: 1,创建AO对象. 2,找形参和变量声明,将变量和新参名作为AO属性名,值为undefined. 3,将实参值和形参值统一. 4,在函数体里找函数声明,值赋给函数体. (二) ...
- 洛谷P2881 [USACO07MAR]排名的牛Ranking the Cows(bitset Floyd)
题意 题目链接 Sol 显然如果题目什么都不说的话需要\(\frac{n * (n - 1)}{2}\)个相对关系 然后求一下传递闭包减掉就行了 #include<bits/stdc++.h&g ...
- JS--我发现,原来你是这样的JS(引用类型不简单[上篇],且听我娓娓道来)
一.介绍 没错,这是第五篇,到了引用类型,这次要分成两次博文了,太多内容了,这是前篇,篇幅很长也很多代码,主要讲引用类型和常用的引用类型,代码试验过的,老铁没毛病. 坚持看坚持写,不容易不容易,希望大 ...
- <Android 应用 之路> JuheNews For aNdroid (改进版)
简介 最新版应用已经上线,欢迎下载使用,提出宝贵意见: http://shouji.baidu.com/software/10720907.html 上一篇介绍的是最开始自己制作的一个采用聚合数据免费 ...
- 移动设备 小米2S不显示CD驱动器(H),便携设备,MTP,驱动USB Driver,MI2感叹号的解决方法
小米2S不显示CD驱动器(H),便携设备,MTP,驱动USB Driver,MI2感叹号的解决方法 by:授客 QQ:1033553122 用户环境 操作系统:Win7 手机设备:小米2S 问题描 ...