1.简介
也许你对树菜单再熟悉不过了,然而你仍有可能更青睐layui的tree,它也许比以往你知道的任何一个类似的组件都更轻量、简单,你在享受许多功能的同时,甚至不用去记太多的参数。
另外,最大的重点在于,她在UI上完全遵循于当下主流的风格,并且具备高度可扩展性,会与你的许多页面非常融洽的并存。
2.制作如下案例
步骤1.编写html
--请选择--
-
步骤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 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 = " " 271 + ""; 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 = ""; 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>
2.后端数据结构拼接(采用的数一次性查出数据 递归拼接)
1 @Override 2 public ListgetMenuDataLayUiTree() { 3 //查询所有菜单 4 List 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 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 menuList, MenuLayuiTree menu) { 26 List 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 }
完美!