树形结构在实际开发中很长用到,比如部门管理,权限菜单等。因为用树形结构来展示会显的很清晰明了。最近写了一个个人博客小项目中用到了LayUI的树形结构,之后写了一个小案例整理一下。
官网地址:https://www.layui.com/v1/doc/modules/tree.html
先看一下显示的效果图。
点击节点右面会显示对应部门的详情信息,可以修改。可以自定义按钮添加部门,也可以直接用自带的方法对部门进行新增,修改和删除。可以获取选中的节点,根据项目需求(有的需要选中保存)。
先需要引入LayUI的样式文件JS和CSS。
案例对应的实体类Dept。
-
@Entity
-
public
class Dept {
-
private Integer id;
-
private String name;
//部门名称
-
private String deptName;
//部门负责人
-
private String phone;
//电话号
-
private String number;
//编号
-
private
double idx;
//排序
-
@JsonIgnore
-
private Dept parent;
-
@JsonIgnore
-
private List<Dept> children =
new ArrayList<>();
-
-
@Id
-
@GeneratedValue
-
public Integer getId() {
-
return id;
-
}
-
-
public void setId(Integer id) {
-
this.id = id;
-
}
-
-
public String getName() {
-
return name;
-
}
-
-
public void setName(String name) {
-
this.name = name;
-
}
-
-
public String getDeptName() {
-
return deptName;
-
}
-
-
public void setDeptName(String deptName) {
-
this.deptName = deptName;
-
}
-
-
public String getPhone() {
-
return phone;
-
}
-
-
public void setPhone(String phone) {
-
this.phone = phone;
-
}
-
-
public String getNumber() {
-
return number;
-
}
-
-
public void setNumber(String number) {
-
this.number = number;
-
}
-
-
public double getIdx() {
-
return idx;
-
}
-
-
public void setIdx(double idx) {
-
this.idx = idx;
-
}
-
-
@ManyToOne
-
@CreatedBy
-
public Dept getParent() {
-
return parent;
-
}
-
-
public void setParent(Dept parent) {
-
this.parent = parent;
-
}
-
-
@OneToMany(cascade=CascadeType.ALL,mappedBy="parent")
-
@OrderBy(value="idx")
-
public List<Dept> getChildren() {
-
return children;
-
}
-
-
public void setChildren(List<Dept> children) {
-
this.children = children;
-
}
-
-
public Dept(Integer id, String name, String deptName, String phone, String number, double idx, Dept parent, List<Dept> children) {
-
this.id = id;
-
this.name = name;
-
this.deptName = deptName;
-
this.phone = phone;
-
this.number = number;
-
this.idx = idx;
-
this.parent = parent;
-
this.children = children;
-
}
-
-
public Dept(Integer id) {
-
this.id = id;
-
}
-
-
public Dept() {
-
}
-
}
显示LayUI树形菜单,只需要一个标签容器即可。
-
<div id="dept_tree">
-
</div>
在案例中还有一些其他样式,比如右边的详情信息,新增按钮等。完整代码如下。
-
<style type="text/css">
-
#dept_main,
#dept_particulars{
-
width:
48.5%;
-
display: inline-block;
-
vertical-align: top;
-
padding:
20px;
-
background: white;
-
box-sizing: border-box;
-
}
-
#dept_tree{
-
margin-top:
20px;
-
}
-
</style>
-
-
<div id="dept_main" style="margin-right: 2%;">
-
<fieldset class="layui-elem-field layui-field-title">
-
<legend>所有部门
</legend>
-
</fieldset>
-
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept">
<i class="layui-icon">

</i>添加部门
</button>
-
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">获取选中节点
</button>
-
<div id="dept_tree">
-
-
</div>
-
</div>
-
<div id="dept_particulars">
-
<fieldset class="layui-elem-field layui-field-title">
-
<legend>部门详情
</legend>
-
</fieldset>
-
<div id="dept_home">
-
<div class="layui-tree-emptyText">无数据
</div>
-
</div>
-
</div>
JS请求数据渲染页面代码,data为请求数据源,当时直接放入的请求链接,好像不行,所以之后才写了一个方法去请求数据源。
-
layui.
use([
'tree',
'util'],
function() {
-
var tree = layui.tree;
-
var util = layui.util;
-
tree.render({
-
elem:
'#dept_tree',
-
data: getData(),
-
id:
'treeId',
-
showCheckbox:
true,
//是否显示复选框
-
onlyIconControl:
true
-
});
-
});
-
-
function getData(){
-
var data = [];
-
$.ajax({
-
url:
"dept/treeload",
//后台数据请求地址
-
type:
"post",
-
async:
false,
-
success:
function(resut){
-
data = resut;
-
}
-
});
-
return data;
-
}
tree 组件提供的有以下基础参数,可根据需要进行相应的设置。
参数选项 | 说明 | 类型 | 示例值 |
---|---|---|---|
elem | 指向容器选择器 | String/Object | - |
data | 数据源 | Array | - |
id | 设定实例唯一索引,用于基础方法传参使用。 | String | - |
showCheckbox | 是否显示复选框 | Boolean | false |
edit | 是否开启节点的操作图标。默认 false。
| Boolean/Array | ['update', 'del'] |
accordion | 是否开启手风琴模式,默认 false | Boolean | false |
onlyIconControl | 是否仅允许节点左侧图标控制展开收缩。默认 false(即点击节点本身也可控制)。若为 true,则只能通过节点左侧图标来展开收缩 | Boolean | false |
isJump | 是否允许点击节点时弹出新窗口跳转。默认 false,若开启,需在节点数据中设定 link 参数(值为 url 格式) | Boolean | false |
showLine | 是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。 | Boolean | true |
text | 自定义各类默认文本,目前支持以下设定: text: { defaultNodeName: '未命名' //节点默认名称 ,none: '无数据' //数据为空时的提示文本 } | Object | - |
因为tree指定了json数据的键名称,所以后台传递过来的数据对应的键名不一样时需要做一下处理,或者实体类中的属性名就和tree的JSON数据的键名称一样。
键名:
属性选项 | 说明 | 类型 | 示例值 |
---|---|---|---|
title | 节点标题 | String | 未命名 |
id | 节点唯一索引,用于对指定节点进行各类操作 | String/Number | 任意唯一的字符或数字 |
children | 子节点。支持设定选项同父节点 | Array | [{title: '子节点1', id: '111'}] |
href | 点击节点弹出新窗口对应的 url。需开启 isJump 参数 | String | 任意 URL |
spread | 节点是否初始展开,默认 false | Boolean | true |
checked | 节点是否初始为选中状态(如果开启复选框的话),默认 false | Boolean | true |
disabled | 节点是否为禁用状态。默认 false | Boolean | false |
后台请求数据的方法。
-
@RequestMapping(value = "/treeload")
-
@ResponseBody
-
public Object treeload(){
-
Sort sort = Sort.
by(
"idx");
-
List<Dept> dpet = deptService.findByParentIsNull(sort);
//查找所有菜单
-
List<HashMap<String, Object>> result = new ArrayList<>();
//定义一个map处理json键名问题
-
return
fun(dpet, result);
-
}
-
-
private Object
fun(List<Dept> dpet, List<HashMap<String, Object>> result) {
-
for(Dept d : dpet){
-
HashMap<String, Object> map = new HashMap<>();
-
map.put(
"id", d.getId());
-
map.put(
"title", d.getName());
-
map.put(
"spread",
true);
//设置是否展开
-
List<HashMap<String, Object>> result1 = new ArrayList<>();
-
List<Dept> children = d.getChildren();
//下级菜单
-
//这里可以根据自己需求判断节点默认选中
-
/*if(m.getParent() != null || m.getChildren().size() == 0){
-
map.put("checked", true); //设置为选中状态
-
}*/
-
map.put(
"children",
fun(children, result1));
-
result.add(map);
-
}
-
return result;
-
}
因为这里新建的实体类字段名和tree指定了json数据的键名称不一样,所以这里用了一个fun递归方法处理的。中间可以根据项目需求,根据条件判断是否需要选中该节点。
返回的JSON数据格式
-
[
-
{
-
"children": [
//子节点
-
{
-
"children": [
-
{
-
"children": [],
-
"id":
30,
-
"title":
"测试",
-
"spread":
true
-
}, {
-
"children": [],
-
"id":
31,
-
"title":
"开发",
-
"spread":
true
-
}, {
-
"children": [
-
{
-
"children": [],
-
"id":
36,
-
"title":
"测试节点",
-
"spread":
true
-
}
-
],
-
"id":
32,
-
"title":
"测试",
-
"spread":
true
-
}
-
],
-
"id":
2,
-
"title":
"技术部",
-
"spread":
true
-
}, {
-
"children": [],
-
"id":
19,
-
"title":
"财务部",
-
"spread":
true
-
}
-
],
-
"id":
1,
//节点id
-
"title":
"某某公司",
//节点名称
-
"spread":
true
-
}, {
-
"children": [],
-
"id":
33,
-
"title":
"测试",
-
"spread":
true
-
}
-
]
设置节点点击回调方法(在加载数据方法tree.render中添加以下代码)。
-
click:
function (obj) {
-
var id = obj.data.id;
-
$(
"#dept_home").load(
"dept/show?id="+id);
-
}
把请求过来的详情页面load到右边的div中显示。后台请求方法
-
@RequestMapping(value =
"/show")
-
public
void show(DeptForm form, ModelMap map)
throws InstantiationException, IllegalAccessException {
-
Dept model =
new Dept();
-
Integer id = form.getId();
-
Integer parentId =
0;
-
if(id!=
null) {
-
model = deptService.findById(id);
-
parentId = model.getParent()==
null?
0:model.getParent().getId();
-
}
-
map.put(
"parentId", parentId);
-
map.put(
"model", model);
-
}
DeptForm类为一个接收类,其中字段和实体类中一样。根据请求传递过来的id,查询这条数据的详细信息,之后把查询的当前部门详情数据及父级节点id(用于下拉树TreeSelect)传递给详情页面。
show.html详情页面代码。
-
<meta charset="UTF-8" />
-
<style type="text/css">
-
.myData
.layui-form-item{
-
margin:
20px
100px
10px
45px;
-
}
-
.myData
.layui-form-label{
-
width:
85px;
-
}
-
.layui-input-block {
-
margin-left:
120px;
-
}
-
</style>
-
<form class="layui-form myData" action="save" method="post" lay-filter="stuform">
-
<input type="hidden" name="id" data-th-value="${model.id}" />
-
-
<div class="layui-form-item">
-
<label class="layui-form-label">上级部门:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="parentId" id="tree" lay-filter="tree" class="layui-input" />
-
</div>
-
</div>
-
<div class="layui-form-item">
-
<label class="layui-form-label">部门名称:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="name" lay-verify="required" th:value="${model.name}" class="layui-input" />
-
</div>
-
</div>
-
<div class="layui-form-item" >
-
<label class="layui-form-label">部门负责人:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="deptName" th:value="${model.deptName}" class="layui-input" />
-
</div>
-
</div>
-
<div class="layui-form-item" >
-
<label class="layui-form-label">电话:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="phone" th:value="${model.phone}" class="layui-input" />
-
</div>
-
</div>
-
<div class="layui-form-item" >
-
<label class="layui-form-label">编号:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="number" th:value="${model.number}" class="layui-input" />
-
</div>
-
</div>
-
<div class="layui-form-item" >
-
<label class="layui-form-label">排序:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="idx" value="0" th:value="${model.idx}" class="layui-input" />
-
</div>
-
</div>
-
<div class="layui-form-item">
-
<label class="layui-form-label">
</label>
-
<div class="layui-input-block">
-
<button lay-submit class="layui-btn layui-btn-radius layui-btn-normal" lay-filter="btnSub">
-
<i class="layui-icon">

</i>修改并保存
-
</button>
-
</div>
-
</div>
-
</form>
-
-
<script th:inline="javascript">
-
layui.use([
"treeSelect",
"form",
"tree"],
function () {
-
var form = layui.form;
-
var tree = layui.tree;
-
form.render(
'select');
-
var treeSelect = layui.treeSelect;
-
treeSelect.render({
-
// 选择器
-
elem:
'#tree',
-
// 数据
-
data:
'dept/treeSelect?id='+[[${model.id==
null ?
0 : model.id}]],
-
// 异步加载方式:get/post,默认get
-
type:
'post',
-
// 占位符
-
placeholder:
'上级菜单',
-
// 是否开启搜索功能:true/false,默认false
-
search:
true,
-
// 一些可定制的样式
-
style: {
-
folder: {
-
enable:
true
-
},
-
line: {
-
enable:
true
-
}
-
},
-
// 加载完成后的回调函数
-
success:
function (d) {
-
// 选中节点,根据id筛选
-
treeSelect.checkNode(
'tree', [[${model.parent ==
null? parentId: model.parent.id}]]);
-
treeSelect.refresh(
'tree');
-
}
-
});
-
-
form.on(
'submit(btnSub)',
function (data) {
-
$.post(
'dept/save', data.field,
function (result) {
-
if (result.success) {
-
tree.reload(
'treeId', {
data: getData()});
-
}
-
layer.msg(result.msg, {
offset:
'rb'});
-
});
-
return
false;
-
});
-
});
-
</script>
上级部门使用的是LayUI下拉树显示的,下拉树数据请求方法。关于下拉树的使用,可以访问LayUI下拉树TreeSelect的使用
-
@RequestMapping(value=
"/treeSelect")
-
@ResponseBody
-
public
Object treeSelect(
Integer id) {
-
Sort sort = Sort.by(
"idx");
-
Specification<Dept> spec = buildSpec1();
-
List<Dept>
list = deptService.findAll(spec,sort);
-
return buildTree(
list, id);
-
}
-
-
private
Object buildTree(
List<Dept>
list,
Integer id) {
-
List<HashMap<
String,
Object>> result=
new ArrayList<>();
-
for (Dept dept :
list) {
-
if(dept.getId() != id) {
-
HashMap<
String,
Object> node=
new HashMap<>();
-
node.put(
"id", dept.getId());
-
node.put(
"name",dept.getName());
-
node.put(
"open",
false);
-
node.put(
"checked",
false);
-
if(dept.getChildren().size() !=
0) {
-
node.put(
"children",buildTree(dept.getChildren(), id));
-
}
-
result.add(node);
-
}
-
}
-
-
return result;
-
}
-
-
public Specification<Dept> buildSpec1() {
-
Specification<Dept> specification =
new Specification<Dept>() {
-
-
private
static
final long serialVersionUID =
1L;
-
-
@Override
-
public Predicate toPredicate(Root<Dept> root, CriteriaQuery
<?> query, CriteriaBuilder cb) {
-
HashSet<Predicate> rules=
new HashSet<>();
-
Predicate
parent = cb.isNull(root.get(
"parent"));
-
rules.add(
parent);
-
return cb.
and(rules.toArray(
new Predicate[rules.size()]));
-
}
-
-
};
-
return specification;
-
}
显示的效果。
上面修改并保存后台方法(因为修改和新增共用的一个方法,用id区分的)。
-
@Override
-
public
Object save(DeptForm form) {
-
try {
-
Dept model =
new Dept();
-
Integer id = form.getId();
-
if(id !=
null) {
-
model = deptService.findById(id);
-
}
-
//父级菜单id
-
Integer parentId = form.getParentId();
-
if(parentId ==
null) {
-
model.setParent(
null);
-
}
else {
-
model.setParent(
new Dept(parentId));
-
}
-
BeanUtils.copyProperties(form, model,
"id",
"parent");
-
deptService.save(model);
-
return
new AjaxResult(
"数据保存成功!");
-
}
catch (
Exception e) {
-
return
new AjaxResult(
false,
"数据保存失败");
-
}
-
}
设置节点操作(在加载数据方法tree.render中添加以下代码)。
-
edit: [
'add',
'update',
'del'],
//操作节点的图标
-
operate:
function(obj){
-
var type = obj.type;
//得到操作类型:add、edit、del
-
var data = obj.data;
//得到当前节点的数据
-
var elem = obj.elem;
//得到当前节点元素
-
-
var id = data.id;
-
var name = data.title;
-
if(type ===
'add'){
//增加节点
-
$.post(
"dept/save", {
parentId: id,
name:
"未命名"},
function (result) {
-
tree.reload(
'treeId', {
data: getData()});
-
})
-
//返回 key 值
-
return ;
-
}
else
if(type ===
'update'){
//修改节点
-
$.post(
"dept/update", {
id: id,
name: name},
function () {
-
tree.reload(
'treeId', {
data: getData()});
-
})
-
}
else
if(type ===
'del'){
//删除节点
-
$.post(
"dept/delete", {
id: id},
function () {
-
tree.reload(
'treeId', {
data: getData()});
-
});
-
};
-
}
其中operate为操作节点回调方法。
obj.type为操作类型,add为新增,update为修改,edl为删除。obj.data为操作节点后的数据。
新增节点后,向后台发送请求添加节点,save方法和上面修改方法一样,id为新建节点的父级节点id。
修改节点,同样,向后台发送修改请求,并传递对象的id,和修改后的数据作为参数。后台响应方法。
-
@RequestMapping(value = "/update")
-
@ResponseBody
-
public Object update(DeptForm form) {
-
try {
-
Dept model = deptService.findById(form.getId());
-
model.setName(form.getName());
-
deptService.save(model);
-
return new AjaxResult(
"数据保存成功!");
-
}
catch (Exception e) {
-
return new AjaxResult(
false,
"数据保存失败");
-
}
-
}
删除节点同理,传递删除节点的id。删除请求方法。
-
@RequestMapping(value=
"/delete")
-
@ResponseBody
-
public Object delete(Integer id) {
-
try {
-
deptService
.deleteById(id);
-
return
new
AjaxResult(
"数据删除成功");
-
}
catch (Exception e) {
-
return
new
AjaxResult(false,
"数据删除失败");
-
}
-
}
使用按钮操作树形菜单。
现在页面中定义两个按钮,给按钮添加lay-demo=""属性,并设置属性值,JS通过这个属性值,绑定点击事件。
-
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept">
<i class="layui-icon">

</i>添加部门
</button>
-
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">获取选中节点
</button>
绑定添加部门和获取选中节点按钮的点击事件的JS代码。
-
util.event(
'lay-demo', {
-
addDept:
function(othis){
-
$.get(
'dept/edit',
function(data) {
-
layer.open({
-
type:
1,
-
title:
'新增',
-
area: [
'530px'],
-
content: data,
-
btn: [
'提交',
'退出'],
-
yes:
function () {
-
},
-
success:
function (layero, index) {
-
layui.use(
'form',
function () {
-
var form = layui.form;
-
layero.addClass(
'layui-form');
-
var submitBtn = layero.find(
'.layui-layer-btn0');
-
submitBtn.attr(
'lay-filter',
'formVerify').attr(
'lay-submit',
'');
-
layero.keydown(
function (e) {
-
if (e.keyCode ==
13) {
-
submitBtn.click();
-
}
-
});
-
-
form.on(
'submit(formVerify)',
function (data) {
-
$.post(
'dept/save', data.field,
function (result) {
-
if (result.success) {
-
layer.close(index);
-
tree.reload(
'treeId', {
data: getData()});
-
}
-
layer.msg(result.msg, {
offset:
'rb'});
-
});
-
return
false;
-
});
-
});
-
}
-
})
-
})
-
},
-
gain:
function () {
-
var checkData = tree.getChecked(
'treeId');
-
var str =
JSON.stringify(checkData);
-
$.post(
'dept/checkedGain', {
data: str},
function () {
-
});
-
layer.alert(
JSON.stringify(checkData), {
shade:
0});
-
}
-
});
添加部门按钮点击事件,先发送请求到后台,跳转到eidt新增页面,edit.html新增页面代码,和上面的show.html显示部门详情页面差不多。上级部门同样使用的LayUI下拉树显示的,下拉树数据请求方法,和上面的详情页面下拉树请求方法一致。LayUI下拉树TreeSelect的使用。新增后的保存方法也和上面的保存方法一致。
后台请求方法代码,跳转到edit页面。
-
@RequestMapping(
value =
"/edit")
-
public void edit(){
-
-
}
edit.html页面完整代码如下。
-
<meta charset="UTF-8" />
-
<style type="text/css">
-
.myData
.layui-form-item{
-
margin:
20px
100px
10px
45px;
-
}
-
.myData
.layui-form-label{
-
width:
85px;
-
}
-
.layui-input-block {
-
margin-left:
120px;
-
}
-
</style>
-
<form class="layui-form myData" action="save" method="post" lay-filter="stuform">
-
-
<div class="layui-form-item">
-
<label class="layui-form-label">上级部门:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="parentId" id="tree2" lay-filter="tree2" class="layui-input" />
-
</div>
-
</div>
-
<div class="layui-form-item">
-
<label class="layui-form-label">部门名称:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="name" lay-verify="required" class="layui-input" />
-
</div>
-
</div>
-
<div class="layui-form-item" >
-
<label class="layui-form-label">部门负责人:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="deptName" class="layui-input" />
-
</div>
-
</div>
-
<div class="layui-form-item" >
-
<label class="layui-form-label">电话:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="phone" class="layui-input" />
-
</div>
-
</div>
-
<div class="layui-form-item" >
-
<label class="layui-form-label">编号:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="number" class="layui-input" />
-
</div>
-
</div>
-
<div class="layui-form-item" >
-
<label class="layui-form-label">排序:
</label>
-
<div class="layui-input-block">
-
<input type="text" name="idx" value="0" class="layui-input" />
-
</div>
-
</div>
-
</form>
-
-
<script th:inline="javascript">
-
layui.use([
"treeSelect",
"form"],
function () {
-
var form = layui.form;
-
form.render(
'select');
-
var treeSelect = layui.treeSelect;
-
treeSelect.render({
-
// 选择器
-
elem:
'#tree2',
-
// 数据
-
data:
'dept/treeSelect',
-
// 异步加载方式:get/post,默认get
-
type:
'post',
-
// 占位符
-
placeholder:
'上级菜单',
-
// 是否开启搜索功能:true/false,默认false
-
search:
true,
-
// 一些可定制的样式
-
style: {
-
folder: {
-
enable:
true
-
},
-
line: {
-
enable:
true
-
}
-
},
-
// 加载完成后的回调函数
-
success:
function (d) {
-
}
-
});
-
});
-
</script>
页面效果。
获取选中节点按钮点击事件。如果项目需要保存数据时,就需要获取到选中节点的数据了。这里可以获取到选中节点的数据,之后当参数传递到后台。传递到后台是一个JSON数据的字符串,需要转换一下,这里给推荐大家两个很好用的JSON转换工具net.sf.json.JSONObject和Alibaba Fastjson。这里用的是Alibaba Fastjson,需要引入以下依赖。
-
<dependency>
-
<groupId>com.alibaba
</groupId>
-
<artifactId>fastjson
</artifactId>
-
<version>1.2.47
</version>
-
</dependency>
这里用于输出,新建了一个和tree的json数据的键名称一样的工具类DeptTree,代码如下。
-
import java.util.ArrayList;
-
import java.util.List;
-
-
public
class DeptTree {
-
private Integer id;
-
private String title;
-
private
boolean checked;
-
private
boolean spread;
-
private List<DeptTree> children =
new ArrayList<>();
-
-
public Integer getId() {
-
return id;
-
}
-
-
public void setId(Integer id) {
-
this.id = id;
-
}
-
-
public String getTitle() {
-
return title;
-
}
-
-
public void setTitle(String title) {
-
this.title = title;
-
}
-
-
public List<DeptTree> getChildren() {
-
return children;
-
}
-
-
public void setChildren(List<DeptTree> children) {
-
this.children = children;
-
}
-
-
public boolean isChecked() {
-
return checked;
-
}
-
-
public void setChecked(boolean checked) {
-
this.checked = checked;
-
}
-
-
public boolean isSpread() {
-
return spread;
-
}
-
-
public void setSpread(boolean spread) {
-
this.spread = spread;
-
}
-
}
后台接收到传递过来的JSON数据字符串,转换后输出方法。
-
@RequestMapping(value = "/checkedGain")
-
@ResponseBody
-
public void checkedGain(String
data){
-
List<DeptTree> array2 = JSONArray.parseArray(
data, DeptTree.
class);
-
treeData(array2);
-
}
-
-
//递归输出选中数据
-
private void treeData(List<DeptTree> array2) {
-
for (DeptTree tree: array2){
-
System.
out.println(tree.getTitle()+
"==="+tree.getId());
-
if(tree.getChildren() !=
null){
-
treeData(tree.getChildren());
-
}
-
}
-
}
选中节点,点击获取选中节点数据。
后台对应方法接收到数据,转换后输出结果。
数据拿到了,之后保存方法就简单了。
后台方法代码基本都在上面了,页面全部代码。
-
<style type="text/css">
-
#dept_main,
#dept_particulars{
-
width:
48.5%;
-
display: inline-block;
-
vertical-align: top;
-
padding:
20px;
-
background: white;
-
box-sizing: border-box;
-
}
-
#dept_tree{
-
margin-top:
20px;
-
}
-
</style>
-
-
<div id="dept_main" style="margin-right: 2%;">
-
<fieldset class="layui-elem-field layui-field-title">
-
<legend>所有部门
</legend>
-
</fieldset>
-
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept">
<i class="layui-icon">

</i>添加部门
</button>
-
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">获取选中节点
</button>
-
<div id="dept_tree">
-
-
</div>
-
</div>
-
<div id="dept_particulars">
-
<fieldset class="layui-elem-field layui-field-title">
-
<legend>部门详情
</legend>
-
</fieldset>
-
<div id="dept_home">
-
<div class="layui-tree-emptyText">无数据
</div>
-
</div>
-
</div>
-
-
<script type="text/javascript">
-
layui.use([
'tree',
'util',
'layer'],
function() {
-
var tree = layui.tree;
-
var util = layui.util;
-
var layer = layui.layer;
-
tree.render({
-
elem:
'#dept_tree',
-
data: getData(),
-
id:
'treeId',
-
showCheckbox:
true,
//时候显示复选框
-
onlyIconControl:
true,
-
edit: [
'add',
'update',
'del'],
//操作节点的图标
-
click:
function (obj) {
-
var id = obj.data.id;
-
$(
"#dept_home").load(
"dept/show?id="+id);
-
},
-
operate:
function(obj){
-
var type = obj.type;
//得到操作类型:add、edit、del
-
var data = obj.data;
//得到当前节点的数据
-
var elem = obj.elem;
//得到当前节点元素
-
-
var id = data.id;
-
var name = data.title;
-
if(type ===
'add'){
//增加节点
-
$.post(
"dept/save", {
parentId: id,
name:
"未命名"},
function (result) {
-
tree.reload(
'treeId', {
data: getData()});
-
})
-
//返回 key 值
-
return ;
-
}
else
if(type ===
'update'){
//修改节点
-
$.post(
"dept/update", {
id: id,
name: name},
function () {
-
tree.reload(
'treeId', {
data: getData()});
-
})
-
}
else
if(type ===
'del'){
//删除节点
-
$.post(
"dept/delete", {
id: id},
function () {
-
tree.reload(
'treeId', {
data: getData()});
-
});
-
};
-
}
-
});
-
-
util.event(
'lay-demo', {
-
addDept:
function(othis){
-
$.get(
'dept/edit',
function(data) {
-
layer.open({
-
type:
1,
-
title:
'新增',
-
area: [
'530px'],
-
content: data,
-
btn: [
'提交',
'退出'],
-
yes:
function () {
-
},
-
success:
function (layero, index) {
-
layui.use(
'form',
function () {
-
var form = layui.form;
-
layero.addClass(
'layui-form');
-
var submitBtn = layero.find(
'.layui-layer-btn0');
-
submitBtn.attr(
'lay-filter',
'formVerify').attr(
'lay-submit',
'');
-
layero.keydown(
function (e) {
-
if (e.keyCode ==
13) {
-
submitBtn.click();
-
}
-
});
-
-
form.on(
'submit(formVerify)',
function (data) {
-
$.post(
'dept/save', data.field,
function (result) {
-
if (result.success) {
-
layer.close(index);
-
tree.reload(
'treeId', {
data: getData()});
-
}
-
layer.msg(result.msg, {
offset:
'rb'});
-
});
-
return
false;
-
});
-
});
-
}
-
})
-
})
-
},
-
gain:
function () {
-
var checkData = tree.getChecked(
'treeId');
-
var str =
JSON.stringify(checkData);
-
$.post(
'dept/checkedGain', {
data: str},
function () {
-
});
-
layer.alert(
JSON.stringify(checkData), {
shade:
0});
-
}
-
});
-
});
-
-
function getData(){
-
var data = [];
-
$.ajax({
-
url:
"dept/treeload",
//后台数据请求地址
-
type:
"post",
-
async:
false,
-
success:
function(resut){
-
data = resut;
-
}
-
});
-
return data;
-
}
-
-
</script>
如果对你有帮助,点赞关注一下呗^_^,留下你的足迹。