【原】无脑操作:EasyUI Tree实现左键只选择叶子节点、右键浮动菜单实现增删改
Easyui中的Tree组件使用频率颇高,经常遇到的需求如下:
1、在树形结构上,只有叶子节点才能被选中,其他节点不能被选中;
2、在叶子节点上右键出现浮动菜单实现新增、删除、修改操作;
3、在非叶子节点上右键出现浮动菜单实现新增、修改操作。
------------------------------------------------------------------------------------------------------------------
实现方法如下:
1、搭建测试环境(可以参考前文:【原】无脑操作:IDEA + maven + SpringBoot + JPA + EasyUI实现CRUD及分页)
2、建库建表
- DROP TABLE biz_department;
- CREATE TABLE biz_department
- (
- departmentid INT AUTO_INCREMENT PRIMARY KEY COMMENT '部门编号',
- departmentpid INT NOT NULL COMMENT '部门父编号',
- departmentname VARCHAR(10) NOT NULL COMMENT '部门名称'
- ) ENGINE=INNODB COMMENT='部门信息';
- INSERT INTO biz_department VALUES
- (NULL, 0, '总部'),
- (NULL, 1, '上海分公司'), (NULL, 1, '安徽分公司'),
- (NULL, 3, '合肥办事处'), (NULL, 3, '铜陵办事处');
3、创建实体类 Department.java
- @Entity
- @Table(name = "biz_department")
- public class Department {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- @Column(name = "departmentid")
- private Integer departmentid;
- @Column(name = "departmentpid")
- private Integer departmentpid;
- @Column(name = "departmentname")
- private String departmentname;
- public Department() {
- }
- public Department(Integer departmentpid, String departmentname) {
- this.departmentpid = departmentpid;
- this.departmentname = departmentname;
- }
- public Integer getDepartmentid() {
- return departmentid;
- }
- public void setDepartmentid(Integer departmentid) {
- this.departmentid = departmentid;
- }
- public Integer getDepartmentpid() {
- return departmentpid;
- }
- public void setDepartmentpid(Integer departmentpid) {
- this.departmentpid = departmentpid;
- }
- public String getDepartmentname() {
- return departmentname;
- }
- public void setDepartmentname(String departmentname) {
- this.departmentname = departmentname;
- }
- }
4、编写DAO接口 DepartmentDao.java
- /**
- * 因为需要使用分页和条件查询,所以从JpaRepository接口 和 JpaSpecificationExecutor接口继承
- */
- public interface DepartmentDao extends JpaRepository<Department, Integer>, JpaSpecificationExecutor<Department> {
- }
5、编写工具类 TreeNode.java 和 TreeUtil.java
- /**
- * EasyUI Tree的封装类
- */
- public class TreeNode {
- private Integer id; // 节点的 id
- private Integer parentId; // 父节点id,java生成树时使用
- private String text; // 显示的节点文字。
- private String iconCls; // 节点图标样式 "iconCls":"icon-save", "iconCls":"icon-ok", 等
- private String state; // 节点状态, 'open' 或 'closed',默认是 'open'。当设为 'closed' 时,此节点有子节点,并且将从远程站点加载它们。
- private String flag; // 节点类型
- private Integer trueId; // 应用系统真实 id
- private boolean checked; // 指示节点是否被选中。
- private LinkedHashMap<?, ?> attributes; // 给一个节点追加的自定义属性。
- private List<TreeNode> children; // 定义了一些子节点的节点数组。
- private String url; // 扩展属性url
- public Integer getTrueId() {
- return trueId;
- }
- public void setTrueId(Integer trueId) {
- this.trueId = trueId;
- }
- public String getFlag() {
- return flag;
- }
- public void setFlag(String flag) {
- this.flag = flag;
- }
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public Integer getParentId() {
- return parentId;
- }
- public void setParentId(Integer parentId) {
- this.parentId = parentId;
- }
- public String getText() {
- return text;
- }
- public void setText(String text) {
- this.text = text;
- }
- public String getIconCls() {
- return iconCls;
- }
- public void setIconCls(String iconCls) {
- this.iconCls = iconCls;
- }
- public String getState() {
- return state;
- }
- public void setState(String state) {
- this.state = state;
- }
- public boolean isChecked() {
- return checked;
- }
- public void setChecked(boolean checked) {
- this.checked = checked;
- }
- public LinkedHashMap<?, ?> getAttributes() {
- return attributes;
- }
- public void setAttributes(LinkedHashMap<?, ?> attributes) {
- this.attributes = attributes;
- }
- public List<TreeNode> getChildren() {
- return children;
- }
- public void setChildren(List<TreeNode> children) {
- this.children = children;
- }
- public String getUrl() {
- return url;
- }
- public void setUrl(String url) {
- this.url = url;
- }
- }
- /**
- * 树工具类
- */
- public class TreeUtil {
- /**
- * Tree装配方法
- *
- * @param tempTreeNodes
- * @param treeNodes
- * @return
- */
- public static List<TreeNode> Assemble(List<TreeNode> tempTreeNodes, List<TreeNode> treeNodes) {
- if (tempTreeNodes != null) {
- Map<Integer, TreeNode> map = new LinkedHashMap<>();
- for (TreeNode tn : tempTreeNodes) {
- map.put(tn.getId(), tn);
- }
- TreeNode treeNode;
- TreeNode pTreeNode;
- for (Integer id : map.keySet()) {
- treeNode = map.get(id);
- if (treeNode.getParentId() == 0) {
- treeNodes.add(treeNode);
- } else {
- pTreeNode = map.get(treeNode.getParentId());
- List<TreeNode> children = pTreeNode.getChildren();
- if (children != null) {
- children.add(treeNode);
- } else {
- children = new ArrayList();
- children.add(treeNode);
- pTreeNode.setChildren(children);
- }
- }
- }
- }
- return treeNodes;
- }
- }
6、规划控制器 DepartmentController.java
- @Controller
- @RequestMapping("/department")
- public class DepartmentController {
- @Autowired
- private DepartmentDao departmentDao;
- @RequestMapping("/view")
- public String view() {
- // 跳转至【资源管理】页面
- return "department";
- }
- @RequestMapping("/tree")
- @ResponseBody
- public String tree() {
- List<Department> list = departmentDao.findAll();
- List<TreeNode> tempTreeNodes = new ArrayList();
- List<TreeNode> treeNodes = new ArrayList();
- // 组装Easyui的Tree必须要有id、parentId、text属性,转换之
- for (Department department : list) {
- TreeNode tempTreeNode = new TreeNode();
- tempTreeNode.setId(department.getDepartmentid());
- tempTreeNode.setParentId(department.getDepartmentpid());
- tempTreeNode.setText(department.getDepartmentname());
- tempTreeNodes.add(tempTreeNode);
- }
- return JSONObject.toJSON(TreeUtil.Assemble(tempTreeNodes, treeNodes)).toString();
- }
- @RequestMapping("/saveNode")
- @ResponseBody
- public Map<String, Object> saveNode(Integer departmentpid, String departmentname) {
- Department model = new Department();
- model.setDepartmentpid(departmentpid);
- model.setDepartmentname(departmentname);
- Map<String, Object> resultMap = new HashMap<>();
- departmentDao.save(model);
- resultMap.put("success", true);
- return resultMap;
- }
- @RequestMapping("/updateNode")
- @ResponseBody
- public Map<String, Object> updateNode(Department model) {
- Map<String, Object> resultMap = new HashMap<>();
- departmentDao.save(model);
- resultMap.put("success", true);
- return resultMap;
- }
- @RequestMapping("/deleteNode")
- @ResponseBody
- public Map<String, Object> deleteNode(Integer departmentid) {
- Map<String, Object> resultMap = new HashMap<>();
- departmentDao.deleteById(departmentid);
- resultMap.put("success", true);
- return resultMap;
- }
- }
7、编写前端代码
HTML页面:department.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>测试Tree功能</title>
- <link rel="stylesheet" type="text/css" href="../easyui/themes/default/easyui.css">
- <link rel="stylesheet" type="text/css" href="../easyui/themes/icon.css">
- <script type="text/javascript" src="../easyui/jquery.min.js"></script>
- <script type="text/javascript" src="../easyui/jquery.easyui.min.js"></script>
- <script type="text/javascript" src="../easyui/locale/easyui-lang-zh_CN.js"></script>
- <script type="text/javascript" src="../biz/department.js"></script>
- </head>
- <body>
- <!-- 部门树 -->
- <ul id="deptTree" class="easyui-tree"></ul>
- <!-- 叶子节点右键菜单 -->
- <div id="leaf" class="easyui-menu" style="width: 120px;">
- <div onclick="addNode()" iconcls="icon-add">新增节点</div>
- <div onclick="removeNode()" iconcls="icon-remove">删除节点</div>
- <div onclick="updateNode()" iconcls="icon-edit">编辑节点</div>
- </div>
- <!-- 非叶子节点右键菜单 -->
- <div id="parentNode" class="easyui-menu" style="width: 120px;">
- <div onclick="addNode()" iconcls="icon-add">新增节点</div>
- <div onclick="updateNode()" iconcls="icon-edit">编辑节点</div>
- </div>
- <!-- 节点内容对话框 -->
- <div id="info" class="easyui-dialog" style="width:300px; height: 120px;" closed=true>
- <form id="treefrm" method="post">
- <input type="hidden" name="departmentid">
- <table style="margin: auto;" cellspacing="10">
- <tr>
- <td>部门名称</td>
- <td><input class="easyui-textbox" name="departmentname" value="" data-options="required:true"></td>
- </tr>
- </table>
- <div style="text-align: center; bottom: 15px; margin-top: 10px;">
- <a id="btnSave" class="easyui-linkbutton"
- data-options="iconCls:'icon-save'">保存</a>
- <a id="btnCancel" class="easyui-linkbutton"
- data-options="iconCls:'icon-cancel'">取消</a>
- </div>
- </form>
- </div>
- </body>
- </html>
对应JS文件:department.js
- // 记录添加还是修改
- var flag;
- // 临时存储选中节点数据
- var tempNode;
- // 页面加载
- $(function () {
- // 菜单树绑定数据
- $('#deptTree').tree({
- url: '/department/tree',
- animate: true,
- lines: true,
- onBeforeSelect: function (node) {
- // onBeforeSelect事件:节点被选中前触发,返回false则取消选择动作
- if (!$(this).tree('isLeaf', node.target)) {
- // 不是叶子节点,则不能选中
- return false;
- }
- },
- onClick: function (node) {
- // alert(node.target.innerText);
- },
- onContextMenu: function (e, node) {
- // 记录选中的节点,为后续增删改操作提供节点数据
- tempNode = node;
- // 阻止右键默认事件
- e.preventDefault();
- // 判断该结点有没有父结点
- var root = $(this).tree('getParent', node.target);
- // 没有父节点则为根结点,可以新增、编辑,不可以删除
- if (root == null) {
- // 如果是根节点,则可以新增、编辑,不可以删除
- $('#parentNode').menu('show', {
- left: e.pageX,
- top: e.pageY
- });
- }
- if ($(this).tree('isLeaf', node.target)) {
- // 如果是叶子节点,则可以新增、编辑和删除
- $('#leaf').menu('show', {
- left: e.pageX,
- top: e.pageY
- });
- } else {
- // 如果不是叶子节点,则可以新增、编辑,不可以删除
- $('#parentNode').menu('show', {
- left: e.pageX,
- top: e.pageY
- });
- }
- }
- });
- // 保存按钮押下处理
- $('#btnSave').click(function () {
- var tempdata, tempurl, tempmsg;
- if (flag == 'add') {
- tempurl = 'saveNode';
- tempmsg = '添加成功!';
- tempdata = {
- departmentpid: tempNode.id,
- departmentname: $('#treefrm').find('input[name=departmentname]').val()
- };
- } else if (flag == 'edit') {
- tempurl = 'updateNode';
- tempmsg = '编辑成功!';
- tempdata = {
- departmentid: $('#treefrm').find('input[name=departmentid]').val(),
- departmentpid: $('#deptTree').tree('getParent', tempNode.target).id,
- departmentname: $('#treefrm').find('input[name=departmentname]').val()
- };
- }
- $.ajax({
- type: 'post',
- async: true,
- url: tempurl,
- data: tempdata,
- dataType: 'json',
- success: function (result) {
- // 树重新加载
- $('#deptTree').tree('reload');
- $.messager.show({
- title: '提示信息',
- msg: tempmsg
- });
- },
- error: function (result) {
- // 请求失败时执行该函数
- $.messager.show({
- title: '错误信息',
- msg: result.msg
- });
- }
- });
- $('#treefrm').form('clear');
- $('#info').dialog('close');
- });
- // 取消按钮押下处理
- $('#btnCancel').click(function () {
- $('#treefrm').form('clear');
- $('#info').dialog('close');
- });
- });
- // 新增节点
- var addNode = function () {
- flag = 'add';
- // 清空表单数据
- $('#treefrm').form('clear');
- // 打开dialog
- $('#info').dialog('open').dialog('setTitle', '新增');
- };
- // 编辑节点
- var updateNode = function () {
- flag = 'edit';
- // 清空表单数据
- $('#treefrm').form('clear');
- $('#treefrm').form('load', {
- departmentid: tempNode.id,
- departmentname: tempNode.text
- });
- // 打开dialog
- $('#info').dialog('open').dialog('setTitle', '编辑');
- };
- // 删除节点
- var removeNode = function () {
- // 前台删除
- $('#deptTree').tree('remove', tempNode.target);
- // 后台删除
- $.ajax({
- type: "post",
- async: true, // 异步请求(同步请求将会锁住浏览器,用户其他操作必须等待请求完成才可以执行)
- url: "deleteNode",
- data: {departmentid: tempNode.id},
- dataType: "json", // 返回数据形式为json
- success: function (result) {
- // 请求成功时执行该函数内容,result即为服务器返回的json对象
- $.messager.show({
- title: '提示信息',
- msg: '删除成功!'
- });
- },
- error: function (result) {
- // 请求失败时执行该函数
- $.messager.show({
- title: '错误信息',
- msg: result.msg
- });
- }
- });
- };
8、运行效果
【原】无脑操作:EasyUI Tree实现左键只选择叶子节点、右键浮动菜单实现增删改的更多相关文章
- EasyUI Combotree只选择叶子节点
EasyUI Combotree的方法拓展自Combo和Tree.而Tree有一个onBeforSelect事件来帮助我们实现只选择叶子节点的功能. Tree事件需要 'node' 参数,它包括下列属 ...
- 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础授权权限
上一篇<[原]无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限>介绍了实现Shiro的基础认证.本篇谈谈实现 ...
- 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限
开发环境搭建参见<[原]无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页> 需求: ① 除了登录页面,在地址栏直接访问其他 ...
- 【原】无脑操作:express + MySQL 实现CRUD
基于node.js的web开发框架express简单方便,很多项目中都在使用.这里结合MySQL数据库,实现最简单的CRUD操作. 开发环境: IDE:WebStorm DB:MySQL ------ ...
- Jquery EasyUI Combotree只能选择叶子节点且叶子节点有多选框
Jquery EasyUI Combotree只能选择叶子节点且叶子节点有多选框 Jquery EasyUI Combotree单选框,Jquery EasyUI Combotree只能选择叶子节点 ...
- 【原】无脑操作:eclipse + maven搭建SSM框架
网上看到一些Spring + Spring MVC + MyBatis框架的搭建教程,不是很详细或是时间久远了,自己动手整一个简单无脑的! 0.系统环境 1)Windows 10 企业版 2)JDK ...
- 【原】无脑操作:ElasticSearch学习笔记(01)
开篇来自于经典的“保安的哲学三问”(你是谁,在哪儿,要干嘛) 问题一.ElasticSearch是什么?有什么用处? 答:截至2018年12月28日,从ElasticSearch官网(https:// ...
- easyui Tree模拟级联勾选cascadeCheck,节点选择,父节点自动选中,节点取消,父节点自动取消选择,节点选择,所有子节点全部选择,节点取消,所有子节点全部取消勾选
最近项目中用到easyui tree,发现tree控件的cascadeCheck有些坑,不像miniui 的tree控件,级联勾选符合业务需求,所以就自己重新改写了onCheck事件,符合业务需求.网 ...
- EasyUI Combotree 只允许选择 叶子节点
$("#SDID").combotree({ url: '/Ajax/GetDeptTree.aspx?level=4&pid=-1', onSelect: functio ...
随机推荐
- windows无人值守文件的制作_autounattend.xml
网址:http://www.windowsafg.com/office2010.html Note:网络不能是国内网络(需要FQ),否则不能生成自动应答文件. 以Windows10为例:Window ...
- 积极参与开源项目,促进.NET Core生态社区发展
今天早上在微信群里聊天聊到百度的SDK 已经支持.NET Core, 百度已经在3月份就支持了,想起当时还是我在他们的github上提的issue: https://github.com/Baidu- ...
- 以Windows服务方式运行.NET Core程序
在之前一篇博客<以Windows服务方式运行ASP.NET Core程序>中我讲述了如何把ASP.NET Core程序作为Windows服务运行的方法,而今,我们又遇到了新的问题,那就是: ...
- javascript 字符串转换数字的方法大总结
方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有 ...
- 【安富莱STM32H7教程】第1章 初学STM32H7的准备工作
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第1章 初学STM32H7的准备工作 俗话说万事开头 ...
- MySQL中的自适应哈希索引
众所周知,InnoDB使用的索引结构是B+树,但其实它还支持另一种索引:自适应哈希索引. 哈希表是数组+链表的形式.通过哈希函数计算每个节点数据中键所对应的哈希桶位置,如果出现哈希冲突,就使用拉链法来 ...
- python安装第三方库报错visual c++ 14.0 is required
使用python安装第三方库时报错如下: error: Microsoft Visual C++ 14.0 is required. Get it with “Microsoft Visual C++ ...
- 7.Flask文件上传
1.1.上传文件和访问上传的文件 upload_file_demo.py from flask import Flask,request,render_template import os from ...
- 【Android Studio安装部署系列】二十五、Android studio使用NDK生成so文件和arr文件
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android Studio使用ndk的简单步骤. NDK环境搭建 下载NDK 下载链接:https://developer.and ...
- .net core自定义高性能的Web API服务网关
网关对于服务起到一个统一控制处理的作用,也便于客户端更好的调用:通过网关可以灵活地控制服务应用接口负载,故障迁移,安全控制,监控跟踪和日志处理等.由于网关在性能和可靠性上都要求非常严格,所以针对业务需 ...