1.简介
也许你对树菜单再熟悉不过了,然而你仍有可能更青睐layui的tree,它也许比以往你知道的任何一个类似的组件都更轻量、简单,你在享受许多功能的同时,甚至不用去记太多的参数。
另外,最大的重点在于,她在UI上完全遵循于当下主流的风格,并且具备高度可扩展性,会与你的许多页面非常融洽的并存。
2.制作如下案例
步骤1.编写html
<div class="layui-inline input-width" style="width: 450px;">
<label class="layui-form-label"><span class="fcred">*</span>上级菜单:</label>
<div class="layui-input-inline">
<div class="layui-unselect layui-form-select downpanel">
<div class="layui-select-title" align="center">
<span class="layui-input layui-unselect" id="treeclass" style="width: 269px;">--请选择--</span>
<input id="pid" type="hidden" name="selectID" value="0">
<i class="layui-edge"></i>
</div>
<dl class="layui-anim layui-anim-upbit">
<dd>
<ul id="classtree"></ul>
</dd>
</dl>
</div>
</div>
</div>
步骤2.初始话树与加载数据
layui.use(['element', 'tree', 'layer', 'form', 'upload'], function () {
var $ = layui.jquery, tree = layui.tree;
loadMenuTree(tree);
$(".downpanel").on("click", ".layui-select-title", function (e) {
$(".layui-form-select").not($(this).parents(".layui-form-select")).removeClass("layui-form-selected");
$(this).parents(".downpanel").toggleClass("layui-form-selected");
layui.stope(e);
}).on("click", "dl i", function (e) {
layui.stope(e);
});
$(document).on("click", function (e) {
$(".layui-form-select").removeClass("layui-form-selected");
});
});
function loadMenuTree(tree) {
var url = "permission/menuDataLayUiTree";
var params = {};
uwillBeAsyncTrue.getdata(url, params, function (data) {
tree({
elem: "#classtree",
nodes: data,
click: function (node) {
var $select = $($(this)[0].elem).parents(".layui-form-select");
$select.removeClass("layui-form-selected").find(".layui-select-title span").html(node.name).end().find("input:hidden[name='selectID']").val(node.id);
}
});
});
}
附件:
1.前端代码
1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8" %>
3 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
4 <%@taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
5 <%
6 String path = request.getContextPath();
7 String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/";
8 %>
9 <!DOCTYPE html>
10 <html lang="en">
11 <head>
12 <base href="<%=basePath%>">
13 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
14 <meta charset="UTF-8">
15 <title>菜单管理</title>
16 <link rel="stylesheet" href="static/layui/css/layui.css">
17 <link rel="stylesheet" href="static/css/common.css">
18 <link rel="stylesheet" href="static/css/schoolInfo.css">
19 <link rel="stylesheet" href="static/css/teacherInfo.css">
20 <!--[if IE 8]>
21 <!-- <link rel="stylesheet" type="text/css" href="static/css/ie.css"/>-->
22 <link rel="stylesheet" type="text/css" href="static/zTree/css/zTreeStyle/zTreeStyle.css"/>
23 <%-- <link rel="stylesheet" type="text/css" href="static/zTree/css/demo.css"/>--%>
24 <style type="text/css">
25 .downpanel .layui-select-title span {
26 line-height: 38px;
27 }
28
29 /*继承父类颜色*/
30 .downpanel dl dd:hover {
31 /* background-color: inherit;*/
32 }
33 </style>
34 <style type="text/css">
35 body {
36 height: 100%;
37 width: 100%;
38 background-size: cover;
39 margin: 0 auto;
40 }
41
42 td {
43 font-size: 12px !important;
44 }
45
46 .layui-form-checkbox span {
47 height: 30px;
48 }
49
50 .layui-field-title {
51 border-top: 1px solid white;
52 }
53
54 table {
55 width: 100% !important;
56 }
57
58 .input-width {
59 width: 360px;
60 }
61
62 .input-widthC {
63 width: 369px;
64 }
65
66 </style>
67 </head>
68 <body class="content">
69 <div id="app">
70 <div class="xy-backdrop" hidden onclick="showFlashDialog()"><img src="static/images/loding.gif"></div>
71 <p class="p-title"></p>
72 <form class="layui-form row-between form">
73 <%--左侧--%>
74 <div class="form-left fl layui-form" style="width: 400px;">
75 <div class="b-bottom">
76 <%-- <p class="text-title">菜单信息</p>--%>
77 <div class="layui-inline search-nobor" style="margin-top: 10px;">
78 <p class="layui-btn layui-btn-radius bg-org box-shaow-org" lay-filter="add" id="add"
79 style="width: 120px;">新增</p>
80 </div>
81
82 <div class="layui-form-item mt30">
83 <div class="layui-inline" style="height: 400px">
84 <ul id="treeDemo" class="ztree" style="margin-top: 10px; width: 200px; height: 150px;">
85 </ul>
86 </div>
87 </div>
88 </div>
89 </div>
90
91 <%--右侧--%>
92 <div id="rightEditId" style="display:none;" class="form-right fl layui-form">
93 <p class="text-title">编辑菜单</p>
94 <div class="flex-start b-bottom mt30">
95 <div class="layui-form-item ">
96 <div class="layui-inline">
97 <label class="layui-form-label"><span class="fcred">*</span>菜单名称:</label>
98 <div class="layui-input-block wh20 input-widthC">
99 <input id="menuName" type="text" name="menuName" maxlength="10" lay-verify="name"
100 onkeydown="if(event.keyCode==32) return false" autocomplete="off" placeholder="菜单名称"
101 class="layui-input" value="${menuUpdate.menuName}">
102 </div>
103 </div>
104
105 <br/>
106 <br/>
107
108 <div class="layui-inline input-width" style="width: 450px;">
109 <label class="layui-form-label"><span class="fcred">*</span>上级菜单:</label>
110 <div class="layui-input-inline">
111 <div class="layui-unselect layui-form-select downpanel">
112 <div class="layui-select-title" align="center">
113 <span class="layui-input layui-unselect" id="treeclass" style="width: 269px;">--请选择--</span>
114 <input id="pid" type="hidden" name="selectID" value="0">
115 <i class="layui-edge"></i>
116 </div>
117 <dl class="layui-anim layui-anim-upbit">
118 <dd>
119 <ul id="classtree"></ul>
120 </dd>
121 </dl>
122 </div>
123 </div>
124 </div>
125
126
127 <br/>
128 <br/>
129
130 <div class="layui-inline">
131 <label class="layui-form-label"><span class="fcred"></span>url地址:</label>
132 <div class="layui-input-block wh20 input-widthC">
133 <input id="menuUrl" type="text" name="menuUrl" maxlength="30" lay-verify="name"
134 onkeydown="if(event.keyCode==32) return false" autocomplete="off"
135 placeholder="url地址:(选填)"
136 class="layui-input" value="${menuUpdate.menuUrl}">
137 </div>
138 </div>
139
140 <br/>
141 <br/>
142
143 <div class="layui-inline">
144 <label class="layui-form-label"><span class="fcred"></span>排序:</label>
145 <div class="layui-input-block wh20 input-widthC">
146 <input id="menuOrder" type="text" name="menuOrder" maxlength="3" lay-verify="name"
147 onkeydown="if(event.keyCode==32) return false" autocomplete="off"
148 placeholder="排序:(选填)"
149 class="layui-input" value="${menuUpdate.menuOrder}" oninput="value=value.replace(/[^\d]/g,'')" >
150 </div>
151 </div>
152
153 <br/>
154 <br/>
155
156 <div class="layui-inline">
157 <label class="layui-form-label"><span class="fcred"></span>图标地址:</label>
158 <div class="layui-input-block wh20 input-widthC">
159 <input id="menuIcon" type="text" name="menuIcon" maxlength="10" lay-verify="name"
160 onkeydown="if(event.keyCode==32) return false" autocomplete="off"
161 placeholder="图标地址:(选填)"
162 class="layui-input" value="${menuUpdate.menuIcon}">
163 </div>
164 </div>
165
166 <br/>
167 <br/>
168
169 </div>
170 </div>
171
172
173 <!--修改信息-->
174 <input id="id" name="id" value="" hidden/>
175 <%-- <input id="pid" value="" hidden>--%>
176 <input id="type" name="type" value="" hidden/>
177 <div class="layui-form-item text-center">
178 <p id="myButton" type="submit"
179 class="layui-btn layui-btn-radius bg-org box-shaow-org wh135px" lay-submit=""
180 lay-filter="demoRole">保存
181 </p>
182 </div>
183 </div>
184 </form>
185
186
187 </div>
188 <script src="static/layui/layui.js"></script>
189 <script src="static/js/jquery-1.8.3.js"></script>
190 <script src="static/js/public.js"></script>
191 <script src="static/js/jquery.form.js"></script>
192 <script type="text/javascript" src="static/zTree/js/jquery-1.4.4.min.js"></script>
193 <script type="text/javascript" src="static/zTree/js/jquery.ztree.core.js"></script>
194 <%--<script type="text/javascript" src="static/zTree/js/jquery.ztree.all.min.js"></script>--%>
195 <%--<script type="text/javascript" src="static/js/common/menu.js"></script>--%>
196 <script src="static/zTree/js/jquery.ztree.excheck.js"></script>
197 <script src="static/zTree/js/jquery.ztree.exedit.js"></script>
198
199
200 <script type="text/javascript">
201 var aa = {aa: 1};
202 var isIE = /msie/i.test(navigator.userAgent) && !window.opera;
203 var imgAA = 0;
204
205 var teacherImg, layer, form;
206 layui.use(['form'], function () {
207 form = layui.form;
208 layer = layui.layer;
209
210 //监听提交
211 form.on('submit(demoRole)', function (data) {
212
213
214 });
215 });
216
217
218 function createTree(url, params, treeId) {
219 var zTree; //用于保存创建的树节点
220 var setting = { //设置
221 view: {
222 // addHoverDom: addHoverDom, //控制是否显示添加按钮
223 // removeHoverDom: removeHoverDom,
224 showLine: true, //显示辅助线
225 selectedMulti: false, //设置是否允许同时选中多个节点
226 showLine: true, //设置是否显示节点与节点之间的连线
227 showTitle: false, //设置是否显示节点的title提示信息
228 dblClickExpand: true
229 },
230 edit: {
231 showRemoveBtn: true, //是否显示移除按钮
232 showRenameBtn: false,
233 enable: true, //控制是否可以拖拽
234 drag: {
235 isCopy: false, //拖拽时, 设置是否允许复制节点
236 isMove: false //拖拽时, 设置是否允许移动节点
237 }
238 },
239 callback: {
240 beforeRemove: zTreeBeforeRemove, //删除之前回调函数
241 // beforeRename: zTreeBeforeRename //修改之前回调函数
242 onClick: zTreeOnClick
243 },
244 data: {
245 simpleData: {
246 enable: true,
247 idKey: "id",
248 pIdKey: "pid",
249 rootPId: 0
250 }
251 }
252 };
253 $.ajax({ //请求数据,创建树
254 type: 'GET',
255 url: url,
256 data: params,
257 dataType: "json", //返回的结果为json
258 success: function (data) {
259 zTree = $.fn.zTree.init($(treeId), setting, data); //创建树
260 },
261 error: function (data) {
262 alert("创建树失败!");
263 }
264 });
265 }
266
267 function addDiyDom(treeId, treeNode) {
268 var aObj = $("#" + treeNode.tId + "_a");
269 if ($("#diyBtn_" + treeNode.id).length > 0) return;
270 var editStr = "<span id='diyBtn_space_" + treeNode.id + "' > </span>"
271 + "<button type='button' class='diyBtn1' id='diyBtn_" + treeNode.id
272 + "' title='" + treeNode.name + "' onfocus='this.blur();'></button>";
273 aObj.append(editStr);
274 var btn = $("#diyBtn_" + treeNode.id);
275 if (btn) btn.bind("click", function () {
276 alert("diy Button for " + treeNode.name);
277 });
278 }
279 ;
280 var newCount = 1;
281 function addHoverDom(treeId, treeNode) {
282 var sObj = $("#" + treeNode.tId + "_span");
283 if (treeNode.editNameFlag || $("#addBtn_" + treeNode.tId).length > 0) return;
284 var addStr = "<span class='button add' id='addBtn_" + treeNode.tId
285 + "' title='add node' onfocus='this.blur();' ></span>";
286 sObj.after(addStr);
287 var btn = $("#addBtn_" + treeNode.tId);
288 if (btn) btn.bind("click", function () {
289 var pid = treeNode.id;
290 // type=1新增 type=2 修改
291 openEditMenu('新增菜单', pid, 1);
292 return false;
293 });
294 }
295 ;
296 function removeHoverDom(treeId, treeNode) {
297 $("#addBtn_" + treeNode.tId).unbind().remove();
298 }
299 /**
300 * 打开右侧 编辑框
301 * */
302 $("#add").click(function () {
303 $("#rightEditId").show();
304 //清空原有的数据
305 $("input").val("");
306 $("#treeclass").html("--请选择--");
307 //设置 type 区分修改还是新增
308 $("#type").val(1);
309
310 });
311 function openEditMenu(title, pid, type) {
312 layer.open({
313 type: 2,
314 title: title,
315 maxmin: true,
316 shade: 0.4,
317 area: ['80%', '80%'],
318 content: "<%=basePath%>permission/editMenu?pid=" + pid + "&type=" + type
319 });
320 $(".layui-layer-min").remove();
321 }
322 /**
323 * 确定删除
324 * */
325 function zTreeBeforeRemove(treeId, treeNode) {
326 //隐藏右侧框
327 $("#rightEditId").hide();
328 var nodeP = treeNode.isParent;
329 var id;
330 if (nodeP) {
331 id=-2;
332 }else {
333 id=treeNode.mid;
334 }
335 layer.confirm('确定要删除节点[' + treeNode.name + ']吗?', function (index) {
336 $.ajax({
337 type: "POST",
338 url: '<%=basePath%>permission/deleteMenu',
339 data: {"id": id, timestamp: (new Date()).valueOf()},
340 dataType: 'json',
341 cache: false,
342 success: function (data) {
343 if (data.code == '0000') {
344 layer.alert("删除成功", {icon: 1});
345 initTree();
346 }else if (data.code == '9998'){
347 layer.alert(data.msg, {icon: 2});
348 }else {
349 layer.alert("删除失败", {icon: 2});
350 }
351 }
352 });
353 });
354
355 return false;
356 }
357 /**
358 * 执行删除
359 * */
360 function doRemove(treeNode) {
361
362 }
363 /**
364 * 点击回调函数 用于修改使用
365 * @param treeId
366 * @param treeNode
367 * @returns {boolean}
368 */
369 function zTreeOnClick(event, treeId, treeNode) {
370 var mid = treeNode.mid;
371 var mpid = treeNode.mpid;
372 var nodeP = treeNode.getParentNode();
373 var nameP;
374 if (nodeP == null) {
375 nameP = '--请选择--';
376 } else {
377 nameP = nodeP.name;
378 }
379 $("#rightEditId").show();
380 //清空原有的数据
381 $("input").val("");
382 $("#treeclass").html("--请选择--");
383 //设置 type 区分修改还是新增
384 //数据回显
385
386 $("#id").val(mid);
387 $("#pid").val(mpid);
388 $("#menuName").val(treeNode.name);
389 $("#treeclass").html(nameP);
390 $("#menuUrl").val(treeNode.menuUrl);
391 $("#menuOrder").val(treeNode.menuOrder);
392 $("#menuIcon").val(treeNode.menuIcon);
393 $("#type").val(2);
394 }
395 function initTree() {
396 var params = {
397 roleId: -1
398 };
399 createTree("permission/menuData", params, "#treeDemo");//创建
400 }
401 initTree();
402
403 /*修改或新增js*/
404 /**
405 * 保存选中的数据
406 */
407 $("#myButton").click(function () {
408 updateOrAddMenu();
409 });
410 function updateOrAddMenu() {
411 var id = $("#id").val();
412 var pid = $("#pid").val();
413 var menuName = $("#menuName").val();
414 var menuUrl = $("#menuUrl").val();
415 var menuOrder = $("#menuOrder").val();
416 var menuIcon = $("#menuIcon").val();
417 var type = $("#type").val();
418 var params = {
419 id: id,
420 pid: pid,
421 menuName: menuName,
422 menuUrl: menuUrl,
423 menuOrder: menuOrder,
424 menuIcon: menuIcon,
425 type: type
426 };
427 var url = "permission/updateOrAddMenu";
428 uwillBeAsyncTrue.getdata(url, params, function (data) {
429 var code = data.code;
430 if (code == '0000') {
431 layer.msg("操作成功");
432 setTimeout(function test() {
433 initTree();
434 $("#rightEditId").hide();
435 }, 800);
436 } else {
437 layer.alert("操作失败", {icon: 2});
438 }
439 });
440 }
441
442 layui.use(['element', 'tree', 'layer', 'form', 'upload'], function () {
443 var $ = layui.jquery, tree = layui.tree;
444 loadMenuTree(tree);
445
446 $(".downpanel").on("click", ".layui-select-title", function (e) {
447 $(".layui-form-select").not($(this).parents(".layui-form-select")).removeClass("layui-form-selected");
448 $(this).parents(".downpanel").toggleClass("layui-form-selected");
449 layui.stope(e);
450 }).on("click", "dl i", function (e) {
451 layui.stope(e);
452 });
453 $(document).on("click", function (e) {
454 $(".layui-form-select").removeClass("layui-form-selected");
455 });
456
457 });
458
459 function loadMenuTree(tree) {
460 var url = "permission/menuDataLayUiTree";
461 var params = {};
462 uwillBeAsyncTrue.getdata(url, params, function (data) {
463 tree({
464 elem: "#classtree",
465 nodes: data,
466 click: function (node) {
467 var $select = $($(this)[0].elem).parents(".layui-form-select");
468 $select.removeClass("layui-form-selected").find(".layui-select-title span").html(node.name).end().find("input:hidden[name='selectID']").val(node.id);
469 }
470 });
471 });
472 }
473
474 </script>
475 </body>
476 </html>
View Code
2.后端数据结构拼接(采用的数一次性查出数据 递归拼接)
1 @Override
2 public List<MenuLayuiTree> getMenuDataLayUiTree() {
3 //查询所有菜单
4 List<MenuLayuiTree> list = new ArrayList<>();
5 MenuLayuiTree menuNull = new MenuLayuiTree();
6 menuNull.setId("0");
7 menuNull.setPid("0");
8 menuNull.setName("一级菜单");
9 menuNull.setMenuLevel("1");
10 menuNull.setMenuOrder("0");
11 list.add(menuNull);
12
13 List<MenuLayuiTree> menuLayuiTrees = permissionDao.queryMenuLayuiTree();
14
15 for (MenuLayuiTree menu : menuLayuiTrees) {
16 String menuLevel = menu.getMenuLevel();
17 if ("1".equals(menuLevel)) {
18 MenuLayuiTree method = method(menuLayuiTrees, menu);
19 list.add(method);
20 }
21 }
22 return list;
23 }
24
25 public MenuLayuiTree method(List<MenuLayuiTree> menuList, MenuLayuiTree menu) {
26 List<MenuLayuiTree> childrens = new ArrayList<>();
27 String id = menu.getId();
28 for (MenuLayuiTree childrenMenu : menuList) {
29 String pid = childrenMenu.getPid();
30 if (pid.equals(id)) {
31 childrens.add(childrenMenu);
32 //查询子节点的下级节点
33 method(menuList, childrenMenu);
34 }
35 }
36 menu.setChildren(childrens);
37 return menu;
38 }
View Code
完美!