也許你對樹菜單再熟悉不過了,然而你仍有可能更青睞layui的tree,它也許比以往你知道的任何一個相似的組件都更輕量、簡單,你在享受許多功能的同時,甚至不用去記太多的參數。javascript
另外,最大的重點在於,她在UI上徹底遵循於當下主流的風格,而且具有高度可擴展性,會與你的許多頁面很是融洽的並存。css
步驟1.編寫htmlhtml
<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); } }); }); }
附件:java
1.前端代碼node
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>
2.後端數據結構拼接(採用的數一次性查出數據 遞歸拼接)jquery
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 }
完美!ajax