[original] brainless operation: EasyUI Tree implements left click to select only leaf node, right click to float menu to add, delete and modify

The Tree component in Easyui is frequently used, and the frequently encountered requirements are as follows:

1. In the tree structure, only leaf nodes can be selected, and other nodes cannot be selected;

2. Right click the leaf node to open the floating menu to add, delete and modify;

3. Right click the non leaf node to open the floating menu for adding and modifying operations.

------------------------------------------------------------------------------------------------------------------

The implementation method is as follows:

1. Build a test environment (refer to the previous article: [original] brainless operation: IDEA + maven + SpringBoot + JPA + EasyUI to realize CRUD and paging)

2. Building database and table

 1 DROP TABLE biz_department;
 2 CREATE TABLE biz_department
 3 (
 4     departmentid INT AUTO_INCREMENT PRIMARY KEY COMMENT 'Department number',
 5     departmentpid INT NOT NULL COMMENT 'Department parent number',
 6     departmentname VARCHAR(10) NOT NULL COMMENT 'Department name'
 7 ) ENGINE=INNODB COMMENT='Departmental information';
 8 INSERT INTO biz_department VALUES
 9 (NULL, 0, 'headquarters'),
10 (NULL, 1, 'Shanghai Branch'), (NULL, 1, 'Anhui Branch'),
11 (NULL, 3, 'Hefei Office'), (NULL, 3, 'Tongling Office');

3. Create entity class Department.java

 1 @Entity
 2 @Table(name = "biz_department")
 3 public class Department {
 4     @Id
 5     @GeneratedValue(strategy = GenerationType.IDENTITY)
 6     @Column(name = "departmentid")
 7     private Integer departmentid;
 8     @Column(name = "departmentpid")
 9     private Integer departmentpid;
10     @Column(name = "departmentname")
11     private String departmentname;
12 
13     public Department() {
14     }
15 
16     public Department(Integer departmentpid, String departmentname) {
17         this.departmentpid = departmentpid;
18         this.departmentname = departmentname;
19     }
20 
21     public Integer getDepartmentid() {
22         return departmentid;
23     }
24 
25     public void setDepartmentid(Integer departmentid) {
26         this.departmentid = departmentid;
27     }
28 
29     public Integer getDepartmentpid() {
30         return departmentpid;
31     }
32 
33     public void setDepartmentpid(Integer departmentpid) {
34         this.departmentpid = departmentpid;
35     }
36 
37     public String getDepartmentname() {
38         return departmentname;
39     }
40 
41     public void setDepartmentname(String departmentname) {
42         this.departmentname = departmentname;
43     }
44 }

4. Write DAO interface DepartmentDao.java

1 /**
2  * Because paging and conditional queries are required, they are inherited from the JpaRepository interface and the jpaspecification executor interface
3  */
4 public interface DepartmentDao extends JpaRepository<Department, Integer>, JpaSpecificationExecutor<Department> {
5 
6 }

5. Write tool classes TreeNode.java and TreeUtil.java

  1 /**
  2  * EasyUI Tree Encapsulation class
  3  */
  4 public class TreeNode {
  5     private Integer id;                      // Nodal id
  6     private Integer parentId;                // Parent node id,java Use when building trees
  7     private String text;                    // The displayed node text.
  8     private String iconCls;                 // Node icon style    "iconCls":"icon-save",  "iconCls":"icon-ok", etc.
  9     private String state;                   // Node status, 'open' or 'closed',The default is 'open'. Set as 'closed' When, this node has children and will load them from the remote site.
 10     private String flag;                    // Node type
 11     private Integer trueId;                 // Application system reality id
 12     private boolean checked;                // Indicates whether the node is selected.
 13     private LinkedHashMap<?, ?> attributes; // A custom attribute appended to a node.
 14     private List<TreeNode> children;        // The node array of some child nodes is defined.
 15     private String url;                     // Extended attribute url
 16 
 17     public Integer getTrueId() {
 18         return trueId;
 19     }
 20 
 21     public void setTrueId(Integer trueId) {
 22         this.trueId = trueId;
 23     }
 24 
 25     public String getFlag() {
 26         return flag;
 27     }
 28 
 29     public void setFlag(String flag) {
 30         this.flag = flag;
 31     }
 32 
 33     public Integer getId() {
 34         return id;
 35     }
 36 
 37     public void setId(Integer id) {
 38         this.id = id;
 39     }
 40 
 41     public Integer getParentId() {
 42         return parentId;
 43     }
 44 
 45     public void setParentId(Integer parentId) {
 46         this.parentId = parentId;
 47     }
 48 
 49     public String getText() {
 50         return text;
 51     }
 52 
 53     public void setText(String text) {
 54         this.text = text;
 55     }
 56 
 57     public String getIconCls() {
 58         return iconCls;
 59     }
 60 
 61     public void setIconCls(String iconCls) {
 62         this.iconCls = iconCls;
 63     }
 64 
 65     public String getState() {
 66         return state;
 67     }
 68 
 69     public void setState(String state) {
 70         this.state = state;
 71     }
 72 
 73     public boolean isChecked() {
 74         return checked;
 75     }
 76 
 77     public void setChecked(boolean checked) {
 78         this.checked = checked;
 79     }
 80 
 81     public LinkedHashMap<?, ?> getAttributes() {
 82         return attributes;
 83     }
 84 
 85     public void setAttributes(LinkedHashMap<?, ?> attributes) {
 86         this.attributes = attributes;
 87     }
 88 
 89     public List<TreeNode> getChildren() {
 90         return children;
 91     }
 92 
 93     public void setChildren(List<TreeNode> children) {
 94         this.children = children;
 95     }
 96 
 97     public String getUrl() {
 98         return url;
 99     }
100 
101     public void setUrl(String url) {
102         this.url = url;
103     }
104 }
 1 /**
 2  * Tree tool class
 3  */
 4 public class TreeUtil {
 5     /**
 6      * Tree Assembly method
 7      *
 8      * @param tempTreeNodes
 9      * @param treeNodes
10      * @return
11      */
12     public static List<TreeNode> Assemble(List<TreeNode> tempTreeNodes, List<TreeNode> treeNodes) {
13         if (tempTreeNodes != null) {
14             Map<Integer, TreeNode> map = new LinkedHashMap<>();
15             for (TreeNode tn : tempTreeNodes) {
16                 map.put(tn.getId(), tn);
17             }
18 
19             TreeNode treeNode;
20             TreeNode pTreeNode;
21             for (Integer id : map.keySet()) {
22                 treeNode = map.get(id);
23                 if (treeNode.getParentId() == 0) {
24                     treeNodes.add(treeNode);
25                 } else {
26                     pTreeNode = map.get(treeNode.getParentId());
27                     List<TreeNode> children = pTreeNode.getChildren();
28                     if (children != null) {
29                         children.add(treeNode);
30                     } else {
31                         children = new ArrayList();
32                         children.add(treeNode);
33                         pTreeNode.setChildren(children);
34                     }
35                 }
36             }
37         }
38 
39         return treeNodes;
40     }
41 }

6. Planning controller DepartmentController.java

 1 @Controller
 2 @RequestMapping("/department")
 3 public class DepartmentController {
 4     @Autowired
 5     private DepartmentDao departmentDao;
 6 
 7     @RequestMapping("/view")
 8     public String view() {
 9         // Go to [resource management] page
10         return "department";
11     }
12 
13     @RequestMapping("/tree")
14     @ResponseBody
15     public String tree() {
16         List<Department> list = departmentDao.findAll();
17         List<TreeNode> tempTreeNodes = new ArrayList();
18         List<TreeNode> treeNodes = new ArrayList();
19 
20         // Assemble Easyui Of Tree Must have id,parentId,text Properties, converting
21         for (Department department : list) {
22             TreeNode tempTreeNode = new TreeNode();
23             tempTreeNode.setId(department.getDepartmentid());
24             tempTreeNode.setParentId(department.getDepartmentpid());
25             tempTreeNode.setText(department.getDepartmentname());
26             tempTreeNodes.add(tempTreeNode);
27         }
28 
29         return JSONObject.toJSON(TreeUtil.Assemble(tempTreeNodes, treeNodes)).toString();
30     }
31 
32     @RequestMapping("/saveNode")
33     @ResponseBody
34     public Map<String, Object> saveNode(Integer departmentpid, String departmentname) {
35         Department model = new Department();
36         model.setDepartmentpid(departmentpid);
37         model.setDepartmentname(departmentname);
38 
39         Map<String, Object> resultMap = new HashMap<>();
40         departmentDao.save(model);
41         resultMap.put("success", true);
42         return resultMap;
43     }
44 
45     @RequestMapping("/updateNode")
46     @ResponseBody
47     public Map<String, Object> updateNode(Department model) {
48         Map<String, Object> resultMap = new HashMap<>();
49         departmentDao.save(model);
50         resultMap.put("success", true);
51         return resultMap;
52     }
53 
54     @RequestMapping("/deleteNode")
55     @ResponseBody
56     public Map<String, Object> deleteNode(Integer departmentid) {
57         Map<String, Object> resultMap = new HashMap<>();
58         departmentDao.deleteById(departmentid);
59         resultMap.put("success", true);
60         return resultMap;
61     }
62 }

7. Write front end code

HTML page: department.html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>test Tree function</title>
 6     <link rel="stylesheet" type="text/css" href="../easyui/themes/default/easyui.css">
 7     <link rel="stylesheet" type="text/css" href="../easyui/themes/icon.css">
 8     <script type="text/javascript" src="../easyui/jquery.min.js"></script>
 9     <script type="text/javascript" src="../easyui/jquery.easyui.min.js"></script>
10     <script type="text/javascript" src="../easyui/locale/easyui-lang-zh_CN.js"></script>
11     <script type="text/javascript" src="../biz/department.js"></script>
12 </head>
13 <body>
14 <!-- Branch tree -->
15 <ul id="deptTree" class="easyui-tree"></ul>
16 <!-- Right click menu of leaf node -->
17 <div id="leaf" class="easyui-menu" style="width: 120px;">
18     <div onclick="addNode()" iconcls="icon-add">New node</div>
19     <div onclick="removeNode()" iconcls="icon-remove">Delete node</div>
20     <div onclick="updateNode()" iconcls="icon-edit">Edit node</div>
21 </div>
22 <!-- Non leaf node right-click menu -->
23 <div id="parentNode" class="easyui-menu" style="width: 120px;">
24     <div onclick="addNode()" iconcls="icon-add">New node</div>
25     <div onclick="updateNode()" iconcls="icon-edit">Edit node</div>
26 </div>
27 <!-- Node content dialog -->
28 <div id="info" class="easyui-dialog" style="width:300px; height: 120px;" closed=true>
29     <form id="treefrm" method="post">
30         <input type="hidden" name="departmentid">
31         <table style="margin: auto;" cellspacing="10">
32             <tr>
33                 <td>Department name</td>
34                 <td><input class="easyui-textbox" name="departmentname" value="" data-options="required:true"></td>
35             </tr>
36         </table>
37         <div style="text-align: center; bottom: 15px; margin-top: 10px;">
38             <a id="btnSave" class="easyui-linkbutton"
39                data-options="iconCls:'icon-save'">Preservation</a>
40             <a id="btnCancel" class="easyui-linkbutton"
41                data-options="iconCls:'icon-cancel'">cancel</a>
42         </div>
43     </form>
44 </div>
45 </body>
46 </html>

Corresponding JS file: department.js

  1 // Record add or modify
  2 var flag;
  3 // Temporary storage of selected node data
  4 var tempNode;
  5 
  6 // Page loading
  7 $(function () {
  8     // Menu tree binding data
  9     $('#deptTree').tree({
 10         url: '/department/tree',
 11         animate: true,
 12         lines: true,
 13         onBeforeSelect: function (node) {
 14             // onBeforeSelect Event: triggered before the node is selected, return to false Then deselect the action
 15             if (!$(this).tree('isLeaf', node.target)) {
 16                 // If it is not a leaf node, it cannot be selected
 17                 return false;
 18             }
 19         },
 20         onClick: function (node) {
 21             // alert(node.target.innerText);
 22         },
 23         onContextMenu: function (e, node) {
 24             // Record the selected node and provide node data for subsequent addition, deletion and modification
 25             tempNode = node;
 26 
 27             // Block right click Default events
 28             e.preventDefault();
 29 
 30             // Determine whether the node has a parent
 31             var root = $(this).tree('getParent', node.target);
 32             // If there is no parent node, it is the root node, which can be added, edited or deleted
 33             if (root == null) {
 34                 // If it is a root node, it can be added, edited or not deleted
 35                 $('#parentNode').menu('show', {
 36                     left: e.pageX,
 37                     top: e.pageY
 38                 });
 39             }
 40 
 41             if ($(this).tree('isLeaf', node.target)) {
 42                 // If it is a leaf node, you can add, edit and delete it
 43                 $('#leaf').menu('show', {
 44                     left: e.pageX,
 45                     top: e.pageY
 46                 });
 47             } else {
 48                 // If it is not a leaf node, it can be added, edited or not deleted
 49                 $('#parentNode').menu('show', {
 50                     left: e.pageX,
 51                     top: e.pageY
 52                 });
 53             }
 54         }
 55     });
 56 
 57     // Save button
 58     $('#btnSave').click(function () {
 59         var tempdata, tempurl, tempmsg;
 60 
 61         if (flag == 'add') {
 62             tempurl = 'saveNode';
 63             tempmsg = 'Added successfully!';
 64             tempdata = {
 65                 departmentpid: tempNode.id,
 66                 departmentname: $('#treefrm').find('input[name=departmentname]').val()
 67             };
 68         } else if (flag == 'edit') {
 69             tempurl = 'updateNode';
 70             tempmsg = 'Edit successfully!';
 71             tempdata = {
 72                 departmentid: $('#treefrm').find('input[name=departmentid]').val(),
 73                 departmentpid: $('#deptTree').tree('getParent', tempNode.target).id,
 74                 departmentname: $('#treefrm').find('input[name=departmentname]').val()
 75             };
 76         }
 77 
 78         $.ajax({
 79             type: 'post',
 80             async: true,
 81             url: tempurl,
 82             data: tempdata,
 83             dataType: 'json',
 84             success: function (result) {
 85                 // Tree reload
 86                 $('#deptTree').tree('reload');
 87 
 88                 $.messager.show({
 89                     title: 'Prompt information',
 90                     msg: tempmsg
 91                 });
 92             },
 93             error: function (result) {
 94                 // Execute this function when the request fails
 95                 $.messager.show({
 96                     title: 'error message',
 97                     msg: result.msg
 98                 });
 99             }
100         });
101 
102         $('#treefrm').form('clear');
103         $('#info').dialog('close');
104     });
105 
106     // Cancel button
107     $('#btnCancel').click(function () {
108         $('#treefrm').form('clear');
109         $('#info').dialog('close');
110     });
111 });
112 
113 // New node
114 var addNode = function () {
115     flag = 'add';
116     // Clear form data
117     $('#treefrm').form('clear');
118     // open dialog
119     $('#info').dialog('open').dialog('setTitle', 'Newly added');
120 };
121 
122 // Edit node
123 var updateNode = function () {
124     flag = 'edit';
125     // Clear form data
126     $('#treefrm').form('clear');
127     $('#treefrm').form('load', {
128         departmentid: tempNode.id,
129         departmentname: tempNode.text
130     });
131     // open dialog
132     $('#info').dialog('open').dialog('setTitle', 'edit');
133 };
134 
135 // Delete node
136 var removeNode = function () {
137     // Foreground deletion
138     $('#deptTree').tree('remove', tempNode.target);
139 
140     // Background deletion
141     $.ajax({
142         type: "post",
143         async: true,           // Asynchronous request (the synchronous request will lock the browser, and other operations of the user must wait for the request to be completed before execution)
144         url: "deleteNode",
145         data: {departmentid: tempNode.id},
146         dataType: "json",      // Return data in the form of json
147         success: function (result) {
148             // The function content is executed when the request is successful, result Is returned by the server json object
149             $.messager.show({
150                 title: 'Prompt information',
151                 msg: 'Delete successfully!'
152             });
153         },
154         error: function (result) {
155             // Execute this function when the request fails
156             $.messager.show({
157                 title: 'error message',
158                 msg: result.msg
159             });
160         }
161     });
162 };

8. Operation effect

Tags: Java Javascript JSON Attribute

Posted on Fri, 31 Jan 2020 11:47:40 -0800 by jpt62089