首页IT科技layui的特点(LayUI树形表格treetable使用及说明)

layui的特点(LayUI树形表格treetable使用及说明)

时间2025-04-28 07:09:19分类IT科技浏览3280
导读:LayUI是现在比较流行的一款前端框架 也有很多人基于LayUI开发了很多不错的组件,比如treetable树形表格。...

LayUI是现在比较流行的一款前端框架

也有很多人基于LayUI开发了很多不错的组件           ,比如treetable树形表格           。

因为treetable是第三方基于LayUI开发的                  ,所以需要先用Layui引入一下文件                  。

layui.config({ base : static/layui/ }).extend({ treetable : treetable-lay/treetable });

之后先看一下显示的效果     。

之后页面只需要引入LayUI的CSS和JS就可以了        。

页面给一个table标签     ,用于显示treetable中的数据样式                  。

<table class="layui-hide" id = "menu" lay-filter="menu"></table>

表格左上方的工具栏按钮组件代码        。

<script type="text/html" id="toolbarDemo"> <div class="layui-btn-group"> <button class="layui-btn layui-btn-sm" lay-event="add"><i class="layui-icon">&#xe654;</i>新增</button> <button class="layui-btn layui-btn-sm" lay-event="updata"><i class="layui-icon">&#xe642;</i>修改</button> <button class="layui-btn layui-btn-sm" lay-event="delete"><i class="layui-icon">&#xe640;</i>删除</button> <button class="layui-btn layui-btn-sm" lay-event="refresh"><i class="layui-icon">&#xe666;</i>刷新</button> </div> </script>

JS请求加载数据及设置表格样式     。

yui.use([treetable, table, layer], function () { var table = layui.table; var layer = layui.layer; var treetable = layui.treetable; //渲染表格 var renderTable = function(){ layer.load(2); //加载层 treetable.render({ height: full-160, id:menu, treeColIndex: 1, //树形图标显示在第几列 treeSpid: 0, //最上级的父级id treeIdName: id, //id字段的名称 treePidName: parentId, //父级节点字段 treeDefaultClose: false, //是否默认折叠 treeLinkage: false, //父级展开时是否自动展开所有子级 elem: #menu, //表格id url: menu/treedata, toolbar: #toolbarDemo, page: false, cols: [ [ {type:radio}, {field: name, title: 菜单名称}, {field: url , title: 地址}, {field: icon , hide : true, title: 图标}, {field: idx, title: 排序} ] ], //数据渲染完的回调 done: function () { //关闭加载 layer.closeAll(loading); } }) }; renderTable(); });

其中URL地址为请求数据地址                  。后台对应的方法           。

@RequestMapping(value="/treedata") @ResponseBody public Object list(TbMenuForm form){ Sort sort = bulidSort(); //排序 Specification<TbMenu> spec = buildSpec(form); //查询条件 List<TbMenu> list = menuService.findAll(spec, sort); return new TreeTableModel(list); } public Sort bulidSort() { return Sort.by("idx"); //按idx字段排序 } public Specification<TbMenu> buildSpec(TbMenuForm form){ return null; }

list方法中的TbMenuForm接收类中的字段和实体类字段差不多  。其中TreeTableModel返回类为返回数据格式的工具类                 。

实体类TbMenu代码

import com.fasterxml.jackson.annotation.JsonIgnore; import org.springframework.data.annotation.CreatedBy; import javax.persistence.*; import java.util.ArrayList; import java.util.List; @Entity public class TbMenu { private Integer id; private String name; //菜单名称 private String url; //路径 private String icon; //图标 private double idx; //排序 @JsonIgnore private TbMenu parent; @JsonIgnore private List<TbMenu> 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 getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public double getIdx() { return idx; } public void setIdx(double idx) { this.idx = idx; } @ManyToOne @CreatedBy public TbMenu getParent() { return parent; } public void setParent(TbMenu parent) { this.parent = parent; } @OneToMany(cascade=CascadeType.ALL,mappedBy="parent") @OrderBy(value="idx") public List<TbMenu> getChildren() { return children; } public void setChildren(List<TbMenu> children) { this.children = children; } public TbMenu(Integer id, String name, String url, String icon, double idx, TbMenu parent, List<TbMenu> children) { this.id = id; this.name = name; this.url = url; this.icon = icon; this.idx = idx; this.parent = parent; this.children = children; } public TbMenu(Integer id) { this.id = id; } public TbMenu() { } @Transient public Integer getParentId() { return parent==null? 0 : parent.getId(); } }

TbMenuForm接收类

public class TbMenuForm { private Integer id; private String name; //菜单名称 private String url; //路径 private String icon; //图标 private double idx; //排序 private Integer parentId; //父节点id 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 getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public double getIdx() { return idx; } public void setIdx(double idx) { this.idx = idx; } public Integer getParentId() { return parentId; } public void setParentId(Integer parentId) { this.parentId = parentId; } }

返回数据格式TreeTableModel类

public class TreeTableModel { private Integer code=0; private String msg="ok"; private Integer count; private List data; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } public List getData() { return data; } public void setData(List data) { this.data = data; } public TreeTableModel() { super(); // TODO Auto-generated constructor stub } public TreeTableModel(Integer code, String msg, Integer count, List data) { super(); this.code = code; this.msg = msg; this.count = count; this.data = data; } public TreeTableModel(List data) { super(); this.count=data.size(); this.data = data; } }

返回的JSON数据格式        ,这里需要注意的是parentId为父节点                  ,需要和前面的JS中设置的属性值一样        ,没有父级节点parentId需要为0     ,不能为null              。

{ "code": 0, "msg": "ok", "count": 6, "data": [ { "id": 1, "name": "系统设置", "url": "", "icon": "", "idx": 1.0, "parentId": 0 //最上级节点                  ,父节点为0 }, { "id": 2, "name": "角色管理", "url": "", "icon": "", "idx": 1.0, "parentId": 1 //上级节点 }, { "id": 6, "name": "数据表格", "url": "", "icon": "", "idx": 1.0, "parentId": 5 }, { "id": 3, "name": "部门管理", "url": "", "icon": "", "idx": 2.0, "parentId": 1 }, { "id": 5, "name": "表格案例", "url": "", "icon": "", "idx": 2.0, "parentId": 0 }, { "id": 7, "name": "树形表格", "url": "", "icon": "", "idx": 2.0, "parentId": 5 } ] }

数据加载完成后           ,页面中就可以显示出数据了  ,效果如下。

使用table.on(toolbar(menu), function(obj){})监听表格上面的工具类按钮点击事件              。

监听工具栏的新增修改删除和刷新按钮方法

table.on(toolbar(menu), function(obj){ var checkStatus = table.checkStatus(menu); var data = checkStatus.data; if(obj.event === add){ var parentId = data.length==0? 0 : data[0].id; $.get(menu/edit, {parentId: parentId}, 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(menu/save,data.field,function(result){ if(result.success){ layer.close(index); //刷新                 ,重新渲染表格 renderTable(); } layer.msg(result.msg,{offset:rb}); }); return false; }); }); } }) }) }else if(obj.event === updata){ if(data.length != 1){ layer.msg("请选择一行进行编辑",{offset:rb}); }else{ var id = data[0].id; $.get(menu/edit, {id: id}, 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(menu/save,data.field,function(result){ if(result.success){ layer.close(index); //刷新              ,重新渲染表格 renderTable(); } layer.msg(result.msg,{offset:rb}); }); return false; }); }); } }) }) } }else if(obj.event === "delete"){ if(data.length != 1){ layer.msg("请选择一行进行删除",{offset:rb}); }else{ var id = data[0].id; layer.confirm(确定删除选定行的数据吗?, function(index){ $.post(menu/delete,{id:id},function(result){ if(result.success){ layer.close(index); renderTable(); } layer.msg(result.msg,{offset:rb}); }); }); } }else if(obj.event === "refresh"){ renderTable(); } })

其中obj.event值为点击工具栏按钮的lay-event属性值                 。

新增和修改方法,先请求后台menu/edit获取到新增修改的页面              ,把页面用LayUI的layer弹框显示出来  。这里新增和修改用的是一个方法和一个页面           。修改时传递了一个id参数                 ,用于查询修改的数据和区别新增还是修改                  。新增时如果选中了一行  ,会把当前行的id作为参数           ,传递到后台                  ,相当于默认的父节点id     。

跳转到新增和修改页面的edit后台方法        。如果修改就把当前修改的数据传递到前台     ,新增时        ,如果有选中的节点                  ,就把选中节点的id作为父节点id传递到前台                  。

@Override public void edit(TbMenuForm form, ModelMap map) throws InstantiationException, IllegalAccessException { TbMenu model = new TbMenu(); Integer id = form.getId(); if(id != null) { model = menuService.findById(id); } map.put("model", model); //修改的对象        ,如果新增model就为null map.put("parentId", form.getParentId()); //父节点id }

edit页面代码     ,上级菜单是用LayUI的TreeSelect做的                  ,对于TreeSelect的用法           ,大家可以访问LayUI下拉树TreeSelect的使用        。

<style type="text/css"> .myData .layui-form-item{ margin: 20px 100px 10px 45px; } .myData .layui-form-label{ width: 80px; } </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="url" th:value="${model.url}" 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="icon" th:value="${model.icon}" 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" th:value="${model.idx}" 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: #tree, // 数据 data: menu/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); } }); }); </script>

menu/treeSelect加载TreeSelect数据     。对于TreeSelect的用法,大家可以访问LayUI下拉树TreeSelect的使用                  。

@RequestMapping(value="/treeSelect") @ResponseBody public Object treeSelect(Integer id) { Sort sort = Sort.by("idx"); //排序 Specification<TbMenu> spec = buildSpec1(); //查询条件              ,可以自行添加                 ,对应的buildSpec1方法 List<TbMenu> list = menuService.findAll(spec,sort); return buildTree(list, id); } private Object buildTree(List<TbMenu> list, Integer id) { List<HashMap<String, Object>> result=new ArrayList<>(); for (TbMenu 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<TbMenu> buildSpec1() { Specification<TbMenu> specification = new Specification<TbMenu>() { private static final long serialVersionUID = 1L; @Override public Predicate toPredicate(Root<TbMenu> 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; }

页面显示效果           。

后台保存方法

@Override public Object save(TbMenuForm form) { try { TbMenu model = new TbMenu(); Integer id = form.getId(); if(id != null) { model = menuService.findById(id); } //父级菜单id Integer parentId = form.getParentId(); if(parentId == null) { model.setParent(null); }else { model.setParent(new TbMenu(parentId)); } BeanUtils.copyProperties(form, model,"id", "parent"); menuService.save(model); return new AjaxResult("数据保存成功!"); } catch (Exception e) { return new AjaxResult(false,"数据保存失败"); } }

AjaxResult类是一个请求完成返回的一个工具类  。

import java.util.HashMap; import org.springframework.data.domain.Page; public class AjaxResult { private Boolean success; private String msg; public Boolean getSuccess() { return success; } public void setSuccess(Boolean success) { this.success = success; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public AjaxResult(String msg) { super(); this.success=true; this.msg = msg; } public AjaxResult(Boolean success, String msg) { super(); this.success = success; this.msg = msg; } public AjaxResult(boolean success) { this.success=success; } @SuppressWarnings("rawtypes") public static HashMap<String, Object> bulidPageResult(Page page) { HashMap<String, Object> result=new HashMap<>(); result.put("total", page.getTotalElements()); result.put("rows", page.getContent()); return result; } }

新增和修改就完了           ,下面就是删除数据                 。删除需要先判断是否选中了一行              。然后把选中行的id作为参数                  ,传递到后台     ,根据id删除数据就可以了。

if(data.length != 1){ layer.msg("请选择一行进行删除",{offset:rb}); }else{ var id = data[0].id; layer.confirm(确定删除选定行的数据吗?, function(index){ $.post(menu/delete,{id:id},function(result){ if(result.success){ layer.close(index); renderTable(); } layer.msg(result.msg,{offset:rb}); }); }); }

最后一个就是刷新了        ,刷新只需要把表格刷新一下就可以了                  ,调用一下表格刷新方法              。

renderTable();

这里持久层框架用的Spring-Data-Jpa        ,但只要数据传递到后台了     ,怎么处理都差不多                  ,请求的数据只要按照规定的JSON格式返回就可以了                 。后台方法代码上面基本的有           ,前台页面代码有些零散  ,下面是显示页面完整代码  。

<script type="text/html" id="toolbarDemo"> <div class="layui-btn-group"> <button class="layui-btn layui-btn-sm" lay-event="add"><i class="layui-icon">&#xe654;</i>新增</button> <button class="layui-btn layui-btn-sm" lay-event="updata"><i class="layui-icon">&#xe642;</i>修改</button> <button class="layui-btn layui-btn-sm" lay-event="delete"><i class="layui-icon">&#xe640;</i>删除</button> <button class="layui-btn layui-btn-sm" lay-event="refresh"><i class="layui-icon">&#xe666;</i>刷新</button> </div> </script> <table class="layui-hide" id = "menu" lay-filter="menu"></table> <script type="text/javascript"> layui.use([treetable, table, layer], function () { var table = layui.table; var layer = layui.layer; var treetable = layui.treetable; //渲染表格 var renderTable = function(){ layer.load(2); //加载层 treetable.render({ height: full-160, id:menu, treeColIndex: 1, //树形图标显示在第几列 treeSpid: 0, //最上级的父级id treeIdName: id, //id字段的名称 treePidName: parentId, //pid字段的名称                 ,父级菜单id treeDefaultClose: false, //是否默认折叠 treeLinkage: false, //父级展开时是否自动展开所有子级 elem: #menu, //表格id url: menu/treedata, toolbar: #toolbarDemo, page: false, cols: [ [ {type:radio}, {field: name, title: 菜单名称}, {field: url , title: 地址}, {field: icon , hide : true, title: 图标}, {field: idx, title: 排序} ] ], //数据渲染完的回调 done: function () { //关闭加载 layer.closeAll(loading); } }) }; renderTable(); table.on(toolbar(menu), function(obj){ var checkStatus = table.checkStatus(menu); var data = checkStatus.data; if(obj.event === add){ var parentId = data.length==0? 0 : data[0].id; $.get(menu/edit, {parentId: parentId}, 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(menu/save,data.field,function(result){ if(result.success){ layer.close(index); //刷新              ,重新渲染表格 renderTable(); } layer.msg(result.msg,{offset:rb}); }); return false; }); }); } }) }) }else if(obj.event === updata){ if(data.length != 1){ layer.msg("请选择一行进行编辑",{offset:rb}); }else{ var id = data[0].id; $.get(menu/edit, {id: id}, 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(menu/save,data.field,function(result){ if(result.success){ layer.close(index); //刷新,重新渲染表格 renderTable(); } layer.msg(result.msg,{offset:rb}); }); return false; }); }); } }) }) } }else if(obj.event === "delete"){ if(data.length != 1){ layer.msg("请选择一行进行删除",{offset:rb}); }else{ var id = data[0].id; layer.confirm(确定删除选定行的数据吗?, function(index){ $.post(menu/delete,{id:id},function(result){ if(result.success){ layer.close(index); renderTable(); } layer.msg(result.msg,{offset:rb}); }); }); } }else if(obj.event === "refresh"){ renderTable(); } }) }) </script>

推荐文章              ,LayUI树形结构tree的使用

以上为个人经验                 ,希望能给大家一个参考  ,也希望大家多多支持本站           。

声明:本站所有文章           ,如无特殊说明或标注                  ,均为本站原创发布                  。任何个人或组织     ,在未征得本站同意时        ,禁止复制            、盗用                、采集      、发布本站内容到任何网站         、书籍等各类媒体平台     。如若本站内容侵犯了原著者的合法权益                  ,可联系我们进行处理        。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
anaconda里面jupyter打不开(通过anaconda升级、安装jupyter notebook内核kernel的python版本) 采集软件是不是真的(采集工具-采集软件-免费采集工具下载)