Layui 内置模块 (一) 数据表格 table

Layui 官网地址
table 数据表格文档 - layui.table
table 官方示例

简介

模块加载名称:table

table 模块是我们的又一走心之作,在 layui 2.0 的版本中全新推出,是 layui 最核心的组成之一。它用于对表格进行一些列功能和动态化数据操作,涵盖了日常业务所涉及的几乎全部需求。支持固定表头、固定行、固定列左/列右,支持拖拽改变列宽度,支持排序,支持多级表头,支持单元格的自定义模板,支持对表格重载(比如搜索、条件筛选等),支持复选框,支持分页,支持单元格编辑等等一些列功能。尽管如此,我们仍将对其进行完善,在控制代码量和性能的前提下,不定期增加更多人性化功能。table 模块也将是 layui 重点维护的项目之一。

数据接口

可参考:返回的数据

方法渲染

其实这是“自动化渲染”的手动模式,本质类似,只是“方法级渲染”将基础参数的设定放在了JS代码中,且原始的 table 标签只需要一个选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
<table id="demo" lay-filter="test"></table>

<script>
var table = layui.table;

//执行渲染
table.render({
elem: '#demo' //指定原始表格元素选择器(推荐id选择器)
,height: 315 //容器高度
,cols: [{}] //设置表头
//,…… //更多参数参考右侧目录:基本参数选项
});
</script>

事实上我们更推荐采用“方法级渲染”的做法,其最大的优势在于你可以脱离HTML文件,而专注于JS本身。尤其对于项目的频繁改动及发布,其便捷性会体现得更为明显。

templet - 自定义列模板

在默认情况下,单元格的内容是完全按照数据接口返回的content原样输出的,如果你想对某列的单元格添加链接等其它元素,你可以借助该参数来轻松实现。这是一个非常实用且强大的功能,你的表格内容会因此而丰富多样。

toolbar - 绑定列工具条

通常你需要在表格的每一行加上 查看、编辑、删除 这样类似的操作按钮,而 tool 参数就是为此而生,你因此可以非常便捷地实现各种操作功能。tool 参数和 templet 参数的使用方式完全类似,通常接受的是一个选择器,也可以是一段HTML字符。

基础方法

table.set(options); //设定全局默认参数。options即各项基础参数
table.on(‘event(filter)’, callback); //事件监听。event为内置事件名(详见下文),filter为容器lay-filter设定的值
table.init(filter, options); //filter为容器lay-filter设定的值,options即各项基础参数。例子见:转换静态表格
table.checkStatus(id); //获取表格选中行(下文会有详细介绍)。id 即为 id 参数对应的值
table.render(options); //用于表格方法级渲染,核心方法。应该不用再过多解释了,详见:方法级渲染
table.reload(id, options); //表格重载
table.resize(id); //重置表格尺寸
table.exportFile(id, data, type); //导出数据

数据接口实现

记录重要步骤,如下:

JSON 工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class JsonUtils {

/**
* 格式化用户列表
*/
public JSONObject jsonObject(IPage userIPage) {

JSONObject jsonObject = new JSONObject();
jsonObject.put("code", 0);
jsonObject.put("msg", "");
jsonObject.put("count", userIPage.getTotal());
jsonObject.put("data", userIPage.getRecords());

return jsonObject;
}
}
  1. 用于格式化返回的数据,跟上文的格式保持一致。
  2. 传入分页数据。

控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* 用户列表操作
*/
@ApiOperation(value = "用户列表操作")
@ApiImplicitParams({
@ApiImplicitParam(name = "userName", value = "根据userName模糊查询", paramType = "query"),
@ApiImplicitParam(name = "page", value = "分页", dataType = "Integer"),
@ApiImplicitParam(name = "limit", value = "每页显示的条数", dataType = "Integer")
})
@GetMapping("/userDate")
@ResponseBody
public JSONObject userDate(int page, int limit,
@RequestParam(value = "keyword", required = false) String userName) {

JsonUtils jsonUtils = new JsonUtils();

/**
* 如果 userName 为空就执行全部搜索
*/
if (StrUtil.hasEmpty(userName)) {
Page<SysUser> pages = new Page<>(page, limit);
IPage<SysUser> userIPage = sysUserService.page(pages, null);
return jsonUtils.jsonObject(userIPage);
}

/**
* 如果 userName 不为空就执行模糊搜索
*/
Page<SysUser> pages = new Page<>(page, limit);
IPage<SysUser> userIPage = sysUserService.page(pages, new QueryWrapper<SysUser>().like("user_name", userName));

return jsonUtils.jsonObject(userIPage);
}
  1. 根据keyword查询(可选),若keyword为空则执行全部搜索,不为空则执行模糊搜索。
  2. StrUtil类由Hutool提供。
  3. 返回JSON数据。

前端 - html

1
2
3
4
5
6
7
8
9
10
11
12
<div class="search">
<span>模糊搜索:</span>
<div class="layui-inline">
<input class="layui-input" id="keyword" autocomplete="off" placeholder="请输入用户名">
</div>
<button class="layui-btn layui-btn-normal" data-type="reload">搜索</button>
</div>

<div class="layui-row">
<!--lay-filter稍后用于绑定相应事件使用-->
<table id="table" lay-filter="test"></table>
</div>
  1. 注意第一个<div>的class值为search
  2. 模糊搜索<input>的id值为keyword
  3. 搜索<button>的data-type值为reload
  4. 表格<table>的lay-filter值为test

前端 - script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!--用于绑定表格外加上操作按钮-->
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<shiro:hasPermission name="sysUser:add">
<button class="layui-btn layui-btn-sm" lay-event="add">新增用户</button>
</shiro:hasPermission>
<button class="layui-btn layui-btn-sm" lay-event="getCheckData">获取选中行数据</button>
<button class="layui-btn layui-btn-sm" lay-event="getCheckLength">获取选中数目</button>
</div>
</script>

<!--用于绑定表格行内加上操作按钮-->
<script type="text/html" id="barDemo">
<shiro:hasPermission name="sysUser:edit">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
</shiro:hasPermission>
<shiro:hasPermission name="sysUser:del">
<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a>
</shiro:hasPermission>
</script>
  1. toolbarDemo用于绑定表格外加上操作按钮
  2. barDemo用于绑定表格行内加上操作按钮
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<script th:inline="none">
layui.use('table', function () {
var table = layui.table;

// table.render()方法返回一个对象:var tableIns = table.render(options),可用于对当前表格进行“重载”等操作
table.render({
skin: 'line', //行边框风格
// ,even: true //开启隔行背景
// ,size: 'sm' //小尺寸的表格
elem: '#table' // 表格id
, url: '/sysUser/user/userDate' // 上文的控制器
, title: '用户数据表'
, toolbar: "#toolbarDemo" // 表格外操作按钮
, page: true
, limits: [10, 20, 50, 100]
, id: 'tableDate'
, cellMinWidth: 60
, cols: [[
{type: 'checkbox', fixed: 'left'}
, {field: 'userId', title: '编号', sort: true}
, {field: 'userName', title: '用户名'}
, {field: 'email', title: '邮箱'}
, {field: 'userType', title: '用户类型', align: 'center', templet: '#userTypeTpl'}
, {field: 'state', title: '用户状态', align: 'center', sort: true, templet: '#stateTpl'}
, {field: 'createTime', title: '创建时间'}
, {field: 'updateTime', title: '更新时间'}
, {field: 'remark', title: '备注'}
, {fixed: 'right', title: '操作', width: 120, align:'center', toolbar: '#barDemo'}
]]
});

// 搜索功能
var $ = layui.$, active = {
reload: function () {
var keyword = $('#keyword');
table.reload('tableDate', {
//从第 1 页开始
page: {
curr: 1
}
//设定异步数据接口的额外参数
, where: {
keyword: keyword.val()
}
});
}
};

// 点击搜索
$('.search .layui-btn').on('click', function () {
var type = $(this).data('type');
active[type] ? active[type].call(this) : '';
});

// 头工具栏事件
table.on('toolbar(test)', function (obj) {
var checkStatus = table.checkStatus(obj.config.id);
switch (obj.event) {
case 'getCheckData':
var data = checkStatus.data;
layer.alert(JSON.stringify(data));
break;
case 'getCheckLength':
var data = checkStatus.data;
layer.msg('选中了: ' + data.length + ' 个')
break;
case 'add':
addUser();
break;
};
});

// 监听行工具事件
// 绑定查删改事件test对于table中的lay-filter的值
table.on('tool(test)', function (obj) {
var data = obj.data;
if (obj.event == 'del') {
layer.confirm('真的删除么?',{
skin: 'layui-layer-lan'
,closeBtn: 0
,anim: 4 //动画类型
}, function (index) {
delUser(data.userId);
layer.close(index);
});
} else if (obj.event == 'edit') {
editUser(data.userId);
}
});

// 新增用户信息
function addUser() {
layer.open({
area: ['45%', '80%'], //宽高
type: 2,
fix: false, //不固定
maxmin: true,
content: '/sysUser/user/add'
});
}

// 修改用户信息
function editUser(userId) {
layer.open({
area: ['45%', '80%'], //宽高
type: 2,
fix: false, //不固定
maxmin: true,
content: '/sysUser/user/edit/' + userId,
});
};

// 删除用户信息
function delUser(userId) {
$.ajax({
url: "/sysUser/user/del/" + userId,
type: "delete",
success: function (result) {
if (result.code == web_status.SUCCESS) {
layer.msg(result.msg, {
icon: 1,
time: 2000
}, function () {
location.reload();
});
} else {
layer.msg(result.msg, {
icon: 2
})
}
}
});
};
});

// /** 消息状态码 */
// web_status = {
// SUCCESS: 0,
// FAIL: 500
// };

</script>

<!--用户状态tpl-->
<script type="text/html" id="stateTpl">
{{# if(d.state == '0'){ }}
<span class="layui-badge layui-bg-green">正常</span>
{{# } else { }}
<span class="layui-badge layui-bg-orange">锁定</span>
{{# } }}
</script>

<!--用户类型tpl-->
<script type="text/html" id="userTypeTpl">
{{# if(d.userType == 1) { }}
<span class="layui-badge-rim">管理员</span>
{{# } else if (d.userType == 2) { }}
<span class="layui-badge-rim">VIP</span>
{{# } else {}}
<span class="layui-badge-rim">普通用户</span>
{{# } }}
</script>
  1. 通过 table.render() 方法指定该容器
  2. 其他参数可参考layui.table
  3. 用户状态请参考自定义列模板

效果