Menu树形菜单的显示(大量的js)
? ? ? ? 后端代码都较为简单。
? ? ? ? ①主页menu-page.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<%@ include file="/WEB-INF/include-head.jsp" %>
<link rel="stylesheet" href="ztree/zTreeStyle.css">
<body>
<%@ include file="/WEB-INF/include-nav.jsp" %>
<div class="container-fluid">
<div class="row">
<%@ include file="/WEB-INF/include-sidebar.jsp" %>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<div class="panel panel-default">
<div class="panel-heading"><i class="glyphicon glyphicon-th-list"></i> 权限菜单列表
<div style="float:right;cursor:pointer;" data-toggle="modal" data-target="#myModal"><i
class="glyphicon glyphicon-question-sign"></i></div>
</div>
<div class="panel-body">
<ul id="treeDemo" class="ztree">
</ul>
</div>
</div>
</div>
</div>
</div>
<script src="jquery/jquery-2.1.1.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="layer/layer.js"></script>
<script src="script/docs.min.js"></script>
<script type="text/javascript" src="ztree/jquery.ztree.all-3.5.min.js"></script>
<script type="text/javascript" src="crowd/my-menu.js"></script>
<script type="text/javascript">
$(function (){
// 生成树形结构
generateTree();
// 给添加子节点按钮绑定单机函数
$("#treeDemo").on("click",".addBtn",function (){
// 将当前节点的id作为新节点的pid保存在全局变量中
window.pid = this.id;
// 打开模态框
$("#menuAddModal").modal("show");
return false;
});
// 给添加子结点模态框中的保存按钮添加绑定单机时间
$("#menuSaveBtn").click(function (){
// 收集表单项中用户输入的数据
var name = $.trim($("#menuAddModal [name = name]").val());
var url = $.trim($("#menuAddModal [name = url]").val());
// 单选按钮定位到被选中的那一个
var icon = $.trim($("#menuAddModal [name = icon]:checked").val());
// 发送ajax请求
$.ajax({
url:"menu/save.json",
type:"post",
data:{
"pid":window.pid,
"name":name,
"url":url,
"icon":icon
},
dataType:"json",
success:function (response){
var result = response.result;
if (result == "SUCCESS"){
layer.msg("操作成功")
// 刷新树形结构
generateTree();
}
if (result == "FAILED"){
layer.msg("操作失败"+response.message);
}
},
error:function (response){
layer.msg(response.status+""+response.statusText);
}
});
// 关闭模态框
$("#menuAddModal").modal("hide");
// 清空表单 jQuery调用
$("#menuResetBtn").click();
});
// 给更新子节点添加单机事件
$("#treeDemo").on("click",".editBtn",function (){
// 将当前节点的id保存在全局变量中
window.id = this.id;
// 打开模态框
$("#menuEditModal").modal("show");
// 获取zTreeObj对象
var zTreeObj = $.fn.zTree.getZTreeObj("treeDemo");
// 根据id属性查询节点对象
// 用来搜索节点的属性名
var key = "id";
// 用来搜索节点的属性值
var value = window.id;
var currentNode = zTreeObj.getNodeByParam(key,value);
// 回显表单数据
$("#menuEditModal [name = name]").val(currentNode.name);
$("#menuEditModal [name = url]").val(currentNode.url);
// radio回显的本质是吧value属性的currentNode.icon一致的radio选中
$("#menuEditModal [name = icon]").val([currentNode.icon]);
return false;
});
// 给更新模态框中的更新按钮绑定单机事件
$("#menuEditBtn").click(function (){
var name = $("#menuEditModal [name = name]").val();
var url = $("#menuEditModal [name = url]").val();
var icon = $("#menuEditModal [name = icon]:checked").val();
// 发送ajax请求
$.ajax({
url:"menu/update.json",
type:"post",
data:{
"id":window.id,
"name":name,
"url":url,
"icon":icon
},
dataType:"json",
success:function (response){
var result = response.result;
if (result == "SUCCESS"){
layer.msg("操作成功")
// 刷新树形结构
generateTree();
}
if (result == "FAILED"){
layer.msg("操作失败"+response.message);
}
},
error:function (response){
layer.msg(response.status+""+response.statusText);
}
});
// 关闭模态框
$("#menuEditModal").modal("hide");
});
// 给删除子节点绑定单机事件
$("#treeDemo").on("click",".removeBtn",function (){
// 将当前节点的id保存在全局变量中
window.id = this.id;
// 打开模态框
$("#menuConfirmModal").modal("show");
// 获取zTreeObj对象
var zTreeObj = $.fn.zTree.getZTreeObj("treeDemo");
// 根据id属性查询节点对象
// 用来搜索节点的属性名
var key = "id";
// 用来搜索节点的属性值
var value = window.id;
var currentNode = zTreeObj.getNodeByParam(key,value);
$("#removeNodeSpan").html("【<i class='"+currentNode.icon+"'></i>"+currentNode.name+"】");
return false;
});
// 给删除模态框中的ok添加单机事件
$("#confirmBtn").click(function (){
// 发送ajax请求
$.ajax({
url:"menu/remove.json",
type:"post",
data:{
"id":window.id
},
dataType:"json",
success:function (response){
var result = response.result;
if (result == "SUCCESS"){
layer.msg("操作成功")
// 刷新树形结构
generateTree();
}
if (result == "FAILED"){
layer.msg("操作失败"+response.message);
}
},
error:function (response){
layer.msg(response.status+""+response.statusText);
}
});
// 关闭模态框
$("#menuConfirmModal").modal("hide");
});
});
$(function () {
$(".list-group-item").click(function () {
if ($(this).find("ul")) {
$(this).toggleClass("tree-closed");
if ($(this).hasClass("tree-closed")) {
$("ul", this).hide("fast");
} else {
$("ul", this).show("fast");
}
}
});
});
</script>
<%@include file="/WEB-INF/modal-menu-add.jsp" %>
<%@include file="/WEB-INF/modal-menu-confirm.jsp" %>
<%@include file="/WEB-INF/modal-menu-edit.jsp" %>
</body>
</html>
? ? ? ? 其中generateTree();的代码我们存放在my-menu.js中
function generateTree(){
// 1、准备生成树形结构的JSON数据,数据的来源是发送ajax请求
$.ajax({
url:"menu/get/whole/tree.json",
type:"post",
dataType:"json",
success:function (response){
var result = response.result;
if (result == "SUCCESS") {
// 2、创建JSON对象用于存储对zTree所做的设置
var setting = {
"view":{
"addDiyDom": myAddDiyDom,
"addHoverDom": myAddHoverDom,
"removeHoverDom": myRemoveHoverDom,
},
"data":{
"key":{
"url":"haha"
}
}
};
// 3、从响应体中取出树形数据
var zNodes = response.data;
// 4、初始化树形结构
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
}
if (result == "FEILER") {
layer.msg(response.message);
}
},
error:function (response){
layer.msg(response.message);
}
});
}
/**
* function 在鼠标移入节点范围时添加按钮组
* @param treeId 整个树形结构附着的ul标签的id
* @param treeNode 当前树形节点的全部数据,包括从后端查询得到的Menu对象的全部属性
*/
function myAddHoverDom(treeId, treeNode){
// 按钮组出现的位置:节点中treeDemo_n_a超链接的后面
// 给span设置有规律的id
var btnGroupId = treeNode.tId + "_btnGrp";
// 判断一下以前是否添加过按钮
if ($("#"+btnGroupId).length > 0){
return ;
}
// 准备按钮的html
var addBtn = "<a id='"+treeNode.id+"' class='btn btn-info dropdown-toggle btn-xs addBtn' style='margin-left:10px;padding-top:0px;" +
"' href='#' title='添加子节点'><i class='fa fa-fw fa-plus rbg '></i></a>";
var removeBtn = "<a id='"+treeNode.id+"' class='btn btn-info dropdown-toggle btn-xs removeBtn' style='margin-left:10px;padding-top:0px;" +
"' href='#' title='删除节点'><i class='fa fa-fw fa-times rbg '></i></a>";
var editBtn = "<a id='"+treeNode.id+"' class='btn btn-info dropdown-toggle btn-xs editBtn' style='margin-left:10px;padding-top:0px;" +
"' href='#' title='修改节点'><i class='fa fa-fw fa-edit rbg '></i></a>";
// 获取当前节点的级别数据
var level = treeNode.level;
// 声明一个变量存储拼装好的按钮代码
var btnHtml = "";
// 判断当前节点级别
if (level == 0){
// 级别为0时是根节点,只能添加子节点
btnHtml = addBtn;
}
if (level == 1){
// 级别为1时是分支节点。可以添加、修改子节点
btnHtml = addBtn + "" + editBtn;
// 获取当前子节点的数量
var length = treeNode.children.length;
// 如果没有自己点可以删除
if (length == 0){
btnHtml = btnHtml + "" + removeBtn;
}
}
if (level == 2){
// 级别为2时为叶子节点,可以修改删除。
btnHtml = editBtn + "" + removeBtn;
}
// 找到附着按钮的超链接
var anchorId = treeNode.tId + "_a";
// 执行在超链接后面附加的span元素的操作
$("#" + anchorId).after("<span id='"+btnGroupId+"'>"+btnHtml+"</span>")
}
/**
* function 在鼠标移出节点范围时添加按钮组
* @param treeId 整个树形结构附着的ul标签的id
* @param treeNode 当前树形节点的全部数据,包括从后端查询得到的Menu对象的全部属性
*/
function myRemoveHoverDom(treeId, treeNode){
// 给span设置有规律的id
var btnGroupId = treeNode.tId + "_btnGrp";
// 移除元素
$("#"+btnGroupId).remove();
}
/**
* function 修改默认图标
* @param treeId 整个树形结构附着的ul标签的id
* @param treeNode 当前树形节点的全部数据,包括从后端查询得到的Menu对象的全部属性
*/
function myAddDiyDom(treeId, treeNode){
// 根据id的生成规则拼接处span标签的id
var spanId = treeNode.tId + "_ico";
// 根据控制图标的span标签的id找到这个span标签
// 删除旧的class
// 添加心得class
$("#" + spanId).removeClass()
.addClass(treeNode.icon);
}
? ? ? ? ②controller
? ? ? ? ? ? ? ? 全部以发送ajax请求的方式,返回ResultEntity<T>获取数据。
package com.atguigu.crowd.mvc.controller;
import com.atguigu.crowd.entity.Menu;
import com.atguigu.crowd.service.api.MenuService;
import com.atguigu.crowd.util.ResultEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@Controller
public class MenuController {
@Autowired
MenuService menuService;
// 删除子节点
@ResponseBody
@RequestMapping(value = "/menu/remove.json")
public ResultEntity<String> removeMenu(@RequestParam("id")Integer id){
menuService.removeMenu(id);
return ResultEntity.successWithoutData();
}
// 更新子节点
@ResponseBody
@RequestMapping(value = "/menu/update.json")
public ResultEntity<String> updateMenu(Menu menu){
menuService.updateMenu(menu);
return ResultEntity.successWithoutData();
}
// 添加子节点
@ResponseBody
@RequestMapping(value = "/menu/save.json")
public ResultEntity<String> saveMenu(Menu menu){
menuService.saveMenu(menu);
return ResultEntity.successWithoutData();
}
// 生成树形结构
@ResponseBody
@RequestMapping("/menu/get/whole/tree.json")
public ResultEntity<Menu> getWholeTreeNew(){
// 1.查询全部的 Menu 对象
List<Menu> menuList = menuService.getAll();
// 2.声明一个变量用来存储找到的根节点
Menu root = null;
// 3、创建Map对象用来存储id和Menu的对应关系便于查找父节点
Map<Integer,Menu> menuMap = new HashMap<>();
// 4、遍历menuList填充menuMap
for (Menu menu : menuList){
Integer id = menu.getId();
menuMap.put(id, menu);
}
// 5、再次遍历menuList查找根节点,组装父子节点
for (Menu menu : menuList){
// 6、获取当前Menu对象的pid的值
Integer pid = menu.getPid();
// 7、如果pid为null,则定位跟几点、
if (pid == null){
root = menu;
// 8、如果当前对象是根节点,不必继续执行
continue;
}
// 9、如果pid不位null,说明当前有父节点
Menu father = menuMap.get(pid);
// 10、将当前节点存入父节点的children集合
father.getChildren().add(menu);
}
// 11、返回树节点
return ResultEntity.successWithData(root);
}
}
? ? ? ? ③service-api 和 serviceImpl
package com.atguigu.crowd.service.api;
import com.atguigu.crowd.entity.Menu;
import java.util.List;
public interface MenuService {
// 获取全部信息
List<Menu> getAll();
// 子节点
void saveMenu(Menu menu);
// 更新节点
void updateMenu(Menu menu);
// 删除节点
void removeMenu(Integer id);
}
package com.atguigu.crowd.service.impl;
import com.atguigu.crowd.entity.Menu;
import com.atguigu.crowd.entity.MenuExample;
import com.atguigu.crowd.mapper.MenuMapper;
import com.atguigu.crowd.service.api.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class MenuServiceImpl implements MenuService {
@Autowired
MenuMapper menuMapper;
// 生成树形结构
@Override
public List<Menu> getAll() {
return menuMapper.selectByExample(new MenuExample());
}
// 增加子节点
@Override
public void saveMenu(Menu menu) {
menuMapper.insert(menu);
}
@Override
public void updateMenu(Menu menu) {
// 由于pid没有传入,一定要选择有选择的更新,保证 “pid”字段不会被置空
menuMapper.updateByPrimaryKeySelective(menu);
}
@Override
public void removeMenu(Integer id) {
menuMapper.deleteByPrimaryKey(id);
}
}
测试:
? ? ? ? 菜单主界面:?
? ? ? ? 鼠标移向各个节点,呈现不同的效果
?
?
?
?
点击各个按钮:
? ? ? ? 增加节点:
? ? ? ? 修改节点:
? ? ? ? ? ? ? ? 可发现有信息的回显。
? ? ? ? ?删除节点:
? ? ? ? ? ? ? ? 将此节点删除,就不演示了。
|