当前位置: 移动技术网 > IT编程>开发语言>JavaScript > Bootstrap Tree View简单而优雅的树结构组件实例解析

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

2017年12月12日  | 移动技术网IT编程  | 我要评论

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在上的简介。

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

那么今天的实例是通过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进行初始化了。

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

这里写图片描述

如果用户已经保存过一部分节点,那么初次展示的时候就需要通过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的应用

不要⑤就够了吗?

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

就像效果图中那样。

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

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简单而优雅的树结构组件实例解析,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网