• 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>
  • 相关阅读:
    数据库索引类型及实现方式
    MyBatis从入门到精通(十一):MyBatis高级结果映射之一对多映射
    解决克隆 centos虚拟机后修改克隆后的机器的ip、mac、uuid失败的问题
    多层表达式
    条件过滤
    复杂表达式
    生成列表
    迭代dict的key和value
    迭代dict的value
    索引迭代
  • 原文地址:https://www.cnblogs.com/hezhh/p/5378975.html
Copyright © 2020-2023  润新知