zoukankan      html  css  js  c++  java
  • bootstrap treetable 树形网格,动态扩展,连数据库

    二话不说,先看看效果图:

    1、先来看写死的:

    展开前~~

    展开后~~

     怎么实现呢?

    先new 一个jsp文件,导入几个包,编写html代码,编写js代码,一个文件搞定!

     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 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     6 <title>Insert title here</title>
     7 <script type="text/javascript" src="../bootstrap-3.3.7-dist/treeview/jquery.js"></script>
     8 <script type="text/javascript" src="../js/jquery.treetable.js"></script>
     9 <link rel="stylesheet" type="text/css" href="../css/jquery.treetable.css">
    10 <link rel="stylesheet" type="text/css" href="../css/jquery.treetable.theme.default.css">
    11 <script type="text/javascript">
    12 $(document).ready(function(){
    13     $("#treeTable").treetable({  
    14         expandable : true,
    15         initialState:"expanded",
    16         //expandable : true
    17         clickableNodeNames:true,//点击节点名称也打开子节点.
    18         indent : 30//每个分支缩进的像素数。
    19     });
    20 });
    21 </script>
    22 </head>
    23 <body>
    24     <div>
    25     <table id="treeTable" style="800px">  
    26         <tr>  
    27              <td>名字</td> 
    28              <td>URL</td> 
    29              <td>操作<td>
    30          </tr>  
    31          <tr data-tt-id="a">  
    32              <td>a</td> 
    33              <td>a.jsp</td> 
    34              <td><button>edit</button> <td>
    35          </tr>  
    36          <tr data-tt-id="a1" data-tt-parent-id="a">  
    37              <td>a1</td>
    38              <td>a1.jsp</td>  
    39              <td><button>edit</button> <td>
    40          </tr>  
    41          <tr data-tt-id="b">  
    42              <td>b</td>  
    43              <td>b.jsp</td> 
    44              <td><button>edit</button> <td>
    45          </tr>  
    46          <tr data-tt-id="b1" data-tt-parent-id="b">  
    47              <td>b1</td>  
    48              <td>b1.jsp</td> 
    49               <td><button>edit</button> <td>
    50          </tr>  
    51     </table>  
    52     </div>
    53 </body>
    54 </html>

    把上面代码拷回去试试?记得导treetable的包。

    2、有了上面的基础,再来看连数据库的,可动态扩展(推荐),但是相对麻烦一点。

    效果图:

    数据库模型是这样的:

    字段解释:nodeId就是节点的id。pid是 parentId也就是父亲的id(注意:最根的节点的pid会和代码耦合,或做好约定——代码总要根据什么字符来找到最根节点),表示该节点是哪个节点的子节点。type=1代表功能,type=0代表菜单。level代表该节点在树的第几层。

    我做了什么工作呢?

    简单解释一下,就是通过查数据库,把上面的数据查出来,每一行数据封装成为一个节点,然后拼成一颗树,然后对树进行“中序遍历”,按“中序遍历“的顺序把每一个节点添加到list,最后显示在前台(有点绕,下面解释为什么这样做。因为是多叉树,中序遍历我打了引号)。注意:这里的数据是可以动态扩展的。

    数据库查出来的数据本来就是一个list,我把这个list的数据封装成为一个节点,然后拼成一颗树,然后又把这颗树按中序的遍历顺序转化成了list。

    看似多余,其实这是由于treetable这个插件构建树的时候是根据html的table里面定义的tr来构建的,具体可观察上面写死的那个例子。而它对tr定义的顺序也有要求(有兴趣可在自己机器上调换一下tr的顺序,看看效果)。

    在这个前提下,试想:传会前台的数据要怎么解析?传回来的数据毫无疑问是json数据,是用list结构的还是tree结构的?

    其实都可以。如果是tree结构的(可见我另外一个例子:http://www.cnblogs.com/chenhtblog/p/8342534.html),前台一样需要对这一棵树进行“中序遍历“,按这个顺序把每一个节点生成一个tr。这里我是在后台处理了业务逻辑,传回来的是“中序遍历“后的list。

    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 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     6 <title>Insert title here</title>
     7 <%
     8     String server_path = request.getContextPath();
     9 %>
    10 <script type="text/javascript" src="../bootstrap-3.3.7-dist/treeview/jquery.js"></script>
    11 <script type="text/javascript" src="../js/jquery.treetable.js"></script>
    12 <link rel="stylesheet" type="text/css" href="../css/jquery.treetable.css">
    13 <link rel="stylesheet" type="text/css" href="../css/jquery.treetable.theme.default.css">
    14 <script type="text/javascript">
    15 $(document).ready(function(){
    16     $.ajax({
    17         "type" : 'post',
    18         "url" : '<%= server_path%>/resource/reslist',
    19         "dataType" : "json",
    20         "success" : function(data) {
    21             $.each(data.data, function(idx, obj) {
    22                 $("#treeTable").append("<tr data-tt-id="" + obj.nodeId + "" data-tt-parent-id="" + obj.pid + ""><td>" + obj.text + "</td><td>" + obj.href + "</td><td><button id="" + obj.nodeId + "">编辑</button><button id="" + obj.nodeId + "">删除</button></td></tr>");
    23             });
    24             $("#treeTable").treetable({  
    25                 expandable : true,
    26                 initialState:"expanded",
    27                 //expandable : true
    28                 clickableNodeNames:true,//点击节点名称也打开子节点.
    29                 indent : 30//每个分支缩进的像素数。
    30             });
    31         }
    32     });
    33     
    34 });
    35 </script>
    36 </head>
    37 <body>
    38     <table id="treeTable" style="800px">  
    39         <tr>  
    40              <td>名字</td> 
    41              <td>URL</td> 
    42              <td>操作</td>
    43          </tr>  
    44     </table>  
    45 
    46 </body>
    47 </html>

    注意:上面用了ajax的异步请求,要把$("#treeTable").treetable();方法写在success域里面,因为要重新生成table,必须要先有数据,然后才能生成!!!

    控制器(springMVC)代码:

    @RequestMapping("reslist")
        public void getReslist(HttpServletRequest request,HttpServletResponse response) throws Exception{
            json.setResult("no");//返回前台的json数据
            Node tree = getTreeJson();//获得树形结构的json数据
            Node n = tree.zxPraseTree(tree);//把树形结构数据按中序遍历顺序,加入list
            List<Node> reslist = n.getNodes();//获得上面的list
            List<Node> list = new ArrayList<Node>();
            for(Node node : reslist) {//去掉null节点
                if(null != node) {
                    if(node.getNodeId() != null) {
                        list.add(node);
                    }
                }
            }
            json.setData(list);//设置,返回到前台
            json.setResult("ok");
            response.getWriter().println(mapper.writeValueAsString(json));
        }
    
         public Node getTreeJson() {
             List<Resource> reslist = resourceService.loadAll();//从数据库加载所有数据,得到list
             List<Node> nodes = new ArrayList<Node>();
             for(Resource res : reslist){
                 Node node = new Node();
                 node.setHref(res.getUrl());
                 node.setIcon(res.getIcon());
                 node.setNodeId(res.getNodeId());
                 node.setPid(res.getPid());
                 node.setText(res.getName());
                 nodes.add(node);
             }
             Node tree = new Node();
             Node mt = tree.createTree(nodes);//把list转化成tree
             System.out.println(tree.iteratorTree(mt));//遍历打印
             return mt;
         }

    提供一个工具类:

      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 NodeTree
     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");
     93         // 将所有节点添加到多叉树中
     94         for (Node node : Nodes) {
     95             if (node.getPid().equals("0") || node.getPid().equals("root")) {
     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("
    ");
    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("
    ");
    141         return buffer.toString();
    142     }
    143     
    144     
    145     /**
    146      * 遍历多叉树
    147      * @param Node 多叉树节点
    148      * @return
    149      */
    150     List<Node> node = new ArrayList<Node>();
    151     public Node zxPraseTree(Node Node) {
    152         if (Node != null) {
    153             for (Node index : Node.getNodes()) {
    154                 node.add(index);
    155                 if (index.getNodes() != null && index.getNodes().size() > 0) {
    156                     node.add(zxPraseTree(index));
    157                 }
    158             }
    159         }
    160         //buffer.append("
    ");
    161         Node n = new Node();
    162         n.setNodes(node);
    163         return n;
    164     }
    165 
    166     public static void main(String[] args) {
    167         List<Node> nodes = new ArrayList<Node>();
    168         nodes.add(new Node("系统管理", "0"));
    169         nodes.add(new Node("角色管理", "系统管理"));
    170         nodes.add(new Node("资源管理", "系统管理"));
    171         nodes.add(new Node("用户管理", "系统管理"));
    172         nodes.add(new Node("添加用户", "用户管理"));
    173         nodes.add(new Node("修改用户", "用户管理"));
    174         nodes.add(new Node("机票管理", "系统管理"));
    175 
    176         Node tree = new Node();
    177         Node mt = tree.createTree(nodes);
    178         System.out.println(tree.iteratorTree(mt));
    179         Node n = tree.zxPraseTree(mt);
    180         List<Node> list = n.getNodes();
    181         for(Node node : list) {
    182             System.out.println(node.getNodeId());
    183         }
    184     }
    185 
    186      
    187 }

    传回来的数据:

    再加上导入bootstrap的包,稍微改一下样式就是第一张图的效果啦~~~

    最后再次说明:本例子支持连数据库,动态扩展。但是例子用了springMVC的环境,不可硬搬代码到你机器上去运行哦。主要思路已经写明白了,工具类也给出,已帮各位解决80%难度。主要是要明白每一步做了什么工作,事在人为,根据思路相信你也可以弄出来。说实话网络上太少比较靠谱的例子了。。。

  • 相关阅读:
    mysql #与$的区别
    linux连接mysql
    19年春第十三周学习
    第二阶段冲刺-02
    第二阶段冲刺-01
    19年春第十二周学习
    第一阶段SCRUM冲刺-10
    第一阶段SCRUM冲刺-09
    第一阶段SCRUM冲刺-08
    19年春第十一周学习
  • 原文地址:https://www.cnblogs.com/chenhtblog/p/8507752.html
Copyright © 2011-2022 走看看