Jquery-zTree学习笔记

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) "" 是必需的!
    2) zTree 的容器 className 别忘了设置为 "ztree"

<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() {
            @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() {
            @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.
     * 

* 如果JSON字符串为Null或"null"字符串, 返回Null. * 如果JSON字符串为"[]", 返回空集合. *

* 如需反序列化复杂Collection如List, 请使用fromJson(String,JavaType) * * @see #fromJson(String, JavaType) */ public T fromJson(String jsonString, Class 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, 先使用函數createCollectionType构造类型,然后调用本函数. * * @see #createCollectionType(Class, Class...) */ @SuppressWarnings("unchecked") public 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, 则调用constructCollectionType(ArrayList.class,MyBean.class) * HashMap, 则调用(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 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> list = Lists.newArrayList(); Map 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 gradeTree = createGradeTree();
            model.addAttribute("gradeTree", JsonMapper.toJsonString(gradeTree));

JSP:

                "gradeName" readonly="true" placeholder="请选择"
                            onclick="showView(this.id)" cssStyle="width:80px;height:30px;"/>
                <div id="z_menuContent" class="menuContent"
                     style="display: none; position: fixed;">
                    
    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;">
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":"初中"}]

你可能感兴趣的:(前端)