zTree开发下拉树

  最近,因为工作需要一个树形下拉框的组件,经过查资料一般有两种的实现方法。其一,就是使用zTree实现;其二,就是使用easyUI实现。因为公司的前端不是使用easyUI设计的,故这里我选择了zTree来实现下拉树。

这里使用简单的数据格式(即简单的Json格式)类似如下Json:

var zNodes =[
            {id:1, pId:0, name:"北京"},
            {id:2, pId:0, name:"天津"},
            {id:3, pId:0, name:"上海"},
            {id:6, pId:0, name:"重庆"},
            {id:4, pId:0, name:"河北省", open:true, nocheck:true},
            {id:41, pId:4, name:"石家庄"},
            {id:42, pId:4, name:"保定"},
            {id:43, pId:4, name:"邯郸"},
            {id:44, pId:4, name:"承德"},
            {id:5, pId:0, name:"广东省", open:true, nocheck:true},
            {id:51, pId:5, name:"广州"},
            {id:52, pId:5, name:"深圳"},
            {id:53, pId:5, name:"东莞"},
            {id:54, pId:5, name:"佛山"},
            {id:6, pId:0, name:"福建省", open:true, nocheck:true},
            {id:61, pId:6, name:"福州"},
            {id:62, pId:6, name:"厦门"},
            {id:63, pId:6, name:"泉州"},
            {id:64, pId:6, name:"三明"}
         ];

这里首先需要一个实体bean,用来封装对应查出来的数据,如下:

public class ZtreeNode {

    // id
    private String id;
    // 父id
    private String pId;
    // 显示名称
    private String name;
    // 是否打开 (这里默认是不打开的,如果需要打开,设为true)
    // private boolean open ;
    // 能否选择 (设置节点是否能够选择,默认都能选择,设为true对应的节点不能选择)
    // private boolean nocheck ;
    
    /**getter and setter*/
}

 这里需要注意的是 pId 中的第二的字母是大写的,如果写成小写的就不能构造成树形结构,所有的都是根节点。

然后,将从数据库中查出来的数据,转换为对应的ztree需要的bean,再转换为相应的Json,代码如下:

// 获取商品分类树 返回json
    public String getGoodsCategoryTreeJson() {
        List<GoodsCategory> allGoodsCategoryList = goodsCategoryService.getGoodsCategoryTreeJson() ;
        List<ZtreeNode> ztreelist = new ArrayList<ZtreeNode>();
        for(GoodsCategory gcty : allGoodsCategoryList){
            ZtreeNode treenade = new ZtreeNode();
            treenade.setId(gcty.getId());
            treenade.setpId(gcty.getParent()==null?"":gcty.getParent().getId());
            treenade.setName(gcty.getName());
            ztreelist.add(treenade);
        }
        return ajax(ztreelist);
    }

 将list转换为对应的Json方法,如下:

用到的Json工具包:

import org.springframework.base.util.JsonUtil;
private static final String HEADER_ENCODING = "UTF-8";
private static final boolean HEADER_NO_CACHE = true;
private static final String HEADER_TEXT_CONTENT_TYPE = "text/plain";
private static final String HEADER_JSON_CONTENT_TYPE = "text/plain";

// AJAX输出
    protected String ajax(String content, String contentType) {
        try {
            HttpServletResponse response = initResponse(contentType);
            response.getWriter().write(content);
            response.getWriter().flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return NONE;
    }

    // 根据文本内容输出AJAX
    protected String ajax(String text) {
        return ajax(text, HEADER_TEXT_CONTENT_TYPE);
    }
    
    // 根据操作状态输出AJAX
    protected String ajax(Status status) {
        HttpServletResponse response = initResponse(HEADER_JSON_CONTENT_TYPE);
        Map<String, String> jsonMap = new HashMap<String, String>();
        jsonMap.put(STATUS_PARAMETER_NAME, status.toString());
        JsonUtil.toJson(response, jsonMap);
        return NONE;
    }
    
    // 根据操作状态、消息内容输出AJAX
    protected String ajax(Status status, String message) {
        HttpServletResponse response = initResponse(HEADER_JSON_CONTENT_TYPE);
        Map<String, String> jsonMap = new HashMap<String, String>();
        jsonMap.put(STATUS_PARAMETER_NAME, status.toString());
        jsonMap.put(MESSAGE_PARAMETER_NAME, message);
        JsonUtil.toJson(response, jsonMap);
        return NONE;
    }
    
    // 根据Object输出AJAX
    protected String ajax(Object object) {
        HttpServletResponse response = initResponse(HEADER_JSON_CONTENT_TYPE);
        JsonUtil.toJson(response, object);
        return NONE;
    }
    
    // 根据boolean状态输出AJAX
    protected String ajax(boolean booleanStatus) {
        HttpServletResponse response = initResponse(HEADER_JSON_CONTENT_TYPE);
        Map<String, Object> jsonMap = new HashMap<String, Object>();
        jsonMap.put(STATUS_PARAMETER_NAME, booleanStatus);
        JsonUtil.toJson(response, jsonMap);
        return NONE;
    }

  private HttpServletResponse initResponse(String contentType) {
        HttpServletResponse response = ServletActionContext.getResponse();
        response.setContentType(contentType + ";charset=" + HEADER_ENCODING);
        if (HEADER_NO_CACHE) {
            response.setDateHeader("Expires", 1L);
            response.addHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache, no-store, max-age=0");
        }
        return response;
    }

这样前台所需要的数据,就从库里取出,并封装成了对应的Json。

接下来就是前台的实现了,前台需要导入的js和css如下:

<link rel="stylesheet" href="${base}/template/ztree/css/demo.css" type="text/css">
<link rel="stylesheet" href="${base}/template/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css">
<script type="text/javascript" src="${base}/template/ztree/js/jquery.ztree.core.js"></script>

 这里只有demo.css是自己添加的,其他都是官方制定的,demo.css是将官方的demo用到的css修改的,如下(这里有冗余样式没有删除掉);

 1 div.content_wrap { 400px;}
 2 div.content_wrap div.left{float: left;}
 3 div.content_wrap div.right{float: right; 340px;}
 4 div.zTreeDemoBackground {text-align:left;}
 5 
 6 ul.ztree {margin-top: 10px;border: 1px solid #617775;background: #fefefe;220px;height:360px;overflow-y:scroll;overflow-x:auto;}
 7 ul.log {border: 1px solid #617775;background: #f0f6e4;300px;height:170px;overflow: hidden;}
 8 ul.log.small {height:45px;}
 9 ul.log li {color: #666666;list-style: none;padding-left: 10px;}
10 ul.log li.dark {background-color: #E3E3E3;}
11 
12 /* ruler */
13 div.ruler {height:20px; 220px; background-color:#f0f6e4;border: 1px solid #333; margin-bottom: 5px; cursor: pointer}
14 div.ruler div.cursor {height:20px; 30px; background-color:#3C6E31; color:white; text-align: right; padding-right: 5px; cursor: pointer}

然后,就是对应的下拉框:

 1 <div class="content_wrap">
 2     <div class="zTreeDemoBackground left">
 3          <input id="citySel"  class="formText" type="text" onclick="showMenu(); return false;" readonly value="" style="150px;"/>
 4          <input id="treeids" type="hidden" name="goods.goodsCategory.id" >
 5          <input type="button" onclick="showMenu();" value="∨">
 6     </div>
 7 </div>
 8<div id="menuContent" class="menuContent" style="display:none; position: absolute;">
 9    <ul id="treeDemo" class="ztree" style="margin-top:0;"></ul>
10 </div>

这里有一个隐藏的文本框用来存放下拉框选择内容对应的id。

对应的脚本如下:

<SCRIPT type="text/javascript">
        
        var setting = {
            view: {
                dblClickExpand: false
            },
            data: {
                simpleData: {
                    enable: true
                }
            },
            callback: {
                onClick: onClick
            },
            view: {
          // 不显示对应的图标 showIcon: false } }; function onClick(e, treeId, treeNode) { var zTree = $.fn.zTree.getZTreeObj("treeDemo"), nodes = zTree.getSelectedNodes(), v = ""; ids = ""; nodes.sort(function compare(a,b){return a.id-b.id;}); for (var i=0, l=nodes.length; i<l; i++) { v += nodes[i].name + ","; ids += nodes[i].id + ","; } if (v.length > 0 ) v = v.substring(0, v.length-1); var cityObj = $("#citySel"); cityObj.attr("value", v); // 将选中的id放到隐藏的文本域中 if (ids.length > 0 ) ids = ids.substring(0, ids.length-1); var treeids = $("#treeids"); treeids.attr("value", ids); } function showMenu() { var cityObj = $("#citySel"); var cityOffset = $("#citySel").offset(); $("#menuContent").css({left:cityOffset.left + "px", top:cityOffset.top + cityObj.outerHeight() + "px"}).slideDown("fast"); $("body").bind("mousedown", onBodyDown); } function hideMenu() { $("#menuContent").fadeOut("fast"); $("body").unbind("mousedown", onBodyDown); } function onBodyDown(event) { if (!(event.target.id == "menuBtn" || event.target.id == "menuContent" || $(event.target).parents("#menuContent").length>0)) { hideMenu(); } } var zNodes ; $(document).ready(function(){       // 加载数据 $.ajax({ async : false, cache:false, type: 'POST', dataType : 'json', url: '${base}/admin/goods!getGoodsCategoryTreeJson.action', error: function () { alert('请求失败'); }, success:function(data){ zNodes = data; } }); $.fn.zTree.init($("#treeDemo"), setting, zNodes); }); </SCRIPT>

这样,一个下拉框就做完了。如下图所示:

如果,需要在修改页面中回写相应的下拉列表数据,添加如下的脚本:

<script type="text/javascript">
$(document).ready(function(){
    if ("${goods.goodsCategory.id}"!="") {
        var treeObj = $.fn.zTree.getZTreeObj("treeDemo");
        var node = treeObj.getNodeByParam("id", "${goods.goodsCategory.id}" , null);
        treeObj.selectNode(node,false , false);
        onClick(event,"${goods.goodsCategory.id}",node,true);
        
    }
});
</script>
原文地址:https://www.cnblogs.com/hezhh/p/5378975.html