Jquery-zTree学习笔记

来源:互联网 发布:哈利波特怪味糖淘宝 编辑:程序博客网 时间:2024/05/21 12:48

zTree 简介
zTree 是一个依靠 jQuery 实现的多功能 “树插件”。优异的性能、灵活的配置、多种功能的组合是 zTree 最大优点。

zTree v3.0 将核心代码按照功能进行了分割,不需要的代码可以不用加载采用了 延迟加载 技术,上万节点轻松加载,即使在 IE6 下也能基本做到秒杀兼容 IE、FireFox、Chrome、Opera、Safari 等浏览器支持 JSON 数据支持静态 和 Ajax 异步加载节点数据支持任意更换皮肤 / 自定义图标(依靠css)支持极其灵活的 checkbox 或 radio 选择功能提供多种事件响应回调灵活的编辑(增/删/改/查)功能,可随意拖拽节点,还可以多节点拖拽哟在一个页面内可同时生成多个 Tree 实例简单的参数配置实现 灵活多变的功能

步骤 1、文件准备

将需要使用的 zTree v3.x 相关的 js、css、img 文件分别放置到相应目录,并且保证相对路径正确

步骤 2、编写 html 页面

按照以下代码,制作 html/jsp 页面,访问试试看吧,注意:    1) "<!DOCTYPE html>" 是必需的!    2) zTree 的容器 className 别忘了设置为 "ztree"
<!DOCTYPE html><HTML> <HEAD>  <TITLE> ZTREE DEMO </TITLE>  <meta http-equiv="content-type" content="text/html; charset=UTF-8">  <link rel="stylesheet" href="demoStyle/demo.css" type="text/css">  <link rel="stylesheet" href="zTreeStyle/zTreeStyle.css" type="text/css">  <script type="text/javascript" src="jquery-1.4.2.js"></script>  <script type="text/javascript" src="jquery.ztree.core-3.x.js"></script>  <SCRIPT LANGUAGE="JavaScript">   var zTreeObj;   // zTree 的参数配置,深入使用请参考 API 文档(setting 配置详解)   var setting = {};   // zTree 的数据属性,深入使用请参考 API 文档(zTreeNode 节点数据详解)   var zNodes = [   {name:"test1", open:true, children:[      {name:"test1_1"}, {name:"test1_2"}]},   {name:"test2", open:true, children:[      {name:"test2_1"}, {name:"test2_2"}]}   ];   $(document).ready(function(){      zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes);   });  </SCRIPT> </HEAD><BODY><div>   <ul id="treeDemo" class="ztree"></ul></div></BODY></HTML>

一般来说zNodes都是拼接成的,要么在后台拼接好要么在页面拼接,当父子节点量比较大的,手动拼接是很麻烦的,下面提供由大牛ThinkGem写的一个封装类,实现JSON String<->Java Object的Mapper

package com.andone.common.mapper;import com.fasterxml.jackson.annotation.JsonInclude.Include;import com.fasterxml.jackson.core.JsonGenerator;import com.fasterxml.jackson.core.JsonParser.Feature;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.*;import com.fasterxml.jackson.databind.module.SimpleModule;import com.fasterxml.jackson.databind.util.JSONPObject;import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;import com.google.common.collect.Lists;import com.google.common.collect.Maps;import net.sf.json.JSONObject;import org.apache.commons.lang3.StringEscapeUtils;import org.apache.commons.lang3.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.IOException;import java.util.List;import java.util.Map;import java.util.TimeZone;/** * 简单封装Jackson,实现JSON String<->Java Object的Mapper. * 封装不同的输出风格, 使用不同的builder函数创建实例. * * @author ThinkGem * @version 2013-11-15 */public class JsonMapper extends ObjectMapper {    private static final long serialVersionUID = 1L;    private static Logger logger = LoggerFactory.getLogger(JsonMapper.class);    private static JsonMapper mapper;    public JsonMapper() {        this(Include.NON_EMPTY);    }    public JsonMapper(Include include) {        // 设置输出时包含属性的风格        if (include != null) {            this.setSerializationInclusion(include);        }        // 允许单引号、允许不带引号的字段名称        this.enableSimple();        // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性        this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);        // 空值处理为空串        this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {            @Override            public void serialize(Object value, JsonGenerator jgen,                                  SerializerProvider provider) throws IOException,                    JsonProcessingException {                jgen.writeString("");            }        });        // 进行HTML解码。        this.registerModule(new SimpleModule().addSerializer(String.class, new JsonSerializer<String>() {            @Override            public void serialize(String value, JsonGenerator jgen,                                  SerializerProvider provider) throws IOException,                    JsonProcessingException {                jgen.writeString(StringEscapeUtils.unescapeHtml4(value));            }        }));        // 设置时区        this.setTimeZone(TimeZone.getDefault());//getTimeZone("GMT+8:00")    }    /**     * 创建只输出非Null且非Empty(如List.isEmpty)的属性到Json字符串的Mapper,建议在外部接口中使用.     */    public static JsonMapper getInstance() {        if (mapper == null) {            mapper = new JsonMapper().enableSimple();        }        return mapper;    }    /**     * 创建只输出初始值被改变的属性到Json字符串的Mapper, 最节约的存储方式,建议在内部接口中使用。     */    public static JsonMapper nonDefaultMapper() {        if (mapper == null) {            mapper = new JsonMapper(Include.NON_DEFAULT);        }        return mapper;    }    /**     * Object可以是POJO,也可以是Collection或数组。     * 如果对象为Null, 返回"null".     * 如果集合为空集合, 返回"[]".     */    public String toJson(Object object) {        try {            return this.writeValueAsString(object);        } catch (IOException e) {            logger.warn("write to json string error:" + object, e);            return null;        }    }    /**     * 反序列化POJO或简单Collection如List<String>.     * <p>     * 如果JSON字符串为Null或"null"字符串, 返回Null.     * 如果JSON字符串为"[]", 返回空集合.     * <p>     * 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String,JavaType)     *     * @see #fromJson(String, JavaType)     */    public <T> T fromJson(String jsonString, Class<T> clazz) {        if (StringUtils.isEmpty(jsonString)) {            return null;        }        try {            return this.readValue(jsonString, clazz);        } catch (IOException e) {            logger.warn("parse json string error:" + jsonString, e);            return null;        }    }    /**     * 反序列化复杂Collection如List<Bean>, 先使用函數createCollectionType构造类型,然后调用本函数.     *     * @see #createCollectionType(Class, Class...)     */    @SuppressWarnings("unchecked")    public <T> T fromJson(String jsonString, JavaType javaType) {        if (StringUtils.isEmpty(jsonString)) {            return null;        }        try {            return (T) this.readValue(jsonString, javaType);        } catch (IOException e) {            logger.warn("parse json string error:" + jsonString, e);            return null;        }    }    /**     * 構造泛型的Collection Type如:     * ArrayList<MyBean>, 则调用constructCollectionType(ArrayList.class,MyBean.class)     * HashMap<String,MyBean>, 则调用(HashMap.class,String.class, MyBean.class)     */    public JavaType createCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {        return this.getTypeFactory().constructParametricType(collectionClass, elementClasses);    }    /**     * 當JSON裡只含有Bean的部分屬性時,更新一個已存在Bean,只覆蓋該部分的屬性.     */    @SuppressWarnings("unchecked")    public <T> T update(String jsonString, T object) {        try {            return (T) this.readerForUpdating(object).readValue(jsonString);        } catch (JsonProcessingException e) {            logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);        } catch (IOException e) {            logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);        }        return null;    }    /**     * 輸出JSONP格式數據.     */    public String toJsonP(String functionName, Object object) {        return toJson(new JSONPObject(functionName, object));    }    /**     * 設定是否使用Enum的toString函數來讀寫Enum,     * 為False時時使用Enum的name()函數來讀寫Enum, 默認為False.     * 注意本函數一定要在Mapper創建後, 所有的讀寫動作之前調用.     */    public JsonMapper enableEnumUseToString() {        this.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);        this.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);        return this;    }    /**     * 支持使用Jaxb的Annotation,使得POJO上的annotation不用与Jackson耦合。     * 默认会先查找jaxb的annotation,如果找不到再找jackson的。     */    public JsonMapper enableJaxbAnnotation() {        JaxbAnnotationModule module = new JaxbAnnotationModule();        this.registerModule(module);        return this;    }    /**     * 允许单引号     * 允许不带引号的字段名称     */    public JsonMapper enableSimple() {        this.configure(Feature.ALLOW_SINGLE_QUOTES, true);        this.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);        return this;    }    /**     * 取出Mapper做进一步的设置或使用其他序列化API.     */    public ObjectMapper getMapper() {        return this;    }    /**     * 对象转换为JSON字符串     *     * @param object     * @return     */    public static String toJsonString(Object object) {        return JsonMapper.getInstance().toJson(object);    }    /**     * JSON字符串转换为对象     *     * @param jsonString     * @param clazz     * @return     */    public static Object fromJsonString(String jsonString, Class<?> clazz) {        return JsonMapper.getInstance().fromJson(jsonString, clazz);    }    /**     * 测试     */    public static void main(String[] args) {        List<Map<String, Object>> list = Lists.newArrayList();        Map<String, Object> map = Maps.newHashMap();        map.put("id", 1);        map.put("pId", -1);        map.put("name", "根节点");        list.add(map);        map = Maps.newHashMap();        map.put("id", 2);        map.put("pId", 1);        map.put("name", "你好");        map.put("open", true);        list.add(map);        String json = JsonMapper.getInstance().toJson(list);        System.out.println(json);        Object o = JsonMapper.getInstance().fromJson(json, JSONObject.class);        System.out.println(o);    }}

具体使用—————————————–

controller层:

 List<TreeNode> gradeTree = createGradeTree();            model.addAttribute("gradeTree", JsonMapper.toJsonString(gradeTree));

JSP:

                <form:input path="gradeName" readonly="true" placeholder="请选择"                            onclick="showView(this.id)" cssStyle="width:80px;height:30px;"/>                <div id="z_menuContent" class="menuContent"                     style="display: none; position: fixed;">                    <ul id="z_treeDemo" class="ztree"                        style="margin-top: 0; border: 1px solid #617775; background: #f0f6e4; width: 180px; height: 200px; overflow-y: auto; overflow-x: auto;"></ul>                </div>

JS:

//年级树形下拉框   √        function beforeClick(treeId, treeNode) {            return (treeNode && !treeNode.isParent);        }        function treeClick(e, treeId, treeNode) {            if (treeId == 'z_treeDemo') {                //获取当前节点的名称                var pName = treeNode.name;                $("#gradeName").attr("value", pName);                //为年级编号赋值                $("#gradeId").attr("value", treeNode.id);                selectClass(pName);                z_hideView();            }        }        function showView(id) {            if (id == 'gradeName') {                var cityObj = $("#" + id);                $("#z_menuContent").css({                    left: cityObj.offset().left + "px",                    top: cityObj.offset().top + cityObj.outerHeight() + "px"                }).slideDown("fast");                $("body").bind("mousedown", z_onBodyDown);            }        }        function z_hideView() {            $("#z_menuContent").fadeOut("fast");            $("body").unbind("mousedown", z_onBodyDown);        }        function z_onBodyDown(event) {            if (!(event.target.id == "menuBtn" || event.target.id == "z_menuContent"                || $(event.target).parents("#z_menuContent").length > 0)) {                z_hideView();            }        }

父子节点关系从数据库获取存放在对象集合中,转化后变成如下:

[{"id":"30319","pId":"-1","name":"小学","code":"小学"},{"id":"30320","pId":"-1","name":"初中","code":"初中"},{"id":"69629","pId":"30319","name":"毕业班","code":"小学"},{"id":"69630","pId":"30320","name":"毕业班","code":"初中"},{"id":"29963","pId":"30319","name":"小学一年级","code":"小学"},{"id":"29964","pId":"30319","name":"小学二年级","code":"小学"},{"id":"29965","pId":"30319","name":"小学三年级","code":"小学"},{"id":"29966","pId":"30319","name":"小学四年级","code":"小学"},{"id":"29967","pId":"30319","name":"小学五年级","code":"小学"},{"id":"29968","pId":"30319","name":"小学六年级","code":"小学"},{"id":"29969","pId":"30320","name":"初中三年级","code":"初中"},{"id":"29970","pId":"30320","name":"初中二年级","code":"初中"},{"id":"29971","pId":"30320","name":"初中一年级","code":"初中"}]
原创粉丝点击