這兩天項目需要寫一個樹形幫助,學習了我們項目組的老師的Ztree的樹的寫法,實現了這個幫助,下面來總結一下Ztree的用法。
(也是參考的一篇csdn上的博客了)
zTree 是一個依靠 jQuery 實現的多功能 “樹插件”。被廣泛應用在系統的權限管理中,本文講解zTree的一般應用
zTree 官網 http://www.treejs.cn/v3/main.php#_zTreeInfo
1、zTree 官網下載 ztree

下載好后放到項目相關目錄下

2、編寫相關代碼
引入相關js 、 css 文件,代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script type="text/javascript" src="js/jquery-3.2.1.min.js" ></script> <link rel="stylesheet" href="ztree/css/metroStyle/metroStyle.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="ztree/js/jquery.ztree.all.min.js" ></script> </head> <body> </body> </html>
上述代碼中的 css 還可以引入如下兩種、它們分別具有不同的樣式
<link rel="stylesheet" href="ztree/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" type="text/css" />
或
<link rel="stylesheet" href="ztree/css/awesomeStyle/awesome.css" rel="stylesheet" type="text/css" />
快速實現一個簡單的樹,請看如下代碼,相關配置說明已寫在代碼中
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript" src="js/jquery-3.2.1.min.js" ></script>
<link rel="stylesheet" href="ztree/css/metroStyle/metroStyle.css" rel="stylesheet" type="text/css" />
<!--
其他兩種css風格樣式
<link rel="stylesheet" href="ztree/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="ztree/css/awesomeStyle/awesome.css" rel="stylesheet" type="text/css" />
-->
<script type="text/javascript" src="ztree/js/jquery.ztree.all.min.js" ></script>
</head>
<body>
<div>
<ul id="treeDemo" class="ztree"></ul>
</div>
<script>
var settingss = {
data: {
simpleData: {
enable: true, //true 、 false 分別表示 使用 、 不使用 簡單數據模式
idKey: "id", //節點數據中保存唯一標識的屬性名稱
pIdKey: "parentId", //節點數據中保存其父節點唯一標識的屬性名稱
rootPId: -1 //用於修正根節點父節點數據,即 pIdKey 指定的屬性值
},
key: {
name: "menuName" //zTree 節點數據保存節點名稱的屬性名稱 默認值:"name"
}
},
check:{
enable:true, //true 、 false 分別表示 顯示 、不顯示 復選框或單選框
nocheckInherit:true //當父節點設置 nocheck = true 時,設置子節點是否自動繼承 nocheck = true
}
};
//數據
var zNodes = [
//注意,數據中的 menuName 必須與 settingss 中key 中定義的name一致,否則找不到
{menuName:"父節點1", open:true, children:[
{menuName:"子節點1"}, {menuName:"子節點2"}]},
{menuName:"父節點2", open:true, children:[
{menuName:"子節點3"}, {menuName:"子節點4"}]}
];
zTreeObj = $.fn.zTree.init($("#treeDemo"), settingss, zNodes); //初始化樹
zTreeObj.expandAll(true); //true 節點全部展開、false節點收縮
</script>
</body>
</html>
運行效果如下圖

3、使用ajax獲取數據
實際項目開發中,數據往往是從后台服務器獲取的,而不是在前端寫死的。如何實現ajax獲取數據,請看如下代碼
數據庫表結構及數據如下

后台接口代碼如下
mapper層
import java.util.List;
import org.apache.ibatis.annotations.Select;
import com.che.pri.bean.MenuTest;
public interface MenuTestMapper {
@Select("select id as id, parent_id as parentId, menu_name as menuName from menu_test")
List<MenuTest> getMenuTestList();
}
controller層
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.che.pri.mapper.MenuTestMapper;
@Controller
public class MenuTestController {
@Autowired
private MenuTestMapper menuTestMapper;
@ResponseBody
@RequestMapping("/getMenuTestList")
public Object getMenuTestList() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("menulists", menuTestMapper.getMenuTestList());
return map;
}
}
html代碼如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript" src="js/jquery-3.2.1.min.js" ></script>
<link rel="stylesheet" href="ztree/css/metroStyle/metroStyle.css" rel="stylesheet" type="text/css" />
<!--
其他兩種css風格樣式
<link rel="stylesheet" href="ztree/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="ztree/css/awesomeStyle/awesome.css" rel="stylesheet" type="text/css" />
-->
<script type="text/javascript" src="ztree/js/jquery.ztree.all.min.js" ></script>
</head>
<body>
<div>
<ul id="treeDemo" class="ztree"></ul>
</div>
<script>
var settingss = {
data: {
simpleData: {
enable: true, //true 、 false 分別表示 使用 、 不使用 簡單數據模式
idKey: "id", //節點數據中保存唯一標識的屬性名稱
pIdKey: "parentId", //節點數據中保存其父節點唯一標識的屬性名稱
rootPId: -1 //用於修正根節點父節點數據,即 pIdKey 指定的屬性值
},
key: {
name: "menuName" //zTree 節點數據保存節點名稱的屬性名稱 默認值:"name"
}
},
check:{
enable:true, //true 、 false 分別表示 顯示 、不顯示 復選框或單選框
nocheckInherit:true //當父節點設置 nocheck = true 時,設置子節點是否自動繼承 nocheck = true
}
};
$(document).ready(function(){
$.ajax({
type:"get",
url:"http://localhost:8089/getMenuTestList",
async:true,
success:function(res){
zTreeObj = $.fn.zTree.init($("#treeDemo"), settingss, res.menulists); //初始化樹
zTreeObj.expandAll(true); //true 節點全部展開、false節點收縮
}
});
});
</script>
</body>
</html>
運行效果如下

4、設置默認選中節點
在開發中,有時我們需要默認選中一些節點。比如修改用戶角色或權限時,就會有這樣的需求,如何對ztree的節點進行默認選中,請看如下代碼
var node = zTreeObj.getNodeByParam("id", 7);
zTreeObj.checkNode(node, true, false);
通過每一條節點數據的 id 進行設置
具體看如下代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript" src="js/jquery-3.2.1.min.js" ></script>
<link rel="stylesheet" href="ztree/css/metroStyle/metroStyle.css" rel="stylesheet" type="text/css" />
<!--
其他兩種css風格樣式
<link rel="stylesheet" href="ztree/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="ztree/css/awesomeStyle/awesome.css" rel="stylesheet" type="text/css" />
-->
<script type="text/javascript" src="ztree/js/jquery.ztree.all.min.js" ></script>
</head>
<body>
<div>
<ul id="treeDemo" class="ztree"></ul>
</div>
<script>
var settingss = {
data: {
simpleData: {
enable: true, //true 、 false 分別表示 使用 、 不使用 簡單數據模式
idKey: "id", //節點數據中保存唯一標識的屬性名稱
pIdKey: "parentId", //節點數據中保存其父節點唯一標識的屬性名稱
rootPId: -1 //用於修正根節點父節點數據,即 pIdKey 指定的屬性值
},
key: {
name: "menuName" //zTree 節點數據保存節點名稱的屬性名稱 默認值:"name"
}
},
check:{
enable:true, //true 、 false 分別表示 顯示 、不顯示 復選框或單選框
nocheckInherit:true //當父節點設置 nocheck = true 時,設置子節點是否自動繼承 nocheck = true
}
};
$(document).ready(function(){
$.ajax({
type:"get",
url:"http://localhost:8089/getMenuTestList",
async:true,
success:function(res){
zTreeObj = $.fn.zTree.init($("#treeDemo"), settingss, res.menulists); //初始化樹
zTreeObj.expandAll(true); //true 節點全部展開、false節點收縮
//設置選中節點
var node = zTreeObj.getNodeByParam("id", 7);
zTreeObj.checkNode(node, true, false);
var node = zTreeObj.getNodeByParam("id", 1);
zTreeObj.checkNode(node, true, false);
var node = zTreeObj.getNodeByParam("id", 4);
zTreeObj.checkNode(node, true, false);
}
});
});
</script>
</body>
</html>
運行效果

其他內容可參考官網API
在這里聲明一下版權
————————————————
版權聲明:本文為CSDN博主「悟世君子」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/wsjzzcbq/article/details/83029532
以上都是學習人家寫的內容了,我介紹一下我在項目中對Ztree的一些理解。
首先,我需要寫一個js讓我跳到我想選擇的樹的頁面里面去,並且從樹的頁面里面獲取到我所需要的返回值。
// 選擇員工
function selectDeviceType() {
var msg = "選擇人員";
$.dialog({
type: 'iframe',
url: context + "/jsp/genersoft/public/health/HealthRyDepartment.jsp",
title: msg,
width: 580,
height: 400,
onclose: function () {
var nodes = this.returnValue;
$("#healthUserId").val(nodes[0].ORGAN_ID);
$("#username").val(nodes[0].ORGAN_NAME);
$("#healthOrgId").val(nodes[0].GRANDPA_ID);
$("#departmentname").val(nodes[0].GRANDPA_NAME);
$("#username").change();
}
});
}
接下來,就是我們選擇幫助的頁面,在這個頁面里,需要初始化一下Ztree,構造一下Ztree的數據屬性,寫個ajax,給他一個后台的url,讓他查數據,返回到前台來,再構造這個樹。
事先需要引一些js
<script type="text/javascript" src="<l:asset path='jquery.js'/>"></script>
<script type="text/javascript" src="<l:asset path='bootstrap.js'/>"></script>
<script type="text/javascript" src="<l:asset path='form.js'/>"></script>
<script type="text/javascript" src="<l:asset path='ui.js'/>"></script>
<script type="text/javascript" src="<l:asset path='loushang-framework.js'/>"></script>
<script type="text/javascript" src="<l:asset path='i18n.js'/>"></script>
<script type="text/javascript" src="<l:asset path='ztree.js'/>"></script>
然后,初始化Ztree,構造這個樹。
<SCRIPT LANGUAGE="JavaScript">
var context = "<l:assetcontext/>";
var dialog = parent.dialog.get(window);
var zTreeObj;
var setting = {
check: {
enable: true,
chkStyle: "radio",
radioType: "all",
chkboxType: {"Y": "s", "N": "s"}
}
};
function filter(treeId, parentNode, childNodes) {
if (!childNodes) return null;
for (var i = 0, l = childNodes.length; i < l; i++) {
childNodes[i].name = childNodes[i].name.replace(/\.n/g, '.');
}
return childNodes;
}
// zTree 的數據屬性,深入使用請參考 API 文檔(zTreeNode 節點數據詳解)
var zNodes = [
{
name: "test1",
open: true,
children: [
{
name:"test1_1",
open:true,
children: [
{name: "test1_1_1"},
{name: "test1_1_2"}
]
},
{
name:"test1_2",
open:true,
children: [
{name: "test1_2_1"},
{name: "test1_2_2"}
]
},
]
},
{
name: "test2",
open: true,
children: [
{
name:"test2_1",
open:true,
children: [
{name: "test2_1_1"},
{name: "test2_1_2"}
]
},
{
name:"test2_2",
open:true,
children: [
{name: "test2_2_1"},
{name: "test2_2_2"}
]
},
]
},
];
$(document).ready(function () {
$.ajax({
type: "POST",
url: context + "/service/health/treeData2",
data: {},
dataType: "json",
aysn: false,
success: function (respMsg) {
zNodes = respMsg;
zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes);
var node = zTreeObj.getNodeByParam("name", '${param.name}', null);
if (node){//判斷有查詢到節點
//方法一:
// $("#"+node.tId+"_a").click();//點擊查詢到的節點
//方法二:
zTreeObj.selectNode(node,true);//選
// node.checked = true;
// zTreeObj.updateNode(node);
}}
});
// var zTreeMenu = $.fn.zTree.getZTreeObj("treeDemo");//根據treeID(zTree的DOM容器的id)獲取
//zTree對象的方法,必須初始化zTree才可以使用此方法
// var treeObj = $.fn.zTree.getZTreeObj("tree");
// var node = zTreeObj.getNodeByParam("id", 1, null);
// var node=zTreeObj.getNodeByParam('name',,null);
// 確定按鈕
$("#confirm").click(function () {
confirm();
});
// 取消按鈕
$("#clear").click(function () {
clear();
});
});
// 確定按鈕
function confirm() {
var msg = L.getLocaleMessage("bsp.organ.053", "請選擇單個節點!");
var selectedNodes = zTreeObj.getCheckedNodes();
if (selectedNodes.length != 1) {
$.sticky(msg, {
autoclose: 1000,
position: "center",
style: "warning"
});
return false;
}
if(selectedNodes["0"].STRU_LEVEL!="4"){
$.sticky("請選擇職工", {
autoclose: 1000,
position: "center",
style: "warning"
});
return false;
}
dialog.close(selectedNodes);
dialog.remove();
}
// 取消
function clear() {
var dialog = parent.dialog.get(window);
dialog.close("clear");
dialog.remove();
return false;
}
</SCRIPT>
</HEAD>
<BODY>
<div>
<ul id="treeDemo" class="ztree"></ul>
<div class="foot">
<div class="btnGroup">
<button id="confirm" type="button" class="btn ue-btn"><spring:message code="bsp.organ.046"
text="確定"/></button>
<button id="clear" type="button" class="btn ue-btn"><spring:message code="bsp.organ.048"
text="清除"/></button>
</div>
</div>
</div>
</BODY>
</HTML>
跳后台url,並對數據做一下拼接。
Contrller層
@Controller
@RequestMapping(value = "/health")
public class HealthController {
@Autowired
private IHealthService healthService;
/**
* 列表跳轉頁面
*
* @return 列表頁面
*/
@RequestMapping
public String queryHealth() {
return "genersoft/public/health/healthQuery";
}
@RequestMapping({"/treeData2"})
@ResponseBody
public List treeData2(HttpServletRequest req) {
return healthService.getTypeTreeData2("");
}
}
Service層
@Service("healthService")
public class HealthServiceImpl implements IHealthService{
@Autowired
private HealthMapper healthMapper;
@Override
@Override
public List getTypeTreeData2(String struId) {
// TODO Auto-generated method stub
List<Map<String,Object>> list = healthMapper.getTreeData2();
List<Map> resList = new ArrayList<>();
//單位list
List<Map<String,Object>> UnitList=new ArrayList<Map<String,Object>>();
//部門list
List<Map<String,Object>> DepartmentList=new ArrayList<Map<String,Object>>();
//崗位list
List<Map<String,Object>> PostList=new ArrayList<Map<String,Object>>();
//人員list
List<Map<String,Object>> PersonList=new ArrayList<Map<String,Object>>();
for(Map<String,Object> unit:list) {
if(Integer.parseInt(String.valueOf(unit.get("STRU_LEVEL")))==1) {
UnitList.add(unit);
}
}
for(Map<String,Object> department:list) {
if(Integer.parseInt(String.valueOf(department.get("STRU_LEVEL")))==2) {
DepartmentList.add(department);
}
}
for(Map<String,Object> post:list) {
if(Integer.parseInt(String.valueOf(post.get("STRU_LEVEL")))==3) {
PostList.add(post);
}
}
for(Map<String,Object> person:list) {
if(Integer.parseInt(String.valueOf(person.get("STRU_LEVEL")))==4) {
PersonList.add(person);
}
}
List<Map<String, Object>> temp1List=new ArrayList<Map<String, Object>>();
List<Map<String, Object>> temp3List=new ArrayList<Map<String, Object>>();
List<Map<String, Object>> temp5List=new ArrayList<Map<String, Object>>();
for(Map<String,Object> temp6:DepartmentList) {
for(Map<String, Object> temp1:PostList) {
List<Map<String,Object>> greatgrandsonList=new ArrayList<Map<String,Object>>();
greatgrandsonList.clear();
for(Map<String,Object> temp2:PersonList) {
if(temp2.get("PARENT_ID").equals(temp1.get("ORGAN_ID"))) {
temp2.put("name",temp2.get("ORGAN_NAME"));
temp2.put("PARENT_NAME", temp1.get("ORGAN_NAME"));
if(temp1.get("PARENT_ID").equals(temp6.get("ORGAN_ID"))) {
temp2.put("GRANDPA_ID", temp6.get("ORGAN_ID"));
temp2.put("GRANDPA_NAME", temp6.get("ORGAN_NAME"));
}
greatgrandsonList.add(temp2);
}
}
temp1.put("children", greatgrandsonList);
temp1List.add(temp1);
}
}
System.out.println(temp1List);
System.out.println(1);
for(Map<String,Object> temp3:DepartmentList) {
List<Map<String,Object>> grandsonList=new ArrayList<Map<String,Object>>();
grandsonList.clear();
for(Map<String,Object> temp4:PostList) {
if(temp4.get("PARENT_ID").equals(temp3.get("ORGAN_ID"))) {
temp4.put("name",temp4.get("ORGAN_NAME"));
temp4.put("PARENT_NAME", temp3.get("ORGAN_NAME"));
grandsonList.add(temp4);
}
}
temp3.put("children", grandsonList);
//System.out.println(temp3);
temp3List.add(temp3);
}
System.out.println(temp3List);
System.out.println(1);
for(Map<String,Object> temp5:UnitList) {
List<Map<String,Object>> sonList=new ArrayList<Map<String,Object>>();
temp5.put("name",temp5.get("ORGAN_NAME"));
sonList.clear();
for(Map<String,Object> temp6:DepartmentList) {
if(temp6.get("PARENT_ID").equals(temp5.get("ORGAN_ID"))) {
temp6.put("name",temp6.get("ORGAN_NAME"));
temp6.put("PARENT_NAME", temp5.get("ORGAN_NAME"));
sonList.add(temp6);
}
}
temp5.put("children", sonList);
//System.out.println(temp5);
temp5List.add(temp5);
}
System.out.println(temp5List);
resList.addAll(temp5List);
return resList;
}
}
這個地方有幾個點需要注意一下:
1.讓他返回成一個父親節點帶着一個子節點的數據格式,要對數據進行一個拼接,返回數據的格式是如下的形式
[{STRU_ID=1, ORGAN_ID=1,
children=[{STRU_ID=2, ORGAN_ID=2,
children=[{STRU_ID=3, ORGAN_ID=3,
children=[{STRU_ID=4, GRANDPA_ID=2, ORGAN_ID=4, PARENT_NAME=崗位, name=a, STRU_LEVEL=4, ORGAN_NAME=a,
PARENT_ID=3, GRANDPA_NAME=2}]
}]
}]
}]
他的下一層規定寫為children,這個是Ztree的數據屬性,最好寫死寫成children。
2.在后台拼接的時候,需要給每個節點的name屬性附上值
temp5.put("name",temp5.get("ORGAN_NAME"));
如果不給name賦值,則在前台顯示的時候會出現undefined的情況。
3.然后是獲取選擇節點的屬性值的方法,如下:
var selectedNodes = zTreeObj.getCheckedNodes();
其他的就沒什么了,that's all,暫時寫到這,想起來再補充。
