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


Posted in Javascript onJune 15, 2017

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 Tree View简单而优雅的树结构组件实例解析 
Bootstrap Tree View简单而优雅的树结构组件实例解析 
Bootstrap Tree View简单而优雅的树结构组件实例解析 
Bootstrap Tree View简单而优雅的树结构组件实例解析

二、应用

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

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

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

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

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

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

Java端非常简单:

@RequestMapping(value = "loadProcitysInfo")
public void loadProcitysInfo(HttpServletResponse response) {
 logger.debug("获取所有省市");
 try {
  List<Provincial> provincials = provincialService.getProvincials();
  for (Provincial provincial : provincials) {
   List<City> citys = cityService.getCitysByProvincialId(provincial.getId());
   provincial.setCitys(citys);
  }
  renderJsonDone(response, provincials);
 } catch (Exception e) {
  logger.error(e.getMessage(), e);
  logger.error(e.getMessage());
  renderJsonError(response, Constants.SERVER_ERROR);
 }
}

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

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

protected void renderJsonDone(HttpServletResponse response, final Object value) {
 Map<String, Object> map = new HashMap<String, Object>();
 map.put("statusCode", 200);
 map.put("result", value);
 String jsonText = JSON.toJSONString(map);
 PrintWriter writer = null;
 try {
  response.setHeader("Pragma", "no-cache");
  response.setHeader("Cache-Control", "no-cache");
  response.setDateHeader("Expires", 0);
  response.setContentType(contentType);
  writer = response.getWriter();
  writer.write(jsonText);
  writer.flush();
 } catch (IOException e) {
  throw new OrderException(e.getMessage());
 } finally {
  if (writer != null)
   writer.close();
 }
}

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

jQuery.ajax({
 url : common.ctx + "/procity/loadProcitysInfo", // 请求的URL
 dataType : 'json',
 async : false,
 timeout : 50000,
 cache : false,
 success : function(response) {
  var json = YUNM.jsonEval(response);

  if (json[YUNM.keys.statusCode] == YUNM.statusCode.ok) {
   var records = json[YUNM.keys.result];
   if (!json)
    return;
   // 城市列表都存在
   if (records != null && records.length > 0) {
    // 遍历子节点
    $.each(records, function(index, value) {
     var proNode = {};
     // text是显示的内容
     proNode["text"] = value.proname;
     proNode["id"] = value.id;
     proNode["procode"] = value.procode;
     // 节点不可选中
     proNode["selectable"] = false;
     // 初始化市级节点
     proNode["nodes"] = [];

     $.each(value.citys, function(index, value) {
      var cityNode = {};
      cityNode["text"] = value.cname;
      cityNode["id"] = value.id;
      cityNode["proid"] = value.proid;
      cityNode["code"] = value.code;
      // 节点不可选中
      cityNode["selectable"] = false;

      proNode["nodes"].push(cityNode);
     });
     // 保存页面端对象中
     //YUNM._set.procityTreeData的数据结构就是二维数组。
     YUNM._set.procityTreeData.push(proNode);
    });
   }
  }
 }
});

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

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

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

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

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

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

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

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

/* 树形省市 */
.treeview .list-group-item.node-checked {
 color: red;
}
.treeview .list-group-item.node-selected {
 color: red;
}

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

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

让treeview和我们打个招呼吧!

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

⑤、节点onNodeChecked、onNodeUnchecked的应用

不要⑤就够了吗?

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

就像效果图中那样。

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

onNodeChecked : function(event, node) {
 YUNM.debug("选中项目为:" + node);
 // 省级节点被选中,那么市级节点都要选中
 if (node.nodes != null) {
  $.each(node.nodes, function(index, value) {
   $this.treeview('checkNode', value.nodeId, {
    silent : true
   });
  });
 } else {
  // 市级节点选中的时候,要根据情况判断父节点是否要全部选中
  // 父节点
  var parentNode = $this.treeview('getParent', node.nodeId);
  var isAllchecked = true; // 是否全部选中
  // 当前市级节点的所有兄弟节点,也就是获取省下面的所有市
  var siblings = $this.treeview('getSiblings', node.nodeId);
  for ( var i in siblings) {
   // 有一个没选中,则不是全选
   if (!siblings[i].state.checked) {
    isAllchecked = false;
    break;
   }
  }
  // 全选,则打钩
  if (isAllchecked) {
   $this.treeview('checkNode', parentNode.nodeId, {
    silent : true
   });
  } else {// 非全选,则变红
   $this.treeview('selectNode', parentNode.nodeId, {
    silent : true
   });
  }
 }
},
onNodeUnchecked : function(event, node) {
 YUNM.debug("取消选中项目为:" + node);
 // 选中的是省级节点
 if (node.nodes != null) {
  // 这里需要控制,判断是否是因为市级节点引起的父节点被取消选中
  // 如果是,则只管取消父节点就行了
  // 如果不是,则子节点需要被取消选中
  if (silentByChild) {
   $.each(node.nodes, function(index, value) {
    $this.treeview('uncheckNode', value.nodeId, {
     silent : true
    });
   });
  }
 } else {
  // 市级节点被取消选中
  var parentNode = $this.treeview('getParent', node.nodeId);
  var isAllUnchecked = true; // 是否全部取消选中
  // 市级节点有一个选中,那么就不是全部取消选中
  var siblings = $this.treeview('getSiblings', node.nodeId);
  for ( var i in siblings) {
   if (siblings[i].state.checked) {
    isAllUnchecked = false;
    break;
   }
  }
  // 全部取消选中,那么省级节点恢复到默认状态
  if (isAllUnchecked) {
   $this.treeview('unselectNode', parentNode.nodeId, {
    silent : true,
   });
   $this.treeview('uncheckNode', parentNode.nodeId, {
    silent : true,
   });
  } else {
   silentByChild = false;
   $this.treeview('selectNode', parentNode.nodeId, {
    silent : true,
   });
   $this.treeview('uncheckNode', parentNode.nodeId, {
    silent : true,
   });
  }
 }
 silentByChild = true;
},

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

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

Javascript 相关文章推荐
JS实现静止元素自动移动示例
Apr 14 Javascript
JQuery获取表格数据示例代码
May 26 Javascript
Node.js编码规范
Jul 14 Javascript
javascript 动态修改css样式方法汇总(四种方法)
Aug 27 Javascript
javascript特效实现——当前时间和倒计时效果的简单实例
Jul 20 Javascript
本地Bootstrap文件字体图标引入却无法显示问题的解决方法
Apr 18 Javascript
基于js实现二级下拉联动
Dec 17 Javascript
Angular 4.x 动态创建表单实例
Apr 25 Javascript
swiper插件自定义切换箭头按钮
Dec 28 Javascript
使用异步组件优化Vue应用程序的性能
Apr 28 Javascript
Nuxt.js实现一个SSR的前端博客的示例代码
Sep 06 Javascript
JavaScript 判断数据类型的4种方法
Sep 11 Javascript
Angularjs为ng-click事件传递参数
Jun 15 #Javascript
详解原生js实现offset方法
Jun 15 #Javascript
微信小程序 监听手势滑动切换页面实例详解
Jun 15 #Javascript
微信小程序canvas写字板效果及实例
Jun 15 #Javascript
AngularJs实现聊天列表实时刷新功能
Jun 15 #Javascript
bootstrap daterangepicker双日历时间段选择控件详解
Jun 15 #Javascript
详解react-router如何实现按需加载
Jun 15 #Javascript
You might like
PHP CURL模拟GET及POST函数代码
2010/04/25 PHP
PHP的5个安全措施小结
2012/07/17 PHP
PHP的new static和new self的区别与使用
2019/11/27 PHP
javascript之大字符串的连接的StringBuffer 类
2007/05/08 Javascript
jQuery 菜单随滚条改为以定位方式(固定要浏览器顶部)
2012/05/24 Javascript
js实现简单登录功能的实例代码
2013/11/09 Javascript
按下Enter焦点移至下一个控件的实现js代码
2013/12/11 Javascript
简体中文转换繁体中文(实现代码)
2013/12/25 Javascript
javascript实现图片延迟加载方法汇总(三种方法)
2015/08/27 Javascript
JavaScript中Number对象的toFixed() 方法详解
2016/09/02 Javascript
AngularJS动态加载模块和依赖的方法分析
2016/11/08 Javascript
Angular2使用Augury来调试Angular2程序
2017/05/21 Javascript
在vue组件中使用axios的方法
2018/03/16 Javascript
使用angular-cli webpack创建多个包的方法
2018/10/16 Javascript
vue 实现搜索的结果页面支持全选与取消全选功能
2019/05/10 Javascript
JavaScript中的ES6 Proxy的具体使用
2019/06/16 Javascript
小程序的上传文件接口的注意要点解析
2019/09/17 Javascript
[54:29]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第二场
2018/04/09 DOTA
[45:59]完美世界DOTA2联赛PWL S2 FTD vs GXR 第二场 11.22
2020/11/24 DOTA
python使用新浪微博api上传图片到微博示例
2014/01/10 Python
一个简单的python爬虫程序 爬取豆瓣热度Top100以内的电影信息
2018/04/17 Python
PyQt5每天必学之拖放事件
2020/08/27 Python
python实现Flappy Bird源码
2018/12/24 Python
Django User 模块之 AbstractUser 扩展详解
2020/03/11 Python
python:解析requests返回的response(json格式)说明
2020/04/30 Python
python语言是免费还是收费的?
2020/06/15 Python
X/HTML5 和 XHTML2
2008/10/17 HTML / CSS
外科实习自我鉴定
2013/10/06 职场文书
计算机专业个人简短的自我评价
2013/10/23 职场文书
护理学中专毕业生求职信
2013/11/11 职场文书
2015年元旦文艺汇演主持词
2014/03/26 职场文书
项目投资合作意向书
2014/07/29 职场文书
幼儿园秋季开学寄语
2014/08/02 职场文书
教师党的群众路线教育实践活动学习笔记
2014/11/05 职场文书
爱牙日宣传活动总结
2015/02/05 职场文书
python中tkinter复选框使用操作
2021/11/11 Python