用了小一天的时间学习了zTree插件,做出了一个地区树的小例子,感觉这个插件真的蛮强大的,实现的过程中也遇到了一些困惑,现在总结一下。
从官网http://www.ztree.me/v3/main.php#_zTreeInfo 下载zTree插件,项目中导入js、css和image,zTree有很多扩展js,暂时没有用上,所以只导入jquery.ztree.core.js就可以了,当然还要导入jquery.min.js,css需要导入zTreeStyle.css,而demo.css中有很多样式,如果需要用到的话也可以导入。
首先页面需要一个输入框,通过点击输入框弹出树列表,选择完地区后可以显示地区名称,当然还需要一个隐藏的输入字段来保存地区的ID。
地区:<input type="text" id="area" οnclick="treeText()"/>
<input type="hidden" name="vo.areaId" id="areaId"/>
然后需要树的容器,一个<ul>列表,class必须是ztree。
<div class="content_wrap" id="tree_box">
<ul id="tree" class="ztree"></ul>
</div>
之后需要编写java类来传列表中的数据,zTree接收的数据是如同json一样的格式,所以这里将数据放进jsonArray中,然后转成String类型。
如果是一次全部加载,直接取出所有结果放到jsonArray中即可。下面主要说明异步加载。
先取根节点的数据,这里的根节点只有一个中国,所以直接取得。
public String getAreaRoot(){
JSONArray jsonArray = new JSONArray();
String sql = "select area_id,area_name from t_area where area_id=0";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next){
JSONObject jsonObject = new JSONObject();
jsonObject.put("areaId", rs.getLong("area_id"));
jsonObject.put("areaName", rs.getString("area_name"));
jsonObject.put("isParent", "true"); //判断是否有子节点,就是前面有没有那个小加号可以展开
jsonArray.add(jsonObject);
}
return jsonArray.toString();
}
对于选择一个地区展开其下列表,需要获取这个地区ID,查询父级parent_id为该地区ID的所有结果,查询的同时还要得到每个结果是否还有子集。
public String getAreaChild(long id){
JSONArray jsonArray = new JSONArray();
String sql = "select area_id,area_name,parent_id,(select count(*) from t_area where t_area.parent_id=t.area_id) count from t_area t where parent_id=?";
ps.setString(1,id);
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next){
JSONObject jsonObject = new JSONObject();
jsonObject.put("areaId", rs.getLong("area_id"));
jsonObject.put("areaName", rs.getString("area_name"));
jsonObject.put("parentId", rs.getLong("parent_id"));
jsonObject.put("isParent", "true");
jsonArray.add(jsonObject);
}
return jsonArray.toString();
}
下面通过action或者servlet将结果传递给页面。
public String getIPArea() throws Exception{
String jsonObj = new AreaTree().getAreaRoot();
request.setAttribute("jsonObj", jsonObj);
return "suc";
}
//这个方法困扰了我很久,两个点,
//一个是js部分中的url应该连到此方法;
//第二是通过HttpServletResponse去传递结果,这是ajax机制,可惜没有深入学
public void asyncTree() throws Exception{
HttpServletResponse response;
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
String jsonObj = new AreaTree().getAreaChild(this.getAreaId());
out.print(jsonObj);
}
关键的javascript部分,官网的API很详细,都是参照写的,http://www.ztree.me/v3/api.php
<script type="text/javascript">
var ztreeObj;
setting={
view:{
selectedMulti: false
},
//异步加载的关键地方,如果是一次全部加载可以忽略
async: {
enable: true,
url: "http://localhost:8080/areaTest/AreaAction!asyncTree.action",
autoParam: ["areaId"], //异步加载需要传递的参数
dataType : "json",
type : "post"
},
data:{
key : {
name : "areaName" //如果命名就是"name",此处可以不写
},
simpleData : {
enable : true,
idKey : "areaId", // id编号命名
pIdKey : "parentId", // 父id编号命名
}
},
callback: {
asyncError: zTreeOnAsyncError,
onClick: onClick,
}
},
zTreeNodes = ${jsonObj}; //列表的数据写在这里,这里用的EL表达式获取action给的值
//点击每个节点的事件
function onClick(e,treeId, treeNode) {
var zTree = $.fn.zTree.getZTreeObj("tree");
zTree.expandNode(treeNode);
$("#area").val(treeNode.areaName);
$("#areaId").val(treeNode.areaId);
}
function zTreeOnAsyncError(e, treeId, treeNode){
alert("异步加载失败!");
}
//树的初始化,必须要有的
$(document).ready(function(){
zTreeObj = $.fn.zTree.init($("#tree"), setting, zTreeNodes);
});
</script>
最后上效果图: