ztree使用教程 异步

时间:2022-03-22 12:40:27

ztree用了有一段时间了,使用心得,很好很强大。现在就来给大家分享一下。

先说下完成的主要功能:异步加载ztree,还有实现数的拖拽,以及实现右键菜单功能,但是因为时间原因,菜单功能没有实现,如果感兴趣,可以自己进行完善。

1、首先就是造数据了,我现在以地区为例,建表ztree,数据如下:

ztree使用教程 异步

2、为了简单期间,我使用servlet进行搭建,先看下项目结构:

ztree使用教程 异步

下面贴出代码:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>ZtreeServlet</servlet-name>
    <servlet-class>com.wtf.servlet.ZtreeServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>ZtreeServlet</servlet-name>
    <url-pattern>/ztreeServlet</url-pattern>
  </servlet-mapping>

</web-app>

实体类Area.java

package com.wtf.model;

public class Area {

	private String id;
	private String name;
	private String preantsId;
	private Integer isParent;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPreantsId() {
		return preantsId;
	}

	public void setPreantsId(String preantsId) {
		this.preantsId = preantsId;
	}

	public Integer getIsParent() {
		return isParent;
	}

	public void setIsParent(Integer isParent) {
		this.isParent = isParent;
	}

	public Area(String id, String name, String preantsId, Integer isParent) {
		super();
		this.id = id;
		this.name = name;
		this.preantsId = preantsId;
		this.isParent = isParent;
	}

	public Area() {
		super();
		// TODO Auto-generated constructor stub
	}

}
dao层使用了原生的jdbc

package com.wtf.dao;

public class ZtreeDao {
	public static Connection connection = null;
	public static PreparedStatement ps  = null;
	public static ResultSet rs = null;

	static{
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		try {
			connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public List<Area> getList() throws ClassNotFoundException, SQLException{
		String sql = "select * from ztree";
		ps = connection.prepareStatement(sql);
		rs = ps.executeQuery();
		List<Area> list = new ArrayList<Area>();
		while(rs.next()){
			Area area = new Area();
			area.setId(rs.getString(1));
			area.setName(rs.getString(2));
			area.setPreantsId(rs.getString(3));
			area.setIsParent(rs.getInt(4));
			list.add(area);
		}
		return list;
	}
	public List<Area> getListByParentsId(String parentsId) throws ClassNotFoundException, SQLException{
		String sql = "select * from ztree where parentsId = ?";
		ps = connection.prepareStatement(sql);
		ps.setString(1, parentsId);
		rs = ps.executeQuery();
		List<Area> list = new ArrayList<Area>();
		while(rs.next()){
			Area area = new Area();
			area.setId(rs.getString(1));
			area.setName(rs.getString(2));
			area.setPreantsId(rs.getString(3));
			area.setIsParent(rs.getInt(4));
			list.add(area);
		}
		return list;
	}
	
	public void updatePNode(String id, Integer isParent) throws SQLException{
		String sql = "update ztree set isParent = ? where id = ?";
		ps = connection.prepareStatement(sql);
		ps.setInt(1, isParent);
		ps.setString(2, id);
		ps.executeUpdate();
	}
	
	public void moveNode(String id, String parentsId, Integer isParent) throws SQLException{
		String sql = "update ztree set parentsId = ?,isParent = ? where id = ?";
		ps = connection.prepareStatement(sql);
		ps.setString(1, parentsId);
		ps.setInt(2, isParent);
		ps.setString(3, id);
		ps.executeUpdate();
	}
	
	public Area getAreaById(Integer id) throws SQLException{
		String sql = "select * from ztree where id = ?";
		ps = connection.prepareStatement(sql);
		ps.setInt(1, id);
		rs = ps.executeQuery();
		Area area = new Area();
		while(rs.next()){
			area.setId(rs.getString(1));
			area.setName(rs.getString(2));
			area.setPreantsId(rs.getString(3));
			area.setIsParent(rs.getInt(4));
		}
		return area;
	}

}
控制层使用的servlet,我使用了两种方法对json串进行封装,一个是手动,另一个使用jackson 进行封装

package com.wtf.servlet;

public class ZtreeServlet extends HttpServlet {
	
	private ZtreeDao dao = new ZtreeDao();
	private ObjectMapper objectMapper = new ObjectMapper();

	public ZtreeServlet() {
		super();
	}
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html");
		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		
		String action = request.getParameter("action");
		if("getTree".equals(action)){
			getTree2(request, response);
			//getTree(request, response);
		}else if("showInfo".equals(action)){
			showInfo(request, response);
		}else if("moveNode".equals(action)){
			try {
				moveNode(request, response);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private void moveNode(HttpServletRequest request,HttpServletResponse response) throws SQLException, JsonGenerationException, JsonMappingException, IOException, ClassNotFoundException {
		String id = request.getParameter("id");
		String targetId = request.getParameter("targetId");
		String moveType = request.getParameter("moveType");
		System.out.println(moveType);
		Area area = dao.getAreaById(Integer.parseInt(targetId));
		Integer isParent = area.getIsParent();
		//如果该节点的父节点不是父节点,变为父节点
		if(isParent.equals(1)){
			dao.updatePNode(targetId, 0);
		}
		//修改该节点
		Area area2 = dao.getAreaById(Integer.parseInt(id));
		dao.moveNode(id, targetId, area2.getIsParent());
		//如果该节点原来的父节点下没有子节点,将其修改为子节点
		List<Area> areas = dao.getListByParentsId(area2.getPreantsId());
		if(areas.size() <= 0){
			dao.updatePNode(area2.getPreantsId(), 1);
		}
		String str = "success";
		PrintWriter out = response.getWriter();
		out.print(str);
		
		
	}
	private void showInfo(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String treeId = request.getParameter("treeId");
		PrintWriter out = response.getWriter();
		out.print(treeId);
		//request.setAttribute("ztreeId", treeId);
	}

	private void getTree2(HttpServletRequest request, HttpServletResponse response) throws IOException {
		PrintWriter out = response.getWriter();
		List<Area> list = null;
		try {
			list = dao.getList();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		if(list.size() > 0){
			ObjectMapper objectMapper = new ObjectMapper();
			String json = "";
			Map<String,Object> map = new HashMap<String, Object>();
			for (Area area : list) {
				if(area.getIsParent().equals(2)){
					map.put("id", area.getId());
					map.put("pId", area.getPreantsId());
					map.put("name", area.getName());
					map.put("isParent", true);
					map.put("open", true);
				}if(area.getIsParent().equals(0)){
					map.put("id", area.getId());
					map.put("pId", area.getPreantsId());
					map.put("name", area.getName());
					map.put("isParent", true);
					map.put("open", false);
				}else if(area.getIsParent().equals(1)){
					map.put("id", area.getId());
					map.put("pId", area.getPreantsId());
					map.put("name", area.getName());
					map.put("isParent", false);
					map.put("open", false);
				}
				json += objectMapper.writeValueAsString(map) + ",";
			}
			String jsonStr = "[ "+ json.substring(0, json.length()-1) +" ]";
			out.print(jsonStr);
			//System.out.println(json);
		}
	}
	
	@SuppressWarnings("unused")
	private void getTree(HttpServletRequest request, HttpServletResponse response) throws IOException {
		PrintWriter out = response.getWriter();
		List<Area> list = null;
		try {
			list = dao.getList();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		if(list.size() > 0){
			ObjectMapper objectMapper = new ObjectMapper();
			String json = objectMapper.writeValueAsString(list);
			String treeStr = "";
			for (Area area : list) {
				if(area.getIsParent().equals(2)){
					treeStr += "{id:'"+ area.getId() +"',pId:'"+ area.getPreantsId() +"',name:'"+ area.getName() +"',isParent:true,open:true},";
				}if(area.getIsParent().equals(0)){
					treeStr += "{id:'"+ area.getId() +"',pId:'"+ area.getPreantsId() +"',name:'"+ area.getName() +"',isParent:true},";
				}else if(area.getIsParent().equals(1)){
					treeStr += "{id:'"+ area.getId() +"',pId:'"+ area.getPreantsId() +"',name:'"+ area.getName() +"',isParent:false},";
				}
			}
			String jsonStr = "[ "+ treeStr.substring(0, treeStr.length()-1) +" ]";
			out.print(jsonStr);
			System.out.println(json);
		}
	}

}
index.html ,引入的js可以从ztree官网进行下载(注:部分代码是从官方原demo里面摘出来的)

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
    <link rel="stylesheet" href="js/zTree_v3-master/css/demo.css" type="text/css">
	<link rel="stylesheet" href="js/zTree_v3-master/css/zTreeStyle/zTreeStyle.css" type="text/css">
	<script type="text/javascript" src="js/zTree_v3-master/js/jquery-1.4.4.min.js"></script>
	<script type="text/javascript" src="js/zTree_v3-master/js/jquery.ztree.all.js"></script>
	<style type="text/css">
	div#rMenu {position:absolute; visibility:hidden; top:0; background-color: #555;text-align: left;padding: 2px;}
	div#rMenu ul li{
		margin: 1px 0;
		padding: 0 5px;
		cursor: pointer;
		list-style: none outside none;
		background-color: #DFDFDF;
	}
	</style>
	<SCRIPT type="text/javascript">
	$(document).ready(function(){
		initTree();
	});
	var setting = {
		data: {
			simpleData: {
				enable: true
			}
		},
		async: {
			enable: true,
			url:"ztreeServlet?action=getTree",
			//autoParam:["id"],
			//otherParam:{},
			dataType: "json",
			type : "post", 
			dataFilter: filter
		},
		callback: {
			onClick: zTreeOnClick, //点击事件
			beforeDrag: beforeDrag, //拖拽之前事件
			beforeDrop: beforeDrop, //拖拽之后事件
			onAsyncSuccess: onAsyncSuccess, //异步加载成功之后事件
			onDragMove: onDragMove,
			onRightClick: OnRightClick
		},
		view: {
			dblClickExpand: dblClickExpand
		},
		edit: {
			enable: true,
			showRemoveBtn: true,
			showRenameBtn: true
		},
	};

	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;
	}
	
	var ZTreeObj;
	var zNodes = null;
	var rMenu;
	function initTree(){
		var url = "ztreeServlet?action=getTree";
		$.ajax({
			url:url,
			data: "",
			type:"POST",
			success:function(zNodes){
				$.fn.zTree.init($("#treeDemo"), setting, eval("(" + zNodes + ")"));
				ZTreeObj = $.fn.zTree.getZTreeObj("treeDemo");
				rMenu = $("#rMenu");
			},
			error: function(){
				alert("初始化功能树失败!");
			}
		});
	}
	
	/* 点击节点事件 */
	function zTreeOnClick(event, treeId, treeNode) {
		var url = "ztreeServlet?action=showInfo";
	    $.ajax({
			url:url,
			data: "treeId="+treeNode.id,
			type:"POST",
			success:function(data){
				$("#id").val(data);
			},
			error: function(){
				alert("初始化功能树失败!");
			}
		});
	};
	
	/* 仅允许节点等级大于0的节点可以双击点开  ,主要针对父节点*/
	function dblClickExpand(treeId, treeNode) {
		return treeNode.level > 0;
	}
	
	//拖拽前执行  
	var dragId;  
	function beforeDrag(treeId, treeNodes) {
       	for (var i=0,l=treeNodes.length; i<l; i++) {  
            dragId = treeNodes[i].pId;  
            if (treeNodes[i].drag === false) {  
                return false;  
           }  
      	}  
       	return true;  
	}  
	 //拖拽释放之后执行  
	function beforeDrop(treeId, treeNodes, targetNode, moveType) {
        var data = {id:treeNodes[0].id,targetId:targetNode.id,moveType:moveType};  
        var confirmVal = false;  
        $.ajax({
	        async: false,  
	        type: "post",  
	        data:data,  
	        url:"ztreeServlet?action=moveNode",  
	        success: function(json){
                if(json=="success" ){
                   	confirmVal = true;  
			ZTreeObj.reAsyncChildNodes(treeNodes, "refresh",false);
                }else{
	 		alert('亲,操作失败');  
                }  
            },  
	        error: function(){
	   		alert('亲,网络有点不给力呀!');  
            }  
        });  
	    return confirmVal;
	}  
	
	function onAsyncSuccess(event, treeId, treeNode, msg){
		var id = treeId;
		alert(id);
	}
	
	//在拖拽过程中的事件
	function onDragMove(event, treeId, treeNodes){
		console.log(event.target); //控制台输出
	}
	
	//右键菜单
	function OnRightClick(event, treeId, treeNode) {
		if (!treeNode && event.target.tagName.toLowerCase() != "button" && $(event.target).parents("a").length == 0) {
			ZTreeObj.cancelSelectedNode();
			showRMenu("root", event.clientX, event.clientY);
		} else if (treeNode && !treeNode.noR) {
			ZTreeObj.selectNode(treeNode);
			showRMenu("node", event.clientX, event.clientY);
		}
	}
	
	function showRMenu(type, x, y) {
		$("#rMenu ul").show();
		if (type=="root") {
			$("#m_del").hide();
			$("#m_check").hide();
			$("#m_unCheck").hide();
		} else {
			$("#m_del").show();
			$("#m_check").show();
			$("#m_unCheck").show();
		}
		rMenu.css({"top":y+"px", "left":x+"px", "visibility":"visible"});

		$("body").bind("mousedown", onBodyMouseDown);
	}
	function hideRMenu() {
		if (rMenu) rMenu.css({"visibility": "hidden"});
		$("body").unbind("mousedown", onBodyMouseDown);
	}
	function onBodyMouseDown(event){
		if (!(event.target.id == "rMenu" || $(event.target).parents("#rMenu").length>0)) {
			rMenu.css({"visibility" : "hidden"});
		}
	}
	
	function addTreeNode(){
	}
	function removeTreeNode(){
	}
	function checkTreeNode(){
	}
	function checkTreeNode(){
	}
	</SCRIPT>
  </head>
<body >
  <div style="margin: 0 auto;">
    <div class="tree">
		<ul id="treeDemo" class="ztree"></ul>
	</div>
	<div id="showId">
		<input type="text" name="id" id="id"/>
	</div>
	<div id="rMenu">
		<ul>
			<li id="m_add" onclick="addTreeNode();">增加节点</li>
			<li id="m_del" onclick="removeTreeNode();">删除节点</li>
			<li id="m_check" onclick="checkTreeNode(true);">Check节点</li>
			<li id="m_unCheck" onclick="checkTreeNode(false);">unCheck节点</li>
		</ul>
	</div>
	</div>
</body>
</html>
如果有兴趣可以从下面的下载地址进行下载
点击打开链接