版权声明:欢迎转载,请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/73291345
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
<link type="text/css" rel="stylesheet" href="${ctx}/components/bootstrap/css/bootstrap.min.css" />
<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",
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 = {};
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.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) {
var i = 0;
$.each(value.nodes, function(index1, value1) {
if (init_code.indexOf(value1.code) != -1) {
value1["state"] = {};
value1["state"]["checked"] = true;
i++;
} else {
value1["state"] = {};
}
});
value["state"] = {};
if (i > 0) {
if (value.nodes.length == i) {
value["state"]["checked"] = true;
}
value["state"]["selected"] = true;
} else {
value["state"]["selected"] = false;
}
});
}
让treeview和我们打个招呼吧!
$("#procitytree").treeview({
data : procityTreeData,
highlightSelected : false,
multiSelect : false,
showCheckbox : true,
}).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的应用已经算是非常全面了,我想你一定也会应用了,不会的话,再来找我啊!
不务正业的IT狗,喜欢读书和写作!
微信扫一扫下方二维码即可关注 沉默王二 公众号:
