Jquery-zTree學習筆記
阿新 • • 發佈:2019-02-12
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":"初中"}]