先上效果图
数据库表设计,结构很简单,就不细说明每个字段的意思了,一眼就可以看出每个字段代表的意思
CREATE TABLE `organize` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(255) DEFAULT NULL,
`DESCRIPTION` varchar(500) DEFAULT NULL,
`P_ID` int(11) DEFAULT NULL,
`IS_PARENT` varchar(255) DEFAULT NULL,
PRIMARY KEY (`ID`)
)
前端代码部分,需要引入zTreeStyle.css和jquery.ztree.all-3.5.min.js文件
<ul id="orgTree" class="ztree"></ul>
<!--右键菜单-->
<div id="rMenu">
<ul>
<li id="m_add" onclick="addTreeNode();">增加节点</li>
<li id="m_edit" onclick="editTreeNode();">修改节点</li>
<li id="m_del" onclick="removeTreeNode();">删除节点</li>
<li id="m_check" onclick="checkTreeNode(true);">选中节点</li>
<li id="m_unCheck" onclick="checkTreeNode(false);">取消节点</li>
<li id="m_reset" onclick="resetTree();">刷新</li>
</ul>
</div>
js代码
var orgId;
var onClick = function(e, treeId, treeNode) {
var nodes = zTree.getSelectedNodes();//
if (nodes.length > 0 && nodes[0]) {
zTree.reAsyncChildNodes(nodes[0], "refresh");// 刷新节点
}
//点击选中
zTree.checkNode(nodes[0], true, true);
zTree.updateNode(nodes[0]);
orgId = treeNode.id;
refresh();
};
var zTreeOnAsyncSuccess = function(event, treeId, treeNode, msg){
var nodes = zTree.getNodes();
if (nodes.length>0) {
for(var i=0;i<nodes.length;i++){
zTree.expandNode(nodes[i], true, false, false);//默认展开第一级节点
}
}
}
var filter = function(treeId, parentNode, childNodes) {
if (!childNodes) return null;
for (var i=0, l=childNodes.length; i<l; i++) {
childNodes[i].name = childNodes[i].name.replace(/\.n/g, '.');
}
return childNodes;
}
var showRMenu = function(type, x, y) {
$("#rMenu ul").show();
y += document.body.scrollTop;
x += document.body.scrollLeft;
rMenu.css({"top":y+"px", "left":x+"px", "visibility":"visible"});
}
/**
* 右键菜单
*/
var OnRightClick = function(event, treeId, treeNode){
if (!treeNode && event.target.tagName.toLowerCase() != "button" && $(event.target).parents("a").length == 0) {
zTree.cancelSelectedNode();
showRMenu("root", event.clientX, event.clientY);
} else if (treeNode && !treeNode.noR) {
zTree.selectNode(treeNode);
showRMenu("node", event.clientX, event.clientY);
}
}
/**
* 隐藏右键菜单
*/
var hideRMenu = function() {
if (rMenu) rMenu.css({"visibility": "hidden"});
}
/**
* 增加节点
*/
var selectedNode;
var addOrEdit = true;
var addTreeNode = function() {
hideRMenu();
reset();
selectedNode = zTree.getSelectedNodes()[0];
$("#organize-add-or-update-modal").modal('show');
addOrEdit = true;
}
/**
* 修改节点
*/
var editTreeNode = function() {
hideRMenu();
reset();
selectedNode = zTree.getSelectedNodes()[0];
$("#organize-add-or-update-modal").modal('show');
$("#organize-form").setForm($.util.getNodeValue(zTree.getSelectedNodes()[0]));
addOrEdit = false;
}
/**
* 移除节点
*/
var removeTreeNode = function() {
hideRMenu();
var nodes = zTree.getSelectedNodes();
if (!nodes || nodes.length<=0) {
return $.util.alert('请选择一个节点!');
}
$.util.confirm('确认要删除?如果有子节点将一起删掉,请确认!',function(r){
if(r){
//后台数据移除
var params = {id:nodes[0].id};
$.util.ajaxReq('back/organize/deleteModel',params,function(success,result){
if(success && result.success){
//界面移除
zTree.removeNode(nodes[0]);
}else{
$.util.alert(result.message);
}
});
}
});
}
/**
* 选中节点
*/
var checkTreeNode = function(checked) {
var nodes = zTree.getSelectedNodes();
if (nodes && nodes.length>0) {
zTree.checkNode(nodes[0], checked, true);
}
hideRMenu();
}
var setting = {
check : {
enable : true
},
data : {
simpleData : {
enable : true,
idKey : "id",//节点id
pIdKey : "pId",//父节点id
rootPId: 0
}
},
async : {
enable : true,
url : "back/organize/organizeAsyncTree",
autoParam : [ "id"],
dataFilter: filter
},
callback : {
onClick : onClick,
onRightClick: OnRightClick
}
};
var buildTree = function(pId){
var zNodes = {};
var params = {pId:pId};
$.util.ajaxReq('back/organize/organizeAsyncTree',params,function(success,result){
if(success){
zNodes = result;
}else{
$.util.alert(result.message);
}
});
return zNodes;
};
//新增界面重置
var reset = function(){
$("#organize-form")[0].reset();
};
var initTree = function(){
zTree = $.fn.zTree.init($("#orgTree"), setting,buildTree(0));
var rootNode_0 = zTree.getNodeByParam('pId',0,null);
zTree.expandNode(rootNode_0, true, false, false, false);
}
/**
* 刷新树
*/
var resetTree = function() {
hideRMenu();
initTree();
}
var zTree, rMenu;
$(function(){
initTree();
rMenu = $("#rMenu");
});
后端代码
/**
* 异步加载树
*/
@RequestMapping("/organizeAsyncTree")
@ResponseBody
public List<OrganizeModel> organizeAsyncTree(HttpServletRequest request,@RequestParam(name="id",defaultValue="0") Integer pId){
return organizeService.organizeAsyncTree(pId).getObj();
}
mybatis文件
<select id="listByPid" resultType="OrganizeModel" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from organize
where 1=1
and p_id = #{pId,jdbcType=INTEGER}
</select>