BootStrap Jstree 树形菜单的增删改查的实现源码

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 树形菜单的增删改查的实现源码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 基于BootStrap Metronic开发框架经验小结【二】列表分页处理和插件JSTree的使用

    在上篇基于BootStrap Metronic开发框架经验小结[一]框架总览及菜单模块的处理,介绍了Bootstrap开发框架的一些基础性概括,包括总体界面效果,以及布局.菜单等内容,本篇继续这一主题,介绍页面内容常用到的数据分页处理,以及Bootstrap插件JSTree的使用. 在数据的界面显示当中,表格数据的展示以及分页是非常常见的处理操作,利用Bootstrap的样式布局,以及JQuery的Ajax数据处理,就能很好实现数据的动态展示和分页处理. 1.列表展示和分页处理1)数据的列表展示

  • BootStrap Jstree 树形菜单的增删改查的实现源码

    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.

  • VUE+Element实现增删改查的示例源码

    前言 &最近因为一些原因,没有更博客,昨天老师布置了一个作业,用vue实现增删改查功能,想想这也不难,就做一下试试吧. 因为自己写的样式没有别人做的好,因此我想用现成的UI框架,一直也没用过Element,就干脆趁机学一下吧. 实验步骤 首先引入一下element的css以及js <!-- 引入样式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chal

  • Jquery与Bootstrap实现后台管理页面增删改查功能示例

    使用jquery与bootstrap实现了一个比较简单但功能齐全的增删改查功能的后台管理页面,虽然只是一个CRUD页面,但麻雀虽小五脏俱全,JS常用的功能都用到了,本例用原生的jquery与bootstrap配合使用,不考虑JS的重构性及打包,该例子零耦合,开箱即用. 先看Demo: 一.用到的Jquery功能 1.获取/赋值input输入值 $("#my_id").val();// 获取 $("#my_id").val("user_id");/

  • .NET使用Hisql实现菜单管理(增删改查)

    一.引言 上一篇.NET集成ORM框架HiSql 已经完成了Hisql的引入,本节就把 项目中的菜单管理改成hisql的方式实现.菜单管理界面如图: 二.修改增删改查相关代码 1. 在 BaseRepository 仓储基类中添加 hisql访问对象:HiSqlClient.这样 所有继承了BaseRepository的业务仓储类都可以使用HiSqlClient操作数据库.本节中的菜单管理用到的仓储对象就是:SysMenuRepository 2.修改 SysMenuRepository类中访问

  • 详解使用pymysql在python中对mysql的增删改查操作(综合)

    这一次将使用pymysql来进行一次对MySQL的增删改查的全部操作,相当于对前五次的总结: 先查阅数据库: 现在编写源码进行增删改查操作,源码为: #!/usr/bin/python #coding:gbk import pymysql from builtins import int #将MysqlHelper的几个函数写出来 def connDB(): #连接数据库 conn=pymysql.connect(host="localhost",user="root&quo

  • JS结合bootstrap实现基本的增删改查功能

    提出问题:如何利用原生的js实现基本的增删改查功能??? 解决问题 假如你已经对JS有一定基础 假如你对bootstrap有一定基础 下面是具体的例子, 包含两个文件(index.jsp  和  index.js) <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC

  • BootStrap实现带有增删改查功能的表格(DEMO详解)

    前言 bootstrap的表格样式,有类似EasyUI的表格,也有卡片式表格,放到移动端显示,各有千秋.但是BootStrap自带的表格是没有操作列的,网上的资源不少,但是都是比较单一.零碎,JS.CSS也经常给的不全,自己经过大概一个月左右的时间,把表格封装了一下,希望能分享给大家. 表格封装了3个版本,接下来给大家展示一下样式和代码. 版本一 1. 样式 表格布局: 添加:添加一行新的空白代码 修改:选中可修改的列,点击需要修改的单元格,即可变成可编辑的状态. 2.代码 @using Dat

  • Springboot+Bootstrap实现增删改查实战

    说明 最近有朋友问我有没有Springboot+Bootstrap实现增删改查的DEMO,当时没有,现在他来了! 实现效果 代码地址 https://gitee.com/indexman/bootstrap_curd 水平一般能力有限,觉得有用的朋友给我来个一键三连或捐助:) 软件架构 前端:bootstrap4.5+thymeleaf+分页插件 后端:spring boot+mybatisPlus 数据库:mysql 核心功能代码 前端 <!DOCTYPE html> <html xm

  • vue实现树形结构增删改查的示例代码

    其实很多公司都会有类似于用户权限树的增删改查功能,正好最近我刚写了一个树形结构的增删改,在这里和大家分享一下,如果有不合理的地方欢迎评论,我会尽快优化~~ 先附上一下效果图 这个是没有点击编辑时,产品的需求是选中某个节点,取得该节点对应的设备数据,所以初始页面是下面这个样子的. 这个是点击了编辑之后,显示节点的编辑按钮 点击最上面的添加按钮,显示最外层父节点的添加画面 修改节点名称 因为我们的需求是编辑与非编辑两种状态,所以我用了两个树形组件,通过v-if进行控制.(v-if:该组件不存在,v-

  • SpringBoot+Vue+Axios+BootStrap实现图书的增删改查功能示例

    目录 一.开发工具 二.项目结构 三.编写项目 四.运行项目 由于是初学Vue.Axios,可能在界面和功能上存在着一些问题,但这些并不妨碍使用.如果有对编程感兴趣的朋友,可以试着做一做.这个由于是第一次做,不太熟练.在后续的过程中会不断的完善. 一.开发工具 IntelliJ IDEA Ultimate 2021.1 apache-maven-3.5.4 MySQL5.7 JDK 1.8.0_281 二.项目结构 三.编写项目 1.创建数据库 SET NAMES utf8mb4; SET FO

随机推荐