众所周知,树型结构显示数据,直观形象,层级关系一目了然,尤其像“部门”,这种层级结构特别显著的。如果直接在树上能进行增删改操作,那方便性自然不言而喻。这篇博客,我们就来看看,怎么利用zTree来实现节点的增删改——合理利用自定义控件、事件回调函数配合以增强用户体验度。
完成增删改,要注意几个关键点:
首先,我们来看看具体的配置信息(详细内容见代码中的注释)
$(function() {
var setting = {
data : {
simpleData : {
enable : true,
idKey : "id", // 结点的id,对应到Json中的id
pIdKey : "parentId",// 结点的pId,对应到Json中的parentId
rootPId : 0 // 根节点设置为0
},
key : {
name : "departName" // 结点显示的name属性,对应到Json中的departName
}
},
view : {
addHoverDom: addHoverDom, // 用于当鼠标移动到节点上时,显示用户自定义控件。务必与 setting.view.removeHoverDom 同时使用
removeHoverDom: removeHoverDom, // 用于当鼠标移出节点时,隐藏用户自定义控件。务必与 addHoverDom 同时使用
dblClickExpand : false,
selectedMulti : false
},
edit: {
enable: true,
editNameSelectAll: true,// 节点编辑名称 input 初次显示时,设置 txt 内容是否为全选状态。
removeTitle:"删除", // 删除按钮的 Title 辅助信息
renameTitle:"重命名" // 编辑名称按钮的 Title 辅助信息。
},
async : {
enable : true,
url : "department!listAllDepByAjax.action"
},
callback : {
beforeEditName: beforeEditName, // 用于捕获节点编辑按钮的 click 事件,并且根据返回值确定是否允许进入名称编辑状态
beforeRemove: beforeRemove, // 用于捕获节点被删除之前的事件回调函数,并且根据返回值确定是否允许删除操作
beforeRename: beforeRename, // 用于捕获节点编辑名称结束(Input 失去焦点 或 按下 Enter 键)之后,更新节点名称数据之前的事件回调函数,并且根据返回值确定是否允许更改名称的操作
onClick : showDetail // 点击节点时,显示节点详细信息
}
};
$.fn.zTree.init($("#departtree"), setting);
});
再看看回调函数的具体实现(其实在进行操作前,都通过ajax把数据同步到数据库)
var log, className = "dark";
var rootNum=0;
// 添加根目录。界面上添加一个button,点击时执行。(因为,树上直接进行添加操作,添加的是子部门)
function addRootDep(){
rootNum++;
$.ajax({
type : "POST",
async : false,
url : "department!addDepNote.action",
data :
{
departName : "根部门" + rootNum,
parentId:0
},
success:function(result){
if(""!=result ){
var zTree = $.fn.zTree.getZTreeObj("departtree");
var newNode=[{id:result,departName:"根部门"+rootNum,parentId:0}];
zTree.addNodes(null,newNode);
}else{
alert("无法添加根部门,请联系管理员!");
}
}
});
}
// 在进行重命名之前,进行一下确认
function beforeEditName(treeId, treeNode) {
className = (className === "dark" ? "":"dark");
var zTree = $.fn.zTree.getZTreeObj("departtree");
zTree.selectNode(treeNode);
return confirm("确认要重命名部门 -- " + treeNode.departName + " 吗?");
}
// 删除操作
function beforeRemove(treeId, treeNode) {
className = (className === "dark" ? "":"dark");
var zTree = $.fn.zTree.getZTreeObj("departtree");
zTree.selectNode(treeNode);
var isDel=confirm("确认删除部门 -- " + treeNode.departName + " 吗?");
var isDeled=false;
if (isDel) {
$.ajax({
type : "POST",
async : false,
url : "department!delete.action",
data :
{
ids : treeNode.id
},
success:function(result){
if (result == "true") {
isDeled= true;
} else {
alert(result);
isDeled= false;
}
}
});
return isDeled;
}else{
return false;
}
}
// 重命名操作
function beforeRename(treeId, treeNode, newName, isCancel) {
className = (className === "dark" ? "":"dark");
if (newName.length == 0) {
alert("节点名称不能为空.");
var zTree = $.fn.zTree.getZTreeObj("departtree");
setTimeout(function(){zTree.editName(treeNode)}, 10);
return false;
}else{
var isDeled=false;
$.ajax({
type : "POST",
async : false,
url : "department!rename.action",
data :
{
id : treeNode.id,
departName : newName
},
success:function(result){
if (result == "true") {
isDeled= true;
} else {
alert("");
isDeled= false;
}
}
});
return isDeled;
}
}
// 添加子部门操作
var newCount = 0;
function addHoverDom(treeId, treeNode) {
var sObj = $("#" + treeNode.tId + "_span");
if (treeNode.editNameFlag || $("#addBtn_"+treeNode.tId).length>0) return;
var addStr = "";
sObj.after(addStr);
var btn = $("#addBtn_"+treeNode.tId);
//var isAdded=false;
if (btn) btn.bind("click", function(){
newCount++;
$.ajax({
type : "POST",
async : false,
url : "department!addDepNote.action",
data :
{
departName : "新部门" + newCount,
parentId:treeNode.id
},
success:function(result){
if(""!=result ){
var zTree = $.fn.zTree.getZTreeObj("departtree");
zTree.addNodes(treeNode, {id:result, parentId:treeNode.id, departName:"新部门" + (newCount)});
return false;
}else{
alert("无法添加新部门,请联系管理员!");
}
}
});
return false;
});
};
// 用于当鼠标移出节点时,隐藏用户自定义控件
function removeHoverDom(treeId, treeNode) {
$("#addBtn_"+treeNode.tId).unbind().remove();
};
【注】如果要修改部门的详细信息,点击部门,页面的右面就就会显示详细信息,进行编辑即可。
总:实现不难,就是稍麻烦一下。但给用户操作带来的方便程度,那可是大大地。