8. 基础参数一览表
8.1. 下面是目前table模块所支持的全部参数一览表:
9. cols - 表头参数一览表
10. templet - 自定义列模板
10.1. 类型: String, 默认值: 无。
10.2. 在默认情况下, 单元格的内容是完全按照数据接口返回的content原样输出的, 如果你想对某列的单元格添加链接等其它元素, 你可以借助该参数来轻松实现。这是一个非常实用且强大的功能, 你的表格内容会因此而丰富多样。
10.3. templet 提供了三种使用方式, 请结合实际场景选择最合适的一种:
10.3.1. 如果自定义模版的字符量太大, 我们推荐你采用[方式一]。
10.3.2. 如果自定义模板的字符量适中, 或者想更方便地调用外部方法, 我们推荐你采用[方式二]。
10.3.3. 如果自定义模板的字符量很小, 我们推荐你采用[方式三]。
10.4. 方式一: 绑定模版选择器。
<!-- 下面的{{d.id}}是动态内容, 它对应数据接口返回的字段名。 -->
<script type="text/html" id="checkboxTpl">
<input type="checkbox" name="lock" value="{{d.id}}" title="锁定" {{ d.id == 10002 ? 'checked' : '' }} />
</script>
<script type="text/javascript">
layui.use(['table'], function(){
var table = layui.table;
table.render({
elem: '#test1' // 指定原始table容器的选择器
,url: 'UserPage.action' // 异步数据接口相关参数
,cols: [[ // 设置表头
,{
field: 'lock', title: '是否锁定', templet: '#checkboxTpl' // 自定义列模板
}
]]
});
});
</script>
10.5. 方式二: 函数转义。
<script type="text/javascript">
layui.use(['table'], function(){
var table = layui.table;
table.render({
elem: '#test1' // 指定原始table容器的选择器
,url: 'UserPage.action' // 异步数据接口相关参数
,cols: [[ // 设置表头
{field: 'sex', title: '性别', templet: function(d){
return '<input type="checkbox" name="sex" lay-text="女|男" lay-skin="switch" value="' + d.sex + '"' + (d.sex == '女' ? 'checked' : '') + ' />';
}}
]]
});
});
</script>
10.6. 方式三: 直接赋值模版字符。
templet: '<div><a href="{{d.id}}">{{d.title}}</a></div>'
11. toolbar - 绑定工具条模板
11.1. 默认情况下, 表格头部工具栏区域左侧模板, 是添加、编辑、删除这样类似的操作按钮。如果你想添加或改变左侧模板, toolbar参数可以配合模板一块使用。
<!-- 工具栏模板: -->
<script type="text/html" id="toolbarTpl">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="add">添加</button>
<button class="layui-btn layui-btn-sm" lay-event="delete">删除</button>
<button class="layui-btn layui-btn-sm" lay-event="update">编辑</button>
</div>
</script>
<script type="text/javascript">
layui.use(['table'], function(){
var table = layui.table;
table.render({
elem: '#test3' // 指定原始table容器的选择器
,toolbar: '#toolbarTpl' // 开启表格头部工具栏区域
});
});
</script>
12. 异步数据接口
12.1. 数据的异步请求由以下几个参数组成:
13. done - 数据渲染完的回调
13.1. 类型: Function, 默认值: 无。
13.2. 无论是异步请求数据, 还是直接赋值数据, 都会触发该回调。你可以利用该回调做一些表格以外元素的渲染。
table.render({
done: function(res, curr, count){
// 如果是异步请求数据方式, res即为你接口返回的信息。
// 如果是直接赋值的方式, res即为: {data: [], count: 99}, data为当前页数据、count为数据总长度
console.log(res);
// 得到当前页码
console.log(curr);
// 得到数据总量
console.log(count);
}
});
14. defaultToolbar - 头部工具栏右侧图标
14.1. 类型: Array, 默认值: ["filter","exports","print"]。
14.2. 该参数可自由配置头部工具栏右侧的图标按钮, 值为一个数组, 支持以下可选值:
- filter: 显示筛选图标。
- exports: 显示导出图标。
- print: 显示打印图标。
14.3. 可根据值的顺序显示排版图标, 如:
defaultToolbar: ['filter', 'print', 'exports']
14.4. 另外你还可以无限扩展图标按钮:
table.render({
defaultToolbar: ["filter", "exports", "print", { // 该参数可自由配置头部工具栏右侧的图标按钮
title: '提示' // 标题
,layEvent: 'tips' // 事件名, 用于toolbar事件中使用
,icon: 'layui-icon-tips' // 图标类名
}]
});
15. text - 自定义文本
15.1. 类型: Object。
15.2. table模块会内置一些默认的文本信息, 如果想修改, 你可以设置以下参数达到目的。
table.render({ // 自定义文本, 如空数据时的异常提示等
text: {
none: '暂时还么有无数据' // 默认: 无数据。
}
});
16. initSort - 初始排序
16.1. 类型: Object, 默认值: 无。
16.2. 用于在数据表格渲染完毕时,默认按某个字段排序。排序方式, asc: 升序、desc: 降序、null: 默认排序。
table.render({
initSort: {
field: 'id' // 排序字段, 对应cols设定的各字段名
,type: 'desc' // 排序方式, asc: 升序、desc: 降序、null: 默认排序
}
});
17. height - 设定容器高度
17.1. 类型: Number/String, 可选值如下:
18. 设定表格外观
18.1. 控制表格外观的主要由以下参数组成:
18.2. 实例
table.render({ // 其它参数在此省略
skin: 'line' // 行边框风格
,even: true // 开启隔行背景
,size: 'sm' // 小尺寸的表格
});
19. 基础方法
19.1. 基础用法是table模块的关键组成部分, 目前所开放的所有方法如下:
> 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); // 导出数据。
20. 事件监听
20.1. 语法: table.on('event(filter)', callback); 注: event为内置事件名, filter为容器lay-filter设定的值。
20.2. table模块在Layui事件机制中注册了专属事件, 如果你使用layui.onevent()自定义模块事件, 请勿占用table名。
20.3. 默认情况下, 事件所监听的是全部的table模块容器, 但如果你只想监听某一个容器, 使用事件过滤器即可。
20.4. 假设原始容器为: <table class="layui-table" lay-filter="test"></table>那么你的事件监听写法如下:
// 以复选框事件为例
table.on('checkbox(test)', function(obj){
console.log(obj)
});
21. 监听头部工具栏事件
21.1. 点击头部工具栏区域设定了属性为lay-event=""的元素时触发。如:
<table id="test1" lay-filter="test1"></table>
table.on('toolbar(test2)', function(obj){
var checkStatus = table.checkStatus(obj.config.id);
switch(obj.event){
case 'add':
layer.msg('添加');
break;
case 'delete':
layer.msg('删除');
break;
case 'update':
layer.msg('编辑');
break;
};
});
22. 监听复选框选择
22.1. 点击复选框时触发, 回调函数返回一个object参数, 携带的成员如下:
table.on('checkbox(test1)', function(obj){
console.log(obj.checked); // 当前是否选中状态
console.log(obj.data); // 选中行的相关数据
console.log(obj.type); // 如果触发的是全选, 则为: all; 如果触发的是单选, 则为: one
});
23. 监听单元格编辑
23.1. 单元格被编辑, 且值发生改变时触发, 回调函数返回一个object参数, 携带的成员如下:
table.on('edit(test1)', function(obj){ // 注: edit是固定事件名, test是table原始容器的属性lay-filter="对应的值"
console.log(obj.value); // 得到修改后的值
console.log(obj.field); // 当前编辑的字段名
console.log(obj.data); // 所在行的所有相关数据
});
24. 监听行单双击事件
24.1. 点击或双击行时触发。
// 监听行单击事件
table.on('row(test2)', function(obj){
console.log(obj.tr) // 得到当前行元素对象
console.log(obj.data) // 得到当前行数据
// obj.del(); // 删除当前行
// obj.update(fields) // 修改当前行数据
});
// 监听行双击事件
table.on('rowDouble(test3)', function(obj){
console.log(obj.tr) // 得到当前行元素对象
console.log(obj.data) // 得到当前行数据
// obj.del(); // 删除当前行
// obj.update(fields) // 修改当前行数据
});
25. 监听排序切换
25.1. 点击表头排序时触发, 它通用在基础参数中设置autoSort: false时使用, 以完成服务端的排序, 而不是默认的前端排序。该事件的回调函数返回一个object参数, 携带的成员如下:
// 禁用前端自动排序, 以便由服务端直接返回排序好的数据
table.render({
elem: '#id'
,autoSort: false // 禁用前端自动排序。
});
// 监听排序事件
table.on('sort(test)', function(obj){ // 注: sort是工具条事件名, test是table原始容器的属性lay-filter="对应的值"
// 尽管我们的table自带排序功能, 但并没有请求服务端。
// 有些时候, 你可能需要根据当前排序的字段, 重新向服务端发送请求, 从而实现服务端排序, 如:
table.reload('idTest', {
initSort: obj // 记录初始排序, 如果不设的话, 将无法标记表头的排序状态。
,where: { // 请求参数
field: obj.field // 排序字段
,order: obj.type // 排序方式
}
});
layer.msg('服务端排序。order by ' + obj.field + ' ' + obj.type);
});
26. 表格重载
26.1. 很多时候, 你需要对表格进行重载。比如数据全局搜索。以下方法可以帮你轻松实现这类需求(可任选一种)。
27. 例子
27.1. 新建一个table_param.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>table参数 - layui</title>
<link rel="stylesheet" href="layui/css/layui.css">
<script type="text/javascript" src="layui/layui.js"></script>
</head>
<body>
<h2>仅开启工具栏, 不显示左侧模板</h2>
<table id="test1" lay-filter="test1"></table>
<h2>让工具栏左侧显示默认的内置模板</h2>
<table id="test2" lay-filter="test2"></table>
<h2>指向自定义工具栏模板选择器</h2>
<table id="test3" lay-filter="test3"></table>
<h2>跨行跨列表格</h2>
<table class="layui-table" lay-data="{}">
<thead>
<tr>
<th lay-data="{field:'username', width:80}" rowspan="2">联系人</th>
<th lay-data="{field:'amount', width:120}" rowspan="2">金额</th>
<th lay-data="{align:'center'}" colspan="3">地址</th>
</tr>
<tr>
<th lay-data="{field:'province', width:80}">省</th>
<th lay-data="{field:'city', width:120}">市</th>
<th lay-data="{field:'county', width:300}">详细</th>
</tr>
</thead>
</table>
<!-- 工具栏模板: -->
<script type="text/html" id="toolbarTpl">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="add">添加</button>
<button class="layui-btn layui-btn-sm" lay-event="delete">删除</button>
<button class="layui-btn layui-btn-sm" lay-event="update">编辑</button>
</div>
</script>
<!-- 下面的{{d.id}}是动态内容, 它对应数据接口返回的字段名。 -->
<script type="text/html" id="checkboxTpl">
<input type="checkbox" name="lock" value="{{d.id}}" title="锁定" {{ d.id == 10002 ? 'checked' : '' }} />
</script>
<script type="text/javascript">
layui.use(['table', 'layer'], function(){
var table = layui.table
,layer = layui.layer;
table.render({
elem: '#test1' // 指定原始table容器的选择器
,url: 'UserPage.action' // 异步数据接口相关参数
,method: 'post' // 接口http请求类型
,where: {token: Math.random()} // 接口的其它参数
,parseData: function(res){ //res 即为原始返回的数据
return {
"code": res.code, // 解析接口状态
"msg": res.msg, // 解析提示文本
"count": res.count, // 解析数据长度
"data": res.data // 解析数据列表
};
}
,request: { // 用于对分页请求的参数: page、limit重新设定名称
pageName: 'page' // 页码的参数名称, 默认: page
,limitName: 'limit' // 每页数据量的参数名, 默认: limit
}
,response: {
statusName: 'code' // 规定数据状态的字段名称, 默认: code
,statusCode: 1 // 规定成功的状态码, 默认: 0
,msgName: 'msg' // 规定状态信息的字段名称, 默认: msg
,countName: 'count' // 规定数据总数的字段名称, 默认: count
,dataName: 'data' // 规定数据列表的字段名称, 默认: data
}
,toolbar: true // 开启表格头部工具栏区域
,width: 1250 // 设定容器宽度
,cellMinWidth: 100 // 全局定义所有常规单元格的最小宽度
,page: true // 开启分页
,limit: 3 // 每页显示的条数
,limits: [3,6,9] // 每页条数的选择项
,title: '用户表1' // 定义table的大标题
,totalRow: true // 是否开启合计行区域
,text: { // 自定义文本, 如空数据时的异常提示等
none: '暂时还么有无数据' // 默认: 无数据。
}
,loading: true // 是否显示加载条
,initSort: {
field: 'id' // 排序字段, 对应 cols设定的各字段名
,type: 'desc' // 排序方式 , asc: 升序、desc: 降序、null: 默认排序
}
// ,autoSort: false // 禁用前端自动排序
,defaultToolbar: ["filter", "exports", "print", { // 该参数可自由配置头部工具栏右侧的图标按钮
title: '提示' // 标题
,layEvent: 'tips' // 事件名, 用于toolbar事件中使用
,icon: 'layui-icon-tips' // 图标类名
}]
,cols: [[ // 设置表头
{type: 'checkbox', fixed: 'left', LAY_CHECKED: true}
,{
field: 'id', // 设定字段名
title: 'ID', // 设定标题名称
width: 150, // 设定列宽
minWidth: 120, // 局部定义当前常规单元格的最小宽度
hide: false, // 是否初始隐藏列
totalRowText: '合计', // 用于显示自定义的合计文本
unresize: true, // 是否禁用拖拽列宽
edit: 'text', // 单元格编辑类型
event: 'threeClick', // 自定义单元格点击事件名
style: 'color: #ff0000;', // 自定义单元格样式
align: 'center' // 单元格排列方式
}
,{field: 'username', title: '用户名'}
,{field: 'sex', title: '性别', templet: function(d){
return '<input type="checkbox" name="sex" lay-text="女|男" lay-skin="switch" value="' + d.sex + '"' + (d.sex == '女' ? 'checked' : '') + ' />';
}}
,{field: 'city', title: '城市'}
,{field: 'sign', title: '签名'}
,{field: 'experience', title: '积分', totalRow: true}
,{field: 'score', title: '评分', totalRow: true}
,{field: 'classify', title: '职业'}
,{field: 'wealth', title: '财富', totalRow: true, width: 200}
,{
field: 'lock', title: '是否锁定', templet: '#checkboxTpl' // 自定义列模板
}
]]
,done: function(res, curr, count){
// 如果是异步请求数据方式, res即为你接口返回的信息。
// 如果是直接赋值的方式, res即为: {data: [], count: 99}, data为当前页数据、count为数据总长度
console.log(res);
// 得到当前页码
console.log(curr);
// 得到数据总量
console.log(count);
}
});
table.render({
elem: '#test2' // 指定原始table容器的选择器
,height: 200 // 设定容器高度
,url: 'user.json' // 异步数据接口相关参数
,toolbar: 'default' // 开启表格头部工具栏区域
,skin: 'line' // 行边框风格
,even: true // 开启隔行背景
,size: 'sm' // 小尺寸的表格
// 默认 true, 即直接由 table组件在前端自动处理排序。若为 false, 则需自主排序, 通常由服务端直接返回排序好的数据。
,autoSort: true
,cols: [[ // 设置表头
{type: 'radio', fixed: 'left'}
,{field: 'id', title: 'ID', sort: true}
,{field: 'username', title: '用户名'}
,{field: 'sex', title: '性别'}
,{field: 'city', title: '城市'}
,{field: 'sign', title: '签名'}
,{field: 'experience', title: '积分'}
,{field: 'score', title: '评分'}
,{field: 'classify', title: '职业'}
,{field: 'wealth', title: '财富'}
]]
});
table.render({
elem: '#test3' // 指定原始table容器的选择器
,toolbar: '#toolbarTpl' // 开启表格头部工具栏区域
,cols: [[ // 设置表头
{type: 'numbers', fixed: 'left'}
,{field: 'id', title: 'ID'}
,{field: 'username', title: '用户名'}
,{field: 'sex', title: '性别'}
,{field: 'city', title: '城市'}
,{field: 'sign', title: '签名'}
,{field: 'experience', title: '积分'}
,{field: 'score', title: '评分'}
,{field: 'classify', title: '职业'}
,{field: 'wealth', title: '财富'}
]]
,data: [{
"id": 10000
,"username": "user-0"
,"sex": "女"
,"city": "城市-0"
,"sign": "签名-0"
,"experience": 255
,"logins": 24
,"wealth": 82830700
,"classify": "作家"
,"score": 57
},{
"id": 10001
,"username": "user-1"
,"sex": "男"
,"city": "城市-1"
,"sign": "签名-1"
,"experience": 884
,"logins": 58
,"wealth": 64928690
,"classify": "词人"
,"score": 27
},{
"id": 10002
,"username": "user-2"
,"sex": "女"
,"city": "城市-2"
,"sign": "签名-2"
,"experience": 650
,"logins": 77
,"wealth": 6298078
,"classify": "酱油"
,"score": 31
}]
});
// 监听事件
table.on('toolbar(test1)', function(obj){
var checkStatus = table.checkStatus(obj.config.id);
switch(obj.event){
case 'tips':
layer.msg('提示');
break;
};
});
table.on('tool(test1)', function(obj){
switch(obj.event){
case 'threeClick':
layer.msg('单元格点击事件: ' + obj.data.id);
break;
};
});
table.on('toolbar(test2)', function(obj){
var checkStatus = table.checkStatus(obj.config.id);
switch(obj.event){
case 'add':
layer.msg('添加');
break;
case 'delete':
layer.msg('删除');
break;
case 'update':
layer.msg('编辑');
break;
};
});
table.on('toolbar(test3)', function(obj){
var checkStatus = table.checkStatus(obj.config.id);
switch(obj.event){
case 'add':
layer.msg('添加');
break;
case 'delete':
layer.msg('删除');
break;
case 'update':
layer.msg('编辑');
break;
};
});
table.on('checkbox(test1)', function(obj){
console.log(obj.checked); // 当前是否选中状态
console.log(obj.data); // 选中行的相关数据
console.log(obj.type); // 如果触发的是全选, 则为: all; 如果触发的是单选, 则为: one
});
table.on('edit(test1)', function(obj){
console.log(obj.value); // 得到修改后的值
console.log(obj.field); // 当前编辑的字段名
console.log(obj.data); // 所在行的所有相关数据
});
table.on('row(test2)', function(obj){
console.log(obj.tr) // 得到当前行元素对象
console.log(obj.data) // 得到当前行数据
// obj.del(); // 删除当前行
// obj.update(fields) // 修改当前行数据
});
// 监听行双击事件
table.on('rowDouble(test3)', function(obj){
console.log(obj.tr) // 得到当前行元素对象
console.log(obj.data) // 得到当前行数据
// obj.del(); // 删除当前行
// obj.update(fields) // 修改当前行数据
});
});
</script>
</body>
</html>
27.2. 新建一Data.java
package layuiTable;
import java.io.Serializable;
public class Data implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String username;
private String sex;
private String city;
private String sign;
private Integer experience;
private Integer logins;
private Long wealth;
private String classify;
private Integer score;
public Data(Integer id, String username, String sex, String city, String sign, Integer experience, Integer logins, Long wealth, String classify, Integer score) {
this.id = id;
this.username = username;
this.sex = sex;
this.city = city;
this.sign = sign;
this.experience = experience;
this.logins = logins;
this.wealth = wealth;
this.classify = classify;
this.score = score;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public Integer getExperience() {
return experience;
}
public void setExperience(Integer experience) {
this.experience = experience;
}
public Integer getLogins() {
return logins;
}
public void setLogins(Integer logins) {
this.logins = logins;
}
public Long getWealth() {
return wealth;
}
public void setWealth(Long wealth) {
this.wealth = wealth;
}
public String getClassify() {
return classify;
}
public void setClassify(String classify) {
this.classify = classify;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
}
27.3. 新建User.java
package layuiTable;
import java.io.Serializable;
import java.util.List;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Integer code;
private String msg;
private Integer count;
private List<Data> data;
public User(Integer code, String msg, Integer count, List<Data> data) {
this.code = code;
this.msg = msg;
this.count = count;
this.data = 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<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
}
27.4. 添加gson.jar
27.5. 新建UserPage.java
package layuiTable;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
public class UserPage extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Enumeration<String> names = req.getParameterNames();
while(names.hasMoreElements()) {
String name = names.nextElement();
System.out.println(name + " = " + req.getParameter(name));
}
Enumeration<String> headerNames = req.getHeaderNames();
while(headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
System.out.println(headerName + " = " + req.getHeader(headerName));
}
int page = Integer.parseInt(req.getParameter("page"));
int limit = Integer.parseInt(req.getParameter("limit"));
ServletContext servletContext = getServletContext();
File file = new File(servletContext.getRealPath("/user.json"));
BufferedReader br = new BufferedReader(new FileReader(file));
StringBuffer sb = new StringBuffer();
String read = null;
while((read = br.readLine()) != null) {
sb.append(read);
}
br.close();
Gson gson = new Gson();
User user = gson.fromJson(sb.toString(), User.class);
int size = user.getData().size();
Data[] dataArr = Arrays.copyOfRange(user.getData().toArray(new Data[size]), (page - 1) * limit, page * limit > size ? size : page * limit);
List<Data> dataList = Arrays.asList(dataArr);
user.setData(dataList);
resp.setHeader("Content-Type", "text/html; charset=UTF-8");
resp.getWriter().write(gson.toJson(user));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
27.6. 运行效果图