当前位置:Gxlcms > JavaScript > Bootstrap Tree View简单而优雅的树结构组件实例解析

Bootstrap Tree View简单而优雅的树结构组件实例解析

时间:2021-07-01 10:21:17 帮助过:4人阅读

A simple and elegant solution to displaying hierarchical tree structures (i.e. a Tree View) while leveraging the best that Twitter Bootstrap has to offer.

这是Bootstrap Tree View在git上的简介。

注意simple、elegant,简单而优雅,我喜欢这两个词。

那么今天的实例是通过Bootstrap Tree View来制作一款省市级菜单的应用。

一、效果图

这里写图片描述 
这里写图片描述 
这里写图片描述 
这里写图片描述

二、应用

①、首先,项目需要引入bootstrap.css、jquery.js、bootstrap-treeview.js

  1. <link type="text/css" rel="stylesheet" href="${ctx}/components/bootstrap/css/bootstrap.min.css" rel="external nofollow" />
  2. <script type="text/javascript" src="${ctx}/components/jquery/jquery-1.10.1.min.js"></script>
  3. <script type="text/javascript" src="${ctx}/components/treeview/js/bootstrap-treeview.js"></script>

②、接下来,页面上需要放一个dom元素。

  1. <div id="procitytree" style="height: 400px;overflow-y :scroll;"></div>

通过设置height和overflow-y,使treeview能够在垂直方向上出现滚动条。

③、由于省市级数据一般都是固定不变的,那么页面初次加载时,我们把省市级数据先拿到。

Java端非常简单:

  1. @RequestMapping(value = "loadProcitysInfo")
  2. public void loadProcitysInfo(HttpServletResponse response) {
  3. logger.debug("获取所有省市");
  4. try {
  5. List<Provincial> provincials = provincialService.getProvincials();
  6. for (Provincial provincial : provincials) {
  7. List<City> citys = cityService.getCitysByProvincialId(provincial.getId());
  8. provincial.setCitys(citys);
  9. }
  10. renderJsonDone(response, provincials);
  11. } catch (Exception e) {
  12. logger.error(e.getMessage(), e);
  13. logger.error(e.getMessage());
  14. renderJsonError(response, Constants.SERVER_ERROR);
  15. }
  16. }

这段代码需要优化,通过mybatis其实可以一次就获得省级和市级的集合。

获取数据后,通过json写入到response中。

  1. protected void renderJsonDone(HttpServletResponse response, final Object value) {
  2. Map<String, Object> map = new HashMap<String, Object>();
  3. map.put("statusCode", 200);
  4. map.put("result", value);
  5. String jsonText = JSON.toJSONString(map);
  6. PrintWriter writer = null;
  7. try {
  8. response.setHeader("Pragma", "no-cache");
  9. response.setHeader("Cache-Control", "no-cache");
  10. response.setDateHeader("Expires", 0);
  11. response.setContentType(contentType);
  12. writer = response.getWriter();
  13. writer.write(jsonText);
  14. writer.flush();
  15. } catch (IOException e) {
  16. throw new OrderException(e.getMessage());
  17. } finally {
  18. if (writer != null)
  19. writer.close();
  20. }
  21. }

前端通过ajax对数据进行组装保存。

  1. jQuery.ajax({
  2. url : common.ctx + "/procity/loadProcitysInfo", // 请求的URL
  3. dataType : 'json',
  4. async : false,
  5. timeout : 50000,
  6. cache : false,
  7. success : function(response) {
  8. var json = YUNM.jsonEval(response);
  9. if (json[YUNM.keys.statusCode] == YUNM.statusCode.ok) {
  10. var records = json[YUNM.keys.result];
  11. if (!json)
  12. return;
  13. // 城市列表都存在
  14. if (records != null && records.length > 0) {
  15. // 遍历子节点
  16. $.each(records, function(index, value) {
  17. var proNode = {};
  18. // text是显示的内容
  19. proNode["text"] = value.proname;
  20. proNode["id"] = value.id;
  21. proNode["procode"] = value.procode;
  22. // 节点不可选中
  23. proNode["selectable"] = false;
  24. // 初始化市级节点
  25. proNode["nodes"] = [];
  26. $.each(value.citys, function(index, value) {
  27. var cityNode = {};
  28. cityNode["text"] = value.cname;
  29. cityNode["id"] = value.id;
  30. cityNode["proid"] = value.proid;
  31. cityNode["code"] = value.code;
  32. // 节点不可选中
  33. cityNode["selectable"] = false;
  34. proNode["nodes"].push(cityNode);
  35. });
  36. // 保存页面端对象中
  37. //YUNM._set.procityTreeData的数据结构就是二维数组。
  38. YUNM._set.procityTreeData.push(proNode);
  39. });
  40. }
  41. }
  42. }
  43. });

④、拿到数据之后,就可以对treeview进行初始化了。

这里,我们讲一点更复杂的应用,如下图。

这里写图片描述

如果用户已经保存过一部分节点,那么初次展示的时候就需要通过treeview展示出来了。
我们定一些规则:

节点全部选中时color为red,check框选中。

节点未全部选中时color为red,check框未选中。

节点一个也没选中时color为默认,check框未选中。

为此,我们需要增加一点css。

  1. /* 树形省市 */
  2. .treeview .list-group-item.node-checked {
  3. color: red;
  4. }
  5. .treeview .list-group-item.node-selected {
  6. color: red;
  7. }

有了这个规则,我们在初次展开treeview的时候,就需要重新制定以下数据规则。

  1. // 省市级数据
  2. var procityTreeData = YUNM._set.procityTreeData;
  3. // 用户已经选中的城市,比如河南洛阳。
  4. var init_code = $this.next("input[name=area]").val();
  5. // 如果用户有选中项,则对选中项进行规则展示
  6. if (init_code) {
  7. // 初始化选中项目
  8. $.each(procityTreeData, function(index, value) {
  9. // 通过i和省级的节点length进行对比,判断是否全选、未全选、全未选三种状态
  10. var i = 0;
  11. $.each(value.nodes, function(index1, value1) {
  12. if (init_code.indexOf(value1.code) != -1) {
  13. // 选中时先初始化state,再把state.checked设为true
  14. value1["state"] = {};
  15. value1["state"]["checked"] = true;
  16. i++;
  17. } else {
  18. // 否则重置state,保证procityTreeData数据的不被更改
  19. // 这个地方其实有待优化,由于js我还不算精通,所以不知道怎么把数组复制到一个新数组里,保证原始属于不被更改
  20. value1["state"] = {};
  21. }
  22. });
  23. value["state"] = {};
  24. // 市级节点有选中,那么省级节点的状态需要变化,根据上面制定的规则来
  25. if (i > 0) {
  26. // 市级全选,那么此时省级节点打钩
  27. if (value.nodes.length == i) {
  28. value["state"]["checked"] = true;
  29. }
  30. // 根据selected来设定颜色
  31. value["state"]["selected"] = true;
  32. } else {
  33. value["state"]["selected"] = false;
  34. }
  35. });
  36. }

让treeview和我们打个招呼吧!

  1. $("#procitytree").treeview({
  2. data : procityTreeData,// 赋值
  3. highlightSelected : false,// 选中项不高亮,避免和上述制定的颜色变化规则冲突
  4. multiSelect : false,// 不允许多选,因为我们要通过check框来控制
  5. showCheckbox : true,// 展示checkbox
  6. }).treeview('collapseAll', {// 节点展开
  7. silent : true
  8. });

⑤、节点onNodeChecked、onNodeUnchecked的应用

不要⑤就够了吗?

不够,我们还要控制节点选择框的变化。

就像效果图中那样。

这里写图片描述 
这里写图片描述 
这里写图片描述

  1. onNodeChecked : function(event, node) {
  2. YUNM.debug("选中项目为:" + node);
  3. // 省级节点被选中,那么市级节点都要选中
  4. if (node.nodes != null) {
  5. $.each(node.nodes, function(index, value) {
  6. $this.treeview('checkNode', value.nodeId, {
  7. silent : true
  8. });
  9. });
  10. } else {
  11. // 市级节点选中的时候,要根据情况判断父节点是否要全部选中
  12. // 父节点
  13. var parentNode = $this.treeview('getParent', node.nodeId);
  14. var isAllchecked = true; // 是否全部选中
  15. // 当前市级节点的所有兄弟节点,也就是获取省下面的所有市
  16. var siblings = $this.treeview('getSiblings', node.nodeId);
  17. for ( var i in siblings) {
  18. // 有一个没选中,则不是全选
  19. if (!siblings[i].state.checked) {
  20. isAllchecked = false;
  21. break;
  22. }
  23. }
  24. // 全选,则打钩
  25. if (isAllchecked) {
  26. $this.treeview('checkNode', parentNode.nodeId, {
  27. silent : true
  28. });
  29. } else {// 非全选,则变红
  30. $this.treeview('selectNode', parentNode.nodeId, {
  31. silent : true
  32. });
  33. }
  34. }
  35. },
  36. onNodeUnchecked : function(event, node) {
  37. YUNM.debug("取消选中项目为:" + node);
  38. // 选中的是省级节点
  39. if (node.nodes != null) {
  40. // 这里需要控制,判断是否是因为市级节点引起的父节点被取消选中
  41. // 如果是,则只管取消父节点就行了
  42. // 如果不是,则子节点需要被取消选中
  43. if (silentByChild) {
  44. $.each(node.nodes, function(index, value) {
  45. $this.treeview('uncheckNode', value.nodeId, {
  46. silent : true
  47. });
  48. });
  49. }
  50. } else {
  51. // 市级节点被取消选中
  52. var parentNode = $this.treeview('getParent', node.nodeId);
  53. var isAllUnchecked = true; // 是否全部取消选中
  54. // 市级节点有一个选中,那么就不是全部取消选中
  55. var siblings = $this.treeview('getSiblings', node.nodeId);
  56. for ( var i in siblings) {
  57. if (siblings[i].state.checked) {
  58. isAllUnchecked = false;
  59. break;
  60. }
  61. }
  62. // 全部取消选中,那么省级节点恢复到默认状态
  63. if (isAllUnchecked) {
  64. $this.treeview('unselectNode', parentNode.nodeId, {
  65. silent : true,
  66. });
  67. $this.treeview('uncheckNode', parentNode.nodeId, {
  68. silent : true,
  69. });
  70. } else {
  71. silentByChild = false;
  72. $this.treeview('selectNode', parentNode.nodeId, {
  73. silent : true,
  74. });
  75. $this.treeview('uncheckNode', parentNode.nodeId, {
  76. silent : true,
  77. });
  78. }
  79. }
  80. silentByChild = true;
  81. },

到这里,treeview的应用已经算是非常全面了

以上所述是小编给大家介绍的Bootstrap Tree View简单而优雅的树结构组件实例解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

人气教程排行