bootstrap treeview樹形菜單 動態擴展 連數據庫


二話不說,先來看效果圖:

呃呃,雖然不是很美觀......不過功能實現就好啦~

 

 

數據庫模型是這樣的:

我做了什么工作呢?

簡單解釋一下,就是通過查數據庫,把上面的數據查出來,每一行數據封裝成為一個節點,然后拼成一顆樹,最后顯示在前台。注意:這里的數據是可以動態擴展的。

字段解釋:nodeId就是節點的id。pid是 parentId也就是父親的id,表示該節點是哪個節點的子節點。type=1代表功能,type=0代表菜單。level代表該節點在樹的第幾層。

OK,大家應該迫不及待想要知道具體實現了.....

滿足大家,先來看前端代碼:

  1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
  2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  3 <html>
  4 <head>
  5 <%
  6     String server_path = request.getContextPath();
  7 %>
  8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  9 </head>
 10 <!-- bootstrap-treeview 導包-->
 11 <link rel="stylesheet" type="text/css" href="<%=server_path %>/bootstrap-3.3.7-dist/css/bootstrap.css" >
 12 <link rel="stylesheet" type="text/css" href="<%=server_path %>/bootstrap-3.3.7-dist/treeview/bootstrap-treeview.css">
 13 <script type="text/javascript" src="<%=server_path %>/bootstrap-3.3.7-dist/treeview/jquery.js"></script>
 14 <script type="text/javascript" src="<%=server_path %>/bootstrap-3.3.7-dist/treeview/bootstrap-treeview.js"></script>
 15 
 16 <script type="text/javascript">
 17 //選中/取消父節點時選中/取消所有子節點
 18 function getChildNodeIdArr(node) {
 19     var ts = [];
 20     if (node.nodes) {
 21         for (x in node.nodes) {
 22             ts.push(node.nodes[x].nodeId);
 23             if (node.nodes[x].nodes) {
 24                 var getNodeDieDai = getChildNodeIdArr(node.nodes[x]);
 25                 for (j in getNodeDieDai) {
 26                     ts.push(getNodeDieDai[j]);
 27                 }
 28             }
 29         }
 30     } else {
 31         ts.push(node.nodeId);
 32     }
 33     return ts;
 34 }
 35 //選中所有子節點時選中父節點
 36 function setParentNodeCheck(node) {
 37     var parentNode = $("#tree").treeview("getNode", node.parentId);
 38     if (parentNode.nodes) {
 39         var checkedCount = 0;
 40         for (x in parentNode.nodes) {
 41             if (parentNode.nodes[x].state.checked) {
 42                 checkedCount ++;
 43             } else {
 44                 break;
 45             }
 46         }
 47         if (checkedCount === parentNode.nodes.length) {
 48             $("#tree").treeview("checkNode", parentNode.nodeId);
 49             setParentNodeCheck(parentNode);
 50         }
 51     }
 52 }
 53 
 54 $(function () {
 55     $.ajax({
 56         type: "Post",
 57         url: '<%= server_path%>/resource/menu',  
 58         dataType: "json",
 59         success: function (result) {
 60             $('#tree').treeview({
 61                 data: result.list,         // 數據源
 62                 showCheckbox: true,   //是否顯示復選框
 63                 highlightSelected: true,    //是否高亮選中
 64                 multiSelect: true,    //多選
 65                 levels : 2,
 66                 enableLinks : true,//必須在節點屬性給出href屬性
 67                 color: "#010A0E",
 68                 onNodeChecked : function (event,node) {
 69                     var selectNodes = getChildNodeIdArr(node); //獲取所有子節點
 70                     if (selectNodes) { //子節點不為空,則選中所有子節點
 71                         $('#tree').treeview('checkNode', [selectNodes, { silent: true }]);
 72                     }
 73                 },
 74                 onNodeUnchecked : function(event, node) { //取消選中節點
 75                     var selectNodes = getChildNodeIdArr(node); //獲取所有子節點
 76                     if (selectNodes) { //子節點不為空,則取消選中所有子節點
 77                         $('#tree').treeview('uncheckNode', [selectNodes, { silent: true }]);
 78                     }
 79                 },
 80                 
 81                 onNodeExpanded : function(event, data) {
 82                         
 83                 },
 84                     
 85                 onNodeSelected: function (event, data) {
 86                     //alert(data.nodeId);
 87                 }
 88                     
 89             });
 90         },
 91         error: function () {
 92             alert("菜單加載失敗!")
 93         }
 94     });
 95 })
 96 </script>
 97 </head>
 98 <body>
 99 <div id="tree" class="col-sm-2"></div>
100 </body>
101 </html>

  你沒有看錯,就是這么一個文件就搞定啦。。。

對了,導包不要導錯了。沒有這些包可以去瀏覽器下載bootstrap treeview包。下不來可來找我要。

 

okok,然后看神奇的后台代碼:

 1 @Controller
 2 @RequestMapping("/resource")
 3 public class ResourceController extends BaseController{
 4 
 5     @RequestMapping("menu")
 6     public void getMenu(HttpServletRequest request,HttpServletResponse response) throws Exception{
 7         json.setResult("no");
 8         Node tree = getTreeJson();//獲得一棵樹模型的數據
 9         //json.setData(tree);
10         json.setList(tree.getNodes());
11         json.setResult("ok");
12         response.getWriter().println(mapper.writeValueAsString(json));//把json數據寫回前台
13     }
14     
15 
16      public Node getTreeJson() {
17          List<Resource> reslist = resourceService.loadAll();//從數據庫獲取所有資源
18          List<Node> nodes = new ArrayList<Node>();//把所有資源轉換成樹模型的節點集合,此容器用於保存所有節點
19          for(Resource res : reslist){
20              Node node = new Node();
21              node.setHref(res.getUrl());
22              node.setIcon(res.getIcon());
23              node.setNodeId(res.getNodeId());
24              node.setPid(res.getPid());
25              node.setText(res.getName());
26              nodes.add(node);//添加到節點容器
27          }
28          Node tree = new Node();//重要插件,創建一個樹模型
29          Node mt = tree.createTree(nodes);//Node類里面包含了一個創建樹的方法。這個方法就是通過節點的信息(nodes)來構建一顆多叉樹manytree->mt。
30          //System.out.println(tree.iteratorTree(mt));
31          return mt;
32      }
33     
34 }

以上代碼,就是負責把數據庫的數據取出來,封裝成對應的節點,根據節點創建一顆樹,然后封裝成json數據傳到前台,就那么簡單。

看不懂不要緊,上面用了springmvc框架做控制器,如果你沒有這環境,又想做測試,你完全可以用其他控制器,servlet都行,只要能把json數據傳回前台就行。當然,上面還用了一些組件,這也不要緊,最重要的不就是紅色部分的代碼嘛,請睜大眼睛:

  1 import java.util.ArrayList;
  2 import java.util.List;
  3 /**
  4  * 樹形節點模型
  5  * @author chenht
  6  *
  7  */
  8 public class Node {
  9     public Node() { 
 10         this.nodes = new ArrayList<Node>();
 11     }
 12     public Node(String nodeId,String pId) {
 13         this.nodeId = nodeId;
 14         this.pid = pId;
 15         this.nodes = new ArrayList<Node>();
 16     }
 17     /**
 18      * 生成一個節點
 19      * @param nodeId
 20      * @param pId
 21      * @param text
 22      * @param icon
 23      * @param href
 24      */
 25     public Node(String nodeId, String pId, String text, String icon, String href) {
 26         super();
 27         this.nodeId = nodeId;
 28         this.pid = pId;
 29         this.text = text;
 30         this.icon = icon;
 31         this.href = href;
 32         this.nodes = new ArrayList<Node>();
 33     }
 34 
 35     private String nodeId;    //樹的節點Id,區別於數據庫中保存的數據Id。
 36     private String pid;
 37     private String text;   //節點名稱
 38     private String icon;
 39     private String href;   //點擊節點觸發的鏈接
 40     private List<Node> nodes;    //子節點,可以用遞歸的方法讀取
 41     
 42     public String getNodeId() {
 43         return nodeId;
 44     }
 45     public void setNodeId(String nodeId) {
 46         this.nodeId = nodeId;
 47     }
 48     
 49     public String getPid() {
 50         return pid;
 51     }
 52     public void setPid(String pid) {
 53         this.pid = pid;
 54     }
 55 
 56     public String getText() {
 57         return text;
 58     }
 59     public void setText(String text) {
 60         this.text = text;
 61     }
 62     
 63     public String getIcon() {
 64         return icon;
 65     }
 66     public void setIcon(String icon) {
 67         this.icon = icon;
 68     }
 69     
 70     public String getHref() {
 71         return href;
 72     }
 73     public void setHref(String href) {
 74         this.href = href;
 75     }
 76     
 77     public List<Node> getNodes() {
 78         return nodes;
 79     }
 80     public void setNodes(List<Node> nodes) {
 81         this.nodes = nodes;
 82     }
 83     
 84     /**
 85      * 生成一顆多叉樹,根節點為root
 86      * @param Nodes 生成多叉樹的節點集合
 87      * @return root
 88      */
 89     public Node createTree(List<Node> Nodes) {
 90         if (Nodes == null || Nodes.size() < 0)
 91             return null;
 92         Node root = new Node("root","0");//根節點自定義,但是要和pid對應好  93         // 將所有節點添加到多叉樹中
 94         for (Node node : Nodes) {
 95             if (node.getPid().equals("0") || node.getPid().equals("root")) {//根節點自定義,但是要和pid對應好
 96                 // 向根添加一個節點
 97                 root.getNodes().add(node);
 98             } else {
 99                 addChild(root, node);
100             }
101         }
102         return root;
103     }
104 
105     /**
106      * 向指定多叉樹節點添加子節點
107      * @param Node 多叉樹節點
108      * @param child 節點
109      */
110     public void addChild(Node Node, Node child) {
111         for (Node item : Node.getNodes()) {
112             if (item.getNodeId().equals(child.getPid())) {
113                 // 找到對應的父親
114                 item.getNodes().add(child);
115                 break;
116             } else {
117                 if (item.getNodes() != null && item.getNodes().size() > 0) {
118                     addChild(item, child);
119                 }
120             }
121         }
122     }
123 
124     /**
125      * 遍歷多叉樹
126      * @param Node 多叉樹節點
127      * @return
128      */
129     public String iteratorTree(Node Node) {
130         StringBuilder buffer = new StringBuilder();
131         buffer.append("\n");
132         if (Node != null) {
133             for (Node index : Node.getNodes()) {
134                 buffer.append(index.getNodeId() + ",");
135                 if (index.getNodes() != null && index.getNodes().size() > 0) {
136                     buffer.append(iteratorTree(index));
137                 }
138             }
139         }
140         buffer.append("\n");
141         return buffer.toString();
142     }
143 
144     public static void main(String[] args) {
145         List<Node> nodes = new ArrayList<Node>();
146         nodes.add(new Node("系統管理", "0"));
147         nodes.add(new Node("角色管理", "系統管理"));
148         nodes.add(new Node("資源管理", "系統管理"));
149         nodes.add(new Node("用戶管理", "系統管理"));
150         nodes.add(new Node("添加用戶", "用戶管理"));
151         nodes.add(new Node("修改用戶", "用戶管理"));
152         nodes.add(new Node("機票管理", "系統管理"));
153 
154         Node tree = new Node();
155         Node mt = tree.createTree(nodes);
156         System.out.println(tree.iteratorTree(mt));
157     }
158 
159      
160 }

 

 歐克歐克,代碼就是那么多,一個文件搞定,有人可能不相信。好吧,火狐瀏覽器下看傳回來的參數是這樣的:

 

現在總該相信了吧?到此,基本介紹完啦,驚不驚喜,開不開心?好吧,本文主要的特點是可動態擴展樹中的節點,而且與數據庫的數據一一對應上。前台用bootstrap的treeview

做展示,想必你看本文之前,已看過不少關於treeview的文章了吧。ps:紅色字體是本文重點。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM