BootStrap Jstree 树形菜单的增删改查的实现源码
发布时间 - 2026-01-10 23:09:59 点击率:次1.首先需下载jstree的插件点击打开链接

2.在页面引入插件js文件css文件
<link rel="stylesheet" href="plugins/jstree/themes/classic/style.css" rel="external nofollow" > <script type="text/javascript" src="plugins/jstree/_lib/jquery.js"></script> <script type="text/javascript" src="plugins/jstree/_lib/jquery.cookie.js"></script> <script type="text/javascript" src="plugins/jstree/_lib/jquery.hotkeys.js"></script> <script type="text/javascript" src="plugins/jstree/jquery.jstree.js"></script>
3.初始化控件
1)html
<div id="demo2" class="demo" style="height:100px;"></div>
2)js 使用 demo2来初始化树形控件
<script type="text/javascript" class="source below">
$(function() {
$("#demo2").jstree(
{
"json_data" : {
"ajax" : {
"url" : "http://localhost:8080/MemberManager/DepartmentTreeJson",
"data" : function(n) {
// the result is fed to the AJAX request `data` option
return {
"operation" : "get_children",
"id" : n.attr ? n
.attr(
"id")
.replace(
"node_",
"")
: 1
};
}
}
},
"plugins" : [
"themes",
"json_data",
"ui",
"crrm",
"contextmenu",
"search" ],
})
.bind("loaded.jstree",
function(event, data) {
})
.bind(
"select_node.jstree",
function(event, data) {
if (data.rslt.obj
.attr("id") != undefined) {
}
})
.bind(
"remove.jstree",
function(e, data) {
data.rslt.obj.each(function() {
$.ajax({
async : false,
type : 'POST',
url : "http://localhost:8080/MemberManager/CreateNodeForDepartment",
data : {
"operation" : "remove_node",
"id" : this.id.replace("node_", "")
},
success : function(r) {
if (!r.status) {
data.inst.refresh();
}
}
});
});
})
.bind(
"remove.jstree",
function(e, data) {
data.rslt.obj.each(function() {
$.ajax({
async : false,
type : 'POST',
url : "http://localhost:8080/MemberManager/CreateNodeForDepartment",
data : {
"operation" : "remove_node",
"id" : this.id
.replace(
"node_",
"")
},
success : function(
r) {
if (!r.status) {
data.inst.refresh();
}
}
});
});
})
.bind(
"create.jstree",
function(e, data) {
$.post(
"http://localhost:8080/MemberManager/CreateNodeForDepartment",
{
"operation" : "create_node",
"id" : data.rslt.parent
.attr(
"id")
.replace(
"node_",
""),
"position" : data.rslt.position,
"title" : data.rslt.name,
"type" : data.rslt.obj
.attr("rel")
},
function(r) {
if (r.status) {
$(data.rslt.obj).attr("id", "node_" + r.id);
} else {
data.inst.refresh();
$.jstree.rollback(data.rlbk);
}
});
})
.bind(
"rename.jstree",
function(e, data) {
$.post(
"http://localhost:8080/MemberManager/CreateNodeForDepartment",
{
"operation" : "rename_node",
"id" : data.rslt.obj
.attr(
"id")
.replace(
"node_",
""),
"title" : data.rslt.new_name
},
function(r) {
if (!r.status) {
data.inst.refresh();
$.jstree.rollback(data.rlbk);
}
});
})
// 1) the loaded event fires as soon as data is parsed and inserted
// 2) but if you are using the cookie plugin or the core `initially_open` option:
.one("reopen.jstree",
function(event, data) {
})
// 3) but if you are using the cookie plugin or the UI `initially_select` option:
.one("reselect.jstree",
function(event, data) {
});
});
</script>
</pre>4.代码解析<p></p><p><pre name="code" class="java">
import java.util.List;
public class Department {
// 部门id
private String departmentid;
// 部门名称
private String name;
// 父级部门ID
private String parentid;
//同级之间的排序。排序id 小的排前面
private String orders;
//子节点
private List<Department> childNode;
public List<Department> getChildNode() {
return childNode;
}
public void setChildNode(List<Department> childNode) {
this.childNode = childNode;
}
public String getDepartmentid() {
return departmentid;
}
public void setDepartmentid(String departmentid) {
this.departmentid = departmentid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getParentid() {
return parentid;
}
public void setParentid(String parentid) {
this.parentid = parentid;
}
public String getOrders() {
return orders;
}
public void setOrders(String orders) {
this.orders = orders;
}
@Override
public String toString(){
return "[departmentID:"+this.departmentid+
"departmentName:"+this.name+
"parentID:"+this.parentid+"orders:"+this.orders+"]";
}
}
4.代码解析
插件初始化我这里使用了插件的两个参数json_data,以及plugins注意看代码结构
4.1上图两个部分即初始化部分重点解释下plugins这个参数是jstree整合插件的地方theme表示主题,json_data将上文定义的json_data也就
是Ajax从后要获取json数据返回到前台页面。contextmenu,是鼠标右键在树形节点上会弹出增删改查的菜单。
4.2 json数据的格式
先看展示
这是一个可以无限极下分的菜单,我们可以根据上图的目录结构对照下面的json数据结构来看,这样会更清晰。
{"data":"软件及数据","attr":{"id":"e59365b9-7b2a-43a3-b10a-cfe03d5eb004"},
"children":[
{"data":"创新组","attr":{"id":"73919359-2a1b-4ee7-bcc2-56949e8560e8"},
"children":[
{"data":"大数据","attr":{"id":"a7ea6a0f-0b78-4064-803b-f2e0a95d914f"},
"children":[
{"data":"研发","attr":{"id":"fc20e438-e7b9-4cca-be6a-49965daab528"},"children":[]}]}]},
{"data":"项目管理","attr":{"id":"e1bdae71-6cfb-4e8c-ab29-a3eb03b9961d"},"children":[]}
]
},
4.4组装json数据,我使用的是首先查找到所有的父节点即parentid=1的时候,然后递归将所有的子节点加到List<chiledren>对象里面,紧接着再通过循环递归组装无限极菜单json数据下面看数据库数据结构
import java.util.List;
public class Department {
// 部门id
private String departmentid;
// 部门名称
private String name;
// 父级部门ID
private String parentid;
//同级之间的排序。排序id 小的排前面
private String orders;
//子节点
private List<Department> childNode;
public List<Department> getChildNode() {
return childNode;
}
public void setChildNode(List<Department> childNode) {
this.childNode = childNode;
}
public String getDepartmentid() {
return departmentid;
}
public void setDepartmentid(String departmentid) {
this.departmentid = departmentid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getParentid() {
return parentid;
}
public void setParentid(String parentid) {
this.parentid = parentid;
}
public String getOrders() {
return orders;
}
public void setOrders(String orders) {
this.orders = orders;
}
@Override
public String toString(){
return "[departmentID:"+this.departmentid+
"departmentName:"+this.name+
"parentID:"+this.parentid+"orders:"+this.orders+"]";
}
}
4.5 此处servlet为客户端提供jstree的json_data。就是在初始化控件时候有ajax调用这个servlet获取json数据并返回给json_data
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.goldwind.www.service.DepartmentService;
import cn.goldwind.www.serviceimpl.DepartmentServiceImpl;
public class DepartmentTreeJson extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public DepartmentTreeJson() {
super();
}
@Override
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
DepartmentService deptService=new DepartmentServiceImpl();
//此处调用创建树节点的方法
StringBuilder json=deptService.createTreeNode();
json.deleteCharAt(json.length()-1);
System.out.println(json);
out.print("["+json+"]");
out.flush();
out.close();
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
@Override
public void init() throws ServletException {
// Put your code here
}
}
4.6上面servlet我们看下createTreeNode方法
这里是创建json的核心。
1)首先获取所有的(parent=1)根节点
@Override
public StringBuilder createTreeNode() {
//创建部门集合
List<Department> departments = new ArrayList<Department>();
//放置所有的根节点部门实体
departments = queryByParentID("1");
if (departments != null) {
return json(departments);
}
return null;
}
public StringBuilder json(List<Department> departments) {
for (int i = 0; i < departments.size(); i++) {
json.append('{');
json.append("\"data\":\"").append(departments.get(i).getName())
.append("\",");
json.append("\"attr\":{\"id\":\"").append(departments.get(i).getDepartmentid()).append("\"},");
List<Department> deptchild = queryByParentID(departments.get(i)
.getDepartmentid());
json.append("\"children\":");
json.append('[');
if (deptchild != null) {
json(deptchild);
if("1".equals(departments.get(i).getParentid())){
json.deleteCharAt(json.length()-1);
json.append(']');
json.append('}');
json.append(',');
}if(!"1".equals(departments.get(i).getParentid())&&deptchild!=null){
json.deleteCharAt(json.length()-1);
json.append(']');
json.append('}');
json.append(',');
}
} else{
json.append(']');
json.append('}');
json.append(',');
}
}
return json;
}
@Override
public List<Department> queryByParentID(String parentID) {
BaseDaoTemplate bd = new BaseDaoTemplate();
List<Department> departments = new ArrayList<Department>();
String sql = "select departmentid,name,parentid,orders from department where parentid=? ";
List<Object> params = new ArrayList<Object>();
params.add(parentID);
departments = bd.findAllData(Department.class, sql, params);
if (departments.size() > 0) {
return departments;
}
return null;
}
4.7
1.如何创建节点通过右键点击树形菜单弹出增加移除等操作(需在plugins里面加入contextmenu 这个例子就有)
2.绑定jstree的操作,此处以增加节点为例不一一例举
原理;通过点击创建按钮(contextMenu)即选定树节点右键弹出按钮。调用上图的方法,上图方法post方法通过ajax请求后台数据把创建的树节点保存到数据库,
operation:操作的方式(创建,移除,修改。。);
id:当前节点的id 即你创建下一个节点的parentID。
title:创建的新节点的名称
有这些数据就可以字啊后台获取数据然后增加到数据库。
4.8 创建 servlet处理所有的操作(创建,移除,修改。。)
import java.io.IOException;
import java.io.PrintWriter;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.goldwind.www.pojo.Department;
import cn.goldwind.www.service.DepartmentService;
import cn.goldwind.www.serviceimpl.DepartmentServiceImpl;
public class CreateNodeForDepartment extends HttpServlet {
private static final long serialVersionUID = 1L;
public CreateNodeForDepartment() {
super();
}
@Override
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
DepartmentService deptService=new DepartmentServiceImpl();
if("rename_node".equals(request.getParameter("operation"))){
String id=request.getParameter("id");
String title=request.getParameter("title");
Department dept=new Department();
dept.setDepartmentid(id);
deptService.modifyDepartment(dept, title);
}else if("create_node".equals(request.getParameter("operation"))){
String id=request.getParameter("id");
String title=request.getParameter("title");
Department dept=new Department();
dept.setDepartmentid(UUID.randomUUID().toString());
dept.setName(title);
dept.setParentid(id);
deptService.insertDepartment(dept);
}else if("remove_node".equals(request.getParameter("operation"))){
String id=request.getParameter("id");
Department dept=new Department();
dept.setDepartmentid(id);
deptService.deleteDepartment(dept);
}
out.flush();
out.close();
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to
* post.
*
* @param request
* the request send by the client to the server
* @param response
* the response send by the server to the client
* @throws ServletException
* if an error occurred
* @throws IOException
* if an error occurred
*/
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/**
* Initialization of the servlet. <br>
*
* @throws ServletException
* if an error occurs
*/
@Override
public void init() throws ServletException {
// Put your code here
}
}
好了这就完成了,当然这里面的树也是可以自定义图标,自定义按钮等操作,具体可以自己去探究。
以上所述是小编给大家介绍的BootStrap Jstree 树形菜单的增删改查的实现源码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# bootstrap
# jstree
# jstree树形菜单
# bootstrap treeview 树形菜单带复选框及级联选择功能
# Bootstrap框架建立树形菜单(Tree)的实例代码
# JS树形菜单组件Bootstrap TreeView使用方法详解
# Bootstrap树形菜单插件TreeView.js使用方法详解
# bootstrap-treeview实现多级树形菜单 后台JSON格式如何组织?
# 递归
# 上图
# 弹出
# 移除
# 数据结构
# 自定义
# 小编
# 的是
# 好了
# 也就
# 就有
# 在此
# 无限极
# 右键
# 这是一个
# 这就
# 给大家
# 鼠标右键
# 为例
# 可以根据
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何用虚拟主机快速搭建网站?详细步骤解析
百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
太平洋网站制作公司,网络用语太平洋是什么意思?
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤
在线制作视频网站免费,都有哪些好的动漫网站?
Laravel如何构建RESTful API_Laravel标准化API接口开发指南
如何快速搭建二级域名独立网站?
如何在阿里云ECS服务器部署织梦CMS网站?
香港服务器建站指南:免备案优势与SEO优化技巧全解析
悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤
*服务器网站为何频现安全漏洞?
nodejs redis 发布订阅机制封装实现方法及实例代码
Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
如何解决hover在ie6中的兼容性问题
Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用
Laravel如何实现模型的全局作用域?(Global Scope示例)
Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】
千库网官网入口推荐 千库网设计创意平台入口
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法
java中使用zxing批量生成二维码立牌
phpredis提高消息队列的实时性方法(推荐)
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
想要更高端的建设网站,这些原则一定要坚持!
作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】
制作企业网站建设方案,怎样建设一个公司网站?
node.js报错:Cannot find module 'ejs'的解决办法
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
智能起名网站制作软件有哪些,制作logo的软件?
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧
Laravel怎么在Blade中安全地输出原始HTML内容
儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?
网站制作企业,网站的banner和导航栏是指什么?
再谈Python中的字符串与字符编码(推荐)
大连网站制作公司哪家好一点,大连买房网站哪个好?
如何确保西部建站助手FTP传输的安全性?
html如何与html链接_实现多个HTML页面互相链接【互相】
如何在阿里云通过域名搭建网站?
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
5种Android数据存储方式汇总
如何用IIS7快速搭建并优化网站站点?
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】
品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?
googleplay官方入口在哪里_Google Play官方商店快速入口指南

