最近想做一个树结构,都说zTree挺好的,就试着搞搞吧。 官方文档:http://www.treejs.cn/v3/main.php#_zTreeInfo 看了好多例子还是懵懵的,各种调试各种效果出不来,心塞。 好了 接着就来个简单的吧。 使用Ajax获取后台JSON数据 然后zTree显示。 首先你要有json包, 我用的spring的Jackson, 之前的文章有Jackson的配置,这里再加一下吧,先上jar包。
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.3</version>
</dependency>
SpringMVC.xml文件加上Jackson配置
<!--start:使用Jackson 2.x的配置,需要导入的jar包:jackson-core-xxx.jar、jackson-annotations-xxx.jar、jackson-databind-xxx.jar-->
<!--通过处理器映射DefaultAnnotationHandlerMapping来开启支持@Controller注解-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
<!--通过处理器适配器AnnotationMethodHandlerAdapter来开启支持@RequestMapping注解-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<!-- 设置返回字符串编码 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name = "supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- json转换器 -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
都是从网上扒拉的 注意Jackson的版本就好,我这里使用的是2.x
先写一个简单的菜单实体类 Menu.java
package com.ys.entity;
/**
* 菜单类
* @author Administrator
*
*/
public class Menu {
private int id;//ID
private String name;//菜单名称
private int pId;//上级菜单编号
private String menu_action;//菜单动作
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getpId() {
return pId;
}
public void setpId(int pId) {
this.pId = pId;
}
public String getMenu_action() {
return menu_action;
}
public void setMenu_action(String menu_action) {
this.menu_action = menu_action;
}
}
这个实体类改了好多次,使用Oracle各种水土不服, 实体类的字段必须要有id、pId、name, 之前查询用别名不好使,只能去数据库改字段了,MySQL好像没有这个问题。
MenuMapper.java
package com.ys.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import com.ys.entity.Menu;
/**
* 菜单类接口方法
* @author Administrator
*
*/
@Repository
public interface MenuMapper {
//获取菜单信息
@Select("select * from t_menu")
List<Menu> getAll();
//修改菜单名称
@Update("update t_menu set name=#{name} where id=#{id}")
int updateMenu(@Param("id")int id,@Param("name")String name);
//删除菜单
@Delete("delete from t_menu where id=#{id}")
int deleteMenu(@Param("id")int id);
}
简单的一个查询就好了。
MenuService.java
package com.ys.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ys.entity.Menu;
import com.ys.mapper.MenuMapper;
@Service
public class MenuService{
@Autowired
private MenuMapper menudao;
/**
* 获取所有菜单列表
* @return
*/
public List<Menu> getAll() {
return menudao.getAll();
}
/**
* 修改菜单信息
* @param id
* @param name
* @return
*/
public int updateMenu(int id,String name){
return menudao.updateMenu(id,name);
}
/**
* 删除菜单
* @param id
* @return
*/
public int deleteMenu(int id){
return menudao.deleteMenu(id);
}
}
MenuController.java
package com.ys.controller;
import java.util.List;
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.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ys.entity.Menu;
import com.ys.service.MenuService;
@Controller
public class MenuController {
@Autowired
private MenuService menuservice;
/**
* 查询menu所有信息返回JSON传到前台ajax
* document.write(JSON.stringify(data));可以输出JSON数据
* @ResponseBody SpringMVC注解 需要配置SpringMVC.xml文件
* @return
*/
@RequestMapping(value="menudata",method=RequestMethod.POST)
@ResponseBody
public List<Menu> getMenuData(){
//查询信息返回JSON
List<Menu> menulist=menuservice.getAll();
return menulist;
}
/**
*修改树节点
*/
@RequestMapping(value="updateMenu",method=RequestMethod.POST)
@ResponseBody
public void updateMenu(int id,String name,HttpServletRequest request,HttpServletResponse response){
int result=menuservice.updateMenu(id,name);
if(result>0){
System.out.println("修改节点成功!");
System.out.println("节点名称="+name);
}else{
System.out.println("修改节点失败!");
}
}
@RequestMapping(value="deleteMenu",method=RequestMethod.POST)
@ResponseBody
public void deleteMenu(int id,HttpServletRequest request,HttpServletResponse response){
int result=menuservice.deleteMenu(id);
if(result>0){
System.out.println("删除节点成功!");
}else{
System.out.println("删除节点失败!");
}
}
}
使用Ajax交互数据的时候,Controller方法上@RequestMapping()最好加上method=RequestMethod.POST 用GET/POST还是别的就随你了。
另外@ResponseBody是一定要加的 用于json的转换。
zTreeMenu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
String path=request.getContextPath();
String basePath=request.getScheme()+"//"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="ctxStatic" value="${pageContext.request.contextPath}/static"></c:set>
<c:set var="ctx" value="${pageContext.request.contextPath}"></c:set>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>OA-zTree树状数据示例</title>
<!-- 导入jQuery zTree依赖于jQuery -->
<script type="text/javascript" src="${ctxStatic}/jquery/jquery-2.1.1.min.js"></script>
<!-- zTree的核心库 -->
<script type="text/javascript" src="${ctxStatic}/zTree/js/jquery.ztree.core.min.js"></script>
<!-- zTree的复选框 -->
<script type="text/javascript" src="${ctxStatic}/zTree/js/jquery.ztree.excheck.min.js"></script>
<script type="text/javascript" src="${ctxStatic}/zTree/js/jquery.ztree.exedit.min.js"></script>
<!-- zTree的样式 -->
<link type="text/css" rel="stylesheet" href="${ctxStatic}/zTree/css/metroStyle/metroStyle.css"/>
<script type="text/javascript">
var zTreeObj;
//树属性的定义
var setting = {
//页面上的显示效果
view: {
addHoverDom: addHoverDom,//鼠标悬停显示按钮
removeHoverDom: removeHoverDom,//鼠标移开操作
selectedMulti: false
},
check : {
enable : true //复选框
},
edit: {
enable: true,
editNameSelectAll: true, //修改选中
showRemoveBtn: true, //显示按钮
showRenameBtn: true
},
data: {
simpleData: {
enable:true,
idKey: "id", //这个 id、pId最好这么写 不然字段对不上没有数据
pIdKey: "pId",
}
},
callback: {
beforeDrag: beforeDrag,
beforeEditName: beforeEditName,
beforeRemove: beforeRemove,
beforeRename: beforeRename,
onRemove: onRemove,//移除操作
onRename: onRename//修改操作
}
};
var log, className = "dark";
function beforeDrag(treeId, treeNodes) {
return false;
}
/* -----------修改方法---------------------*/
/* 修改前弹框 */
function beforeEditName(treeId, treeNode) {
className = (className === "dark" ? "":"dark");
showLog("[ "+getTime()+" beforeEditName ] " + treeNode.name);
var zTree = $.fn.zTree.getZTreeObj("ztreeDemo");
zTree.selectNode(treeNode);
setTimeout(function() {
if (confirm("进入节点 -- " " + treeNode.name + " " 的编辑状态吗?")) {
setTimeout(function(){
zTree.editName(treeNode);
}, 0);
}
}, 0);
return false;
};
function beforeRename(treeId, treeNode, newName, isCancel) {
className = (className === "dark" ? "":"dark");
showLog((isCancel ? "<span style='color:red'>":"") + "[ "+getTime()+" beforeRename ] " + treeNode.name + (isCancel ? "</span>":""));
if (newName.length == 0) {
setTimeout(function() {
var zTree = $.fn.zTree.getZTreeObj("ztreeDemo");
zTree.cancelEditName();
alert("节点名称不能为空.");
}, 0);
return false;
}
return true;
};
function onRename(e, treeId, treeNode) {
$.ajax({
type: 'post',
url: '${ctx}/updateMenu',
data: {id:treeNode.id, name:treeNode.name},
dataType: 'json',
success: function(data){
},
error:function(data){
}
});
};
/* -----------------删除方法---------------------- */
function beforeRemove(treeId, treeNode) {
className = (className === "dark" ? "":"dark");
showLog("[ "+getTime()+" beforeRemove ] " + treeNode.name);
var zTree = $.fn.zTree.getZTreeObj("ztreeDemo");
zTree.selectNode(treeNode);
//删除前先进行判断此节点是否存在子节点 若存在子节点不可删除
var ztree=$.fn.zTree.getZTreeObj(treeId);
nodes=ztree.getSelectedNodes();
var node=nodes[0];
if(node.isParent){
alert('父节点下存在子节点数据,不能删除!!!');
return false;
}else{
return confirm("确认删除 节点 -- "" + treeNode.name + "" 吗?");
}
};
//删除操作
function onRemove(e, treeId, treeNode) {
//showLog("[ "+getTime()+" onRemove ] " + treeNode.name);
$.ajax({
type:'post',
url:'${ctx}/deleteMenu',
data:{id:treeNode.id},
dataType:'json',
success:function(data){
},
});
};
function showRemoveBtn(treeId, treeNode) {
return !treeNode.isFirstNode;
}
function showRenameBtn(treeId, treeNode) {
return !treeNode.isLastNode;
}
function showLog(str) {
if (!log) log = $("#log");
log.append("<li class='"+className+"'>"+str+"</li>");
if(log.children("li").length > 8) {
log.get(0).removeChild(log.children("li")[0]);
}
}
function getTime() {
var now= new Date(),
h=now.getHours(),
m=now.getMinutes(),
s=now.getSeconds(),
ms=now.getMilliseconds();
return (h+":"+m+":"+s+ " " +ms);
}
function removeHoverDom(treeId, treeNode) {
$("#addBtn_"+treeNode.tId).unbind().remove();
};
function selectAll() {
var zTree = $.fn.zTree.getZTreeObj("ztreeDemo");
zTree.setting.edit.editNameSelectAll = $("#selectAll").attr("checked");
}
$(document).ready(function(){
$.fn.zTree.init($("#ztreeDemo"), setting, zNodes);
$("#selectAll").bind("click", selectAll);
});
//获取后台数据 加载zTree树
var zNodes;
$.ajax({
async:false,
cache:false,
type:'post',
dataType:'json',
url:'${ctx}/menudata',
success:function(data){
//document.write(JSON.stringify(data));
zNodes=data;
}
});
$(function() {
$.fn.zTree.init($("#ztreeDemo"), setting, zNodes);
});
</script>
</head>
<body>
<div class="zTreeDemoBackground left">
<ul id="ztreeDemo" class="ztree"></ul>
</div>
</body>
</html>
看看效果吧。