This commit is contained in:
2024-10-29 14:04:59 +08:00
commit 48bf3e6f33
2839 changed files with 762707 additions and 0 deletions

View File

@@ -0,0 +1,201 @@
<h3 lay-toc="{level: 2, id: 'examples'}" class="layui-hide">综合演示 🔥</h3>
<pre class="layui-code" lay-options="{preview: 'iframe', id: 'table-demo-1', text: {preview: '综合演示 🔥'}, style: 'height: 506px;', layout: ['preview', 'code'], tools: ['full','window'], done: function(obj){
setTimeout(function(){
layer.tipsIndex = layer.tips(
'点击该图标可最大化查看效果',
layui.$('#table-demo-1 .layui-icon-screen-full'), {
tips: 4,
time: 30*1000
})
});
}, toolsEvent: function(oi, type){
if(type === 'full'){
layer.close(layer.tipsIndex);
}
}}">
<textarea>
{{- d.include("/table/examples/demo.md") }}
</textarea>
</pre>
<h3 id="demo-static" lay-toc="{level: 2}" class="ws-bold">静态表格</h3>
静态表格是指内容已经存在于页面中的 `<table class="layui-table">` 元素,且可通过一些*特定属性*设定不同风格。
<pre class="layui-code" lay-options="{preview: true, style: 'height: 335px; overflow: auto;', layout: ['preview', 'code'], tools: ['full']}">
<textarea>
{{- d.include("/table/examples/static.md") }}
</textarea>
</pre>
<h3 id="demo-auto-render" lay-toc="{level: 2}" class="ws-bold">模板配置渲染</h3>
在上文「[综合演示](#examples)」中,是通过组件核心方法完成的渲染。除此,还可以在模板上直接配置相关属性,让其自动完成渲染。
<pre class="layui-code" lay-options="{preview: true, layout: ['preview', 'code'], tools: ['full'], done: function(obj){
layui.table.init(obj.container.children('table'));
}, toolsEvent: function(oi, type){
if(type === 'full'){
layui.table.resize('ID-table-demo-init');
}
}}">
<textarea>
{{- d.include("/table/examples/autoRender.md") }}
</textarea>
</pre>
<h3 id="demo-init" lay-toc="{level: 2}" class="ws-bold">静态表格转换</h3>
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['preview', 'code'], tools: ['full']}">
<textarea>
{{- d.include("/table/examples/init.md") }}
</textarea>
</pre>
<h3 id="demo-data" lay-toc="{level: 2}" class="ws-bold">已知数据渲染</h3>
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['preview', 'code'], ID: 'ID-table-demo-data', tools: ['full'], done: function(obj){
layui.table.resize(this.ID);
}, toolsEvent: function(oi, type){
if(type === 'full'){
layui.table.resize(this.ID);
}
}}">
<textarea>
{{- d.include("/table/examples/data.md") }}
</textarea>
</pre>
<h3 id="demo-templet" lay-toc="{level: 2, hot: true}" class="ws-bold">自定义模板</h3>
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['preview', 'code'], tools: ['full'], ID: 'ID-table-demo-templet', done: function(obj){
layui.table.resize(this.ID);
}, toolsEvent: function(oi, type){
if(type === 'full'){
layui.table.resize(this.ID);
}
}}">
<textarea>
{{- d.include("/table/examples/templet.md") }}
</textarea>
</pre>
<h3 id="demo-css" lay-toc="{level: 2, hot: true}" class="ws-bold">自定义样式 <sup>2.7+</sup></h3>
<pre class="layui-code" lay-options="{preview: 'iframe', style: 'height: 538px;', layout: ['preview', 'code'], tools: ['full']}">
<textarea>
{{- d.include("/table/examples/css.md") }}
</textarea>
</pre>
<h3 id="demo-page" lay-toc="{level: 2}" class="ws-bold">自定义分页</h3>
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['preview', 'code'], tools: ['full'], ID: 'ID-table-demo-page', done: function(obj){
layui.table.resize(this.ID);
}, toolsEvent: function(oi, type){
if(type === 'full'){
layui.table.resize(this.ID);
}
}}">
<textarea>
{{- d.include("/table/examples/page.md") }}
</textarea>
</pre>
<h3 id="demo-search" lay-toc="{level: 2, hot: true}" class="ws-bold">外部搜索</h3>
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['preview', 'code'], tools: ['full'], ID: 'ID-table-demo-search', done: function(obj){
obj.render();
layui.table.resize(this.ID);
}, toolsEvent: function(oi, type){
if(type === 'full'){
layui.table.resize(this.ID);
}
}}">
<textarea>
{{- d.include("/table/examples/search.md") }}
</textarea>
</pre>
<h3 id="demo-editable" lay-toc="{level: 2, hot: true}" class="ws-bold">编辑的权限控制 <sup>2.7+</sup></h3>
以下演示一个根据返回数据中某个字段来判断是否开启该行的编辑,*单击对应行*可进入单元格编辑。
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['preview', 'code'], tools: ['full']}">
<textarea>
{{- d.include("/table/examples/editable.md") }}
</textarea>
</pre>
<h3 id="demo-editmodes" lay-toc="{level: 2, hot: true}" class="ws-bold">实现多样化编辑</h3>
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['preview', 'code'], tools: ['full'], toolsEvent: function(oi, type){
if(type === 'full'){
layui.table.resize('ID-table-demo-editmodes');
}
}}">
<textarea>
{{- d.include("/table/examples/editModes.md") }}
</textarea>
</pre>
<h3 id="demo-parse" lay-toc="{level: 2, hot: true}" class="ws-bold">转换数据格式</h3>
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['preview', 'code'], tools: ['full'], toolsEvent: function(oi, type){
if(type === 'full'){
layui.table.resize('ID-table-demo-parse');
}
}}">
<textarea>
{{- d.include("/table/examples/parse.md") }}
</textarea>
</pre>
<h3 id="demo-filter" lay-toc="{level: 2}" class="ws-bold">筛选列记忆功能</h3>
即点击当前表格右上角筛选图标后,对表头进行显示隐藏勾选,再刷新页面依然保留当前筛选状态。
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['preview', 'code'], tools: ['full'], toolsEvent: function(oi, type){
if(type === 'full'){
layui.table.resize('ID-table-demo-filter');
}
}}">
<textarea>
{{- d.include("/table/examples/filter.md") }}
</textarea>
</pre>
<h3 id="demo-setRowChecked" lay-toc="{level: 2, hot: true}" class="ws-bold">选中行操作</h3>
点击行任意处,通过行事件中执行相关选中方法,实现对整行的状态选中。*如下以「单选」行为例:*
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['preview', 'code'], tools: ['full'], toolsEvent: function(oi, type){
if(type === 'full'){
layui.table.resize('ID-table-demo-setRowChecked');
}
}}">
<textarea>
{{- d.include("/table/examples/setRowChecked.md") }}
</textarea>
</pre>
<h3 id="demo-theads" lay-toc="{level: 2}" class="ws-bold">多级表头</h3>
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['preview', 'code'], tools: ['full'], done: function(obj){
layui.table.init(obj.container.children('table'));
}, toolsEvent: function(oi, type){
if(type === 'full'){
layui.table.resize('ID-table-demo-theads-1');
layui.table.resize('ID-table-demo-theads-2');
}
}}">
<textarea>
{{- d.include("/table/examples/theads.md") }}
</textarea>
</pre>
<h3 id="more-examples" class="ws-anchor ws-bold">更多示例</h3>
> - 🎉 不定期分享在 [Gitee Issues](https://gitee.com/layui/layui/issues)

View File

@@ -0,0 +1,181 @@
<table class="layui-table">
<colgroup>
<col width="150">
<col>
</colgroup>
<thead>
<tr>
<th>属性名</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>url</td>
<td>
发送异步请求的 URL。默认会自动传递两个参数`?page=1&limit=30`(该参数可通过 `request` 属性自定义)
<br>`page` 代表当前页码、`limit` 代表每页数据条数。
</td>
</tr>
<tr>
<td>method</td>
<td>
请求的方式,默认:`get`
</td>
</tr>
<tr>
<td>where</td>
<td>
请求的其他参数。如:`where: {token: 'sasasas', id: 123}`
</td>
</tr>
<tr>
<td>headers</td>
<td>
请求的数据头参数。如:`headers: {token: 'sasasas'}`
</td>
</tr>
<tr>
<td>contentType</td>
<td>
请求的内容编码类型。若要发送 `json` 内容,可设置:<br>
`contentType: 'application/json'`
</td>
</tr>
<tr>
<td>dataType <sup>2.7+</sup></td>
<td>
请求的数据类型,默认 `json`
</td>
</tr>
<tr>
<td>jsonpCallback <sup>2.7+</sup></td>
<td>
设置当 `dataType: 'jsonp'` 时的回调函数名。
</td>
</tr>
<tr>
<td>request</td>
<td>
用于对默认的分页相关的请求参数 `page,limit` 重新设定名称。如:
```
request: {
pageName: 'curr', // 页码的参数名称默认page
limitName: 'nums' // 每页数据条数的参数名默认limit
}
```
那么请求数据时的参数将会变为 `?curr=1&nums=30`
</td>
</tr>
<tr>
<td>
[**parseData**](#options.parseData)
</td>
<td>
<div class="ws-anchor" id="options.parseData">
数据格式解析的回调函数,用于将返回的任意数据格式解析成 table 组件规定的数据格式:
</div>
```
{
"code": 0,
"msg": "",
"count": 1000,
"data": [{}, {}]
}
```
很多时候,您接口返回的数据格式并不一定都符合 table 默认规定的格式,比如:
```
{
"status": 0,
"message": "",
"total": 180,
"data": {
"item": [{}, {}]
}
}
```
此时我们可以借助 `parseData` 回调函数将数据解析并转换为默认规定的格式:
```
table.render({
elem: '',
url: '',
parseData: function(res){ // res 即为原始返回的数据
return {
"code": res.status, // 解析接口状态
"msg": res.message, // 解析提示文本
"count": res.total, // 解析数据长度
"data": res.data.item // 解析数据列表
};
},
// … //其他参数
});
```
该函数非常实用
</td>
</tr>
</tbody>
</table>
<h4 id="data.reserved" class="ws-anchor ws-bold">返回数据中的特定字段</h4>
在返回的数据中,允许规定某些特定字段,以便 table 组件进行相应的特定解析。
| 特定字段名 | 描述 | 读写状态 |
| --- | --- | --- |
| LAY_CHECKED | 当前行的选中状态 | 可读可写 |
| LAY_DISABLED | 当前行是否禁止选择 | 可读可写 |
| LAY_INDEX | 当前行下标。每页重新从零开始计算 | 只读 |
| LAY_NUM | 当前行序号 | 只读 |
| LAY_COL | 当前列的表头属性配置项 | 只读 |
示例一: 在返回的数据中设置特定字段:
```
{
"code": 0,
"count": 1000,
"data": [{},{
LAY_DISABLED: true
}]
}
```
示例二: 在模板中读取特定字段示例:
{{!
```
<script type="text/html" id="TPL-demo-xxx">
当前行下标: {{= d.LAY_INDEX }}
当前列的某个表头属性: {{= d.LAY_COL.field }}
</script>
```
!}}

View File

@@ -0,0 +1,485 @@
<table class="layui-table">
<colgroup>
<col width="150">
<col>
<col width="100">
<col width="100">
</colgroup>
<thead>
<tr>
<th>属性名</th>
<th>描述</th>
<th>类型</th>
<th>默认值</th>
</tr>
</thead>
<tbody>
<tr>
<td>field</td>
<td>
设置字段名。通常是表格数据列的唯一标识
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>title</td>
<td>
设置列的标题。
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>fieldTitle <sup>2.8+</sup></td>
<td>
设置列的字段标题。该属性在筛选列和导出场景中优先级高于 `title` 属性
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>width</td>
<td>
设置列宽。若不填写,则自动分配;若填写,则支持值为:*数字、百分比*。如:
`width: 200` / `width: '30%'`
</td>
<td>number/string</td>
<td>-</td>
</tr>
<tr>
<td>minWidth</td>
<td>
设置当前列的最小宽度,一般用于列宽自动分配的情况。其优先级高于基础属性中的 `cellMinWidth`
</td>
<td>number</td>
<td>
`60`
</td>
</tr>
<tr>
<td>maxWidth <sup>2.8+</sup></td>
<td>
设置当前列的最大宽度。其优先级高于基础属性中的 `cellMaxWidth`
</td>
<td>number</td>
<td>-</td>
</tr>
<tr>
<td>expandedWidth <sup>2.8.15+</sup></td>
<td>
设置单元格被展开后的宽度。若设置的值的小于当前列宽,则展开后的列宽保持不变。注:当 `expandedMode` 属性为默认值时有效。
</td>
<td>number</td>
<td>-</td>
</tr>
<tr>
<td>expandedMode <sup>2.8.17+</sup></td>
<td>
用于设置所有单元格默认展开方式,可选值有:
- `tips` 悬浮展开方式
- `default` 多行展开方式(默认)
优先级高于 `cellExpandedMode` 基础属性
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>type</td>
<td>
设置列类型。可选值有:
- `normal` 常规列,无需设定
- `checkbox` 复选框列
- `radio` 单选框列
- `numbers` 序号列
- `space` 空列
</td>
<td>string</td>
<td>
`normal`
</td>
</tr>
<tr>
<td>LAY_CHECKED</td>
<td>
设置全选状态,当列设置 `type: 'checkbox'` 时才有效。
</td>
<td>boolean</td>
<td>
`false`
</td>
</tr>
<tr>
<td>fixed</td>
<td>
设置固定列,即不跟随 table 横向滚动条而滚动。可选值有:
- `left` 固定在左
- `right` 固定在右
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>
[templet](#cols.templet)
</td>
<td colspan="3">
<div class="ws-anchor" id="cols.templet">
设置列的自定义模板,核心属性。模板遵循 <a href="../laytpl/" target="_blank">laytpl</a> 组件语法。
</div>
`templet` 提供了三种使用方式,选择任一用法即可:
- **设置模版选择器**
{{!
```
<script type="text/html" id="TPL-demo-title">
<a href="/detail/{{= d.id }}" class="layui-table-link">
{{= d.title }}
</a>
</script>
<!--
模板中的 `d` 不仅包含当前行数据,还包含特定字段,如:
{{= d.LAY_INDEX }} {{= d.LAY_COL }} 等
-->
```
```
table.render({
cols: [[
{field: 'title', templet: '#TPL-demo-title'}
// …
]],
// …
});
```
!}}
- **设置模板内容**
该方式必须在内容中包裹一层 `<div></div>`,否则无法读取模板。
{{!
```
table.render({
cols: [[
{field: 'title', templet: '<div><a href="/detail/{{= d.id }}" class="layui-table-link">{{= d.title }}</a></div>'}
// …
]],
// …
});
```
!}}
- **设置模板函数**
函数将返回一个 `d` 参数,包含当前行数据及特定的额外字段。
```
table.render({
cols: [[
{field: 'title', templet: function(d){
console.log(d); // 得到当前行数据
console.log(this); // 得到表头当前列配置项
console.log(d.LAY_NUM); // 得到序号。或其他特定字段
// 返回模板内容
return '<a href="/detail/'+ d.id +'" class="layui-table-link">'+ d.title +'</a>'
}}
// …
]],
// …
});
```
</td>
</tr>
<tr>
<td>exportTemplet <sup>2.6.9+</sup></td>
<td colspan="3">
<div class="ws-anchor" id="cols.exportTemplet">
设置表格导出时的模板,用法同 `templet` 属性。当 `templet` 指向的模板内容较复杂时建议使用,如下以模板存在 `select` 元素为例:
</div>
```
exportTemplet: function(d, obj){
// 当前 td
var td = obj.td(this.field);
// 返回 select 选中值
return td.find('select').val();
}
```
</td>
</tr>
<tr>
<td>
[totalRow](#cols.totalRow)
</td>
<td colspan="3">
<div class="ws-anchor" id="cols.totalRow">
是否开启该列的自动合计功能,默认不开启。
</div>
- **采用前端合计**
{{!
```
// 开启并输出合计行前端合计结果
totalRow: true
// 开启并输出合计行自定义模板。此处 TOTAL_NUMS 即为合计结果的固定特定字段
totalRow: '{{= d.TOTAL_NUMS }} 单位'
// 取整或其他运算
totalRow: '{{= parseInt(d.TOTAL_NUMS) }}'
```
!}}
注意:*合计行模板仅支持字符写法,不支持函数写法,请勿与 `templet` 用法混淆。*
- **采用后端合计**
前端合计的数据有限,因此常需要后端直接返回合计结果,组件将优先读取。数据格式如下:
```
{
"code": 0,
"totalRow": {
"score": "777",
"experience": "999"
},
"data": [{}, {}],
"msg": "",
"count": 1000
}
```
在合计行自定义模板中输出后端返回的合计数据
{{!
```
// 获取后端接口返回数据中的统计字段。此处 TOTAL_ROW 即对应返回据中的 totalRow
totalRow: '分数:{{= d.TOTAL_ROW.score }}'
```
!}}
如上,在 `totalRow` 中返回所需统计的列字段名和值即可。
`totalRow` 字段同样可以通过 `parseData` 回调来解析成为 table 组件所规定的数据格式。
</td>
</tr>
<tr>
<td>
[edit](#cols.edit)
</td>
<td>
<div class="ws-anchor" id="cols.edit">
用于对列所在的单元格开启编辑功能。可选值有:
</div>
- `edit: 'text'` 单行输入模式
- `edit: 'textarea'` 多行输入模式 <sup>2.7+</sup>
**函数写法** <sup>2.7+</sup>
```
edit: function(d){
// d 即为当前行数据,此时可根据行相关字段来开启该行是否编辑的权限
if(d.editable){ // editable 为任意字段名
return 'text'; // 编辑模式
}
}
```
</td>
<td>string<br>function</td>
<td>
`false`
</td>
</tr>
<tr>
<td>hide</td>
<td>
是否初始隐藏列
</td>
<td>boolean</td>
<td>
`false`
</td>
</tr>
<tr>
<td>ignoreExport <sup>2.8.3+</sup></td>
<td>
是否导出时忽略该列。支持以下可选值:
- `true` : 忽略导出
- `false` : 强制导出,对所有列适用
- `null` : 只对常规列导出(默认)
</td>
<td>boolean</td>
<td>
-
</td>
</tr>
<tr>
<td>escape</td>
<td>
是否对当前列进行内容编码(转义 html优先级大于基础属性中的 `escape`
</td>
<td>boolean</td>
<td>
`true`
</td>
</tr>
<tr>
<td>sort</td>
<td>
是否开启列的排序功能。<br>
注意:<em>不推荐对值同时存在“数字和普通字符”的列开启排序,因为会进入字典序排序计算中</em>,如:`'张三' > '2' > '100'`,这可能并不是你想要的结果,但字典序排列采用的是 `ASCII` 码比对。
</td>
<td>boolean</td>
<td>
`false`
</td>
</tr>
<tr>
<td>unresize</td>
<td>
是否禁用拖拽列宽。默认情况下会根据列类型 `type` 属性来决定是否禁用,如复选框列,会自动禁用。而其它普通列,默认允许拖拽列宽,当然你也可以设置 true 来禁用该功能。
</td>
<td>boolean</td>
<td>
`false`
</td>
</tr>
<tr>
<td>event</td>
<td>
自定义单元格点击事件名,以便在 [单元格工具事件](#on-tool) 中完成对该单元格的事件处理。
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>style</td>
<td>
自定义单元格样式。可传入任意的 CSS 内容,如:`style: 'font-size: 13px; color: red;'`
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>align</td>
<td>
单元格排列方式。可选值有:`left` | `center` | `right`
</td>
<td>string</td>
<td>
`left`
</td>
</tr>
<tr>
<td>colspan</td>
<td>
单元格所占列数。一般用于多级表头
</td>
<td>number</td>
<td>
`1`
</td>
</tr>
<tr>
<td>rowspan</td>
<td>
单元格所占行数。一般用于多级表头
</td>
<td>number</td>
<td>
`1`
</td>
</tr>
</tbody>
</table>

View File

@@ -0,0 +1,484 @@
<table class="layui-table">
<colgroup>
<col width="150">
<col>
<col width="100">
<col width="100">
</colgroup>
<thead>
<tr>
<th>属性名</th>
<th>描述</th>
<th>类型</th>
<th>默认值</th>
</tr>
</thead>
<tbody>
<tr>
<td>elem</td>
<td>绑定原始 table 元素,方法渲染方式必填。</td>
<td>string/DOM</td>
<td>-</td>
</tr>
<tr>
<td>
[url](#options.ajax)
</td>
<td>
发送异步请求的 URL。更多异步相关属性见 : [#异步属性](#options.ajax)
</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>
[cols](#options.cols)
</td>
<td>
表头属性集,通过二维数组定义多级表头。方法渲染时必填。 更多表头属性见 : [#表头属性](#options.cols)
</td>
<td>array</td>
<td>-</td>
</tr>
<tr>
<td>data</td>
<td>
直接赋值数据。既适用于只展示一页数据,也能对一段已知数据进行多页展示。该属性与 `url` 属性只能二选一。
<hr>
**注**:当设置 `data` 模式时,`count` 的值取 `data.length`,即对一段已知数据进行分页展示。 此时在 `page` 属性中设置 `count` 无效。 若要在同一页显示所有数据,可将 `limit` 设置成 `data.length`,即与 `count` 等同即可,那么默认的分页栏只会显示 1 页,若要自定义分页结构,可通过 `pagebar` 属性结合 `laypage` 组件来重新自定义分页排版。
</td>
<td>array</td>
<td>-</td>
</tr>
<tr>
<td>id</td>
<td>
设定实例唯一索引,以便用于其他方法对 table 实例进行相关操作。若该属性未设置,则默认从 `elem` 属性绑定的原始 table 元素中的 `id` 属性值中获取。
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>toolbar</td>
<td>
开启表格头部工具栏。支持以下几种值写法:
- `toolbar: '#template-id'` 自定义工具栏模板选择器
- `toolbar: '<div>xxx</div>` 直接传入模板字符
- `toolbar: true` 仅开启工具栏右侧,不显示左侧模板
- `toolbar: 'default'` 开启工具栏并显示默认模板
</td>
<td>string<br>boolean</td>
<td>
`false`
</td>
</tr>
<tr>
<td>defaultToolbar</td>
<td>
设置头部工具栏右侧图标。值是一个数组,可选成员有: `filter,exports,print` (分别代表:筛选图标、导出图标、打印图标)。图标可根据数组值的顺序排列,如:`defaultToolbar: ['filter','print','exports']` <br>支持自定义图标及事件,用法详见示例: [#综合演示](#examples)
</td>
<td>array</td>
<td>-</td>
</tr>
<tr>
<td>width</td>
<td>设置容器宽度,默认自适应。</td>
<td>number</td>
<td>-</td>
</tr>
<tr>
<td>
[height](#options.height)
</td>
<td>
<div class="ws-anchor" id="options.height">
设置表格容器高度,默认自适应。其他可选值的规则如下:
</div>
- `height: 315` 设置固定高度
- `height: 'full-30'` 设置自适应高度。这是一个特定的语法格式:`full` 表示铺满;后面的数字表示当前 table 之外的元素占用的高度,如:表格头部到页面最顶部*加*表格底部距离页面最底部的“距离和”
- `height: '#id-30'` 设置相对父元素的高度自适应,其中 `#id` 即父元素的 ID 选择器,其计算原理和上述 `full` 相同。
</td>
<td>number<br>string</td>
<td>-</td>
</tr>
<tr>
<td>maxHeight <sup>2.8+</sup></td>
<td>
设置表格容器的最大高度,设置该属性后,`height` 属性将被认定为默认的自适应值。
</td>
<td>number</td>
<td>-</td>
</tr>
<tr>
<td>cellMinWidth</td>
<td>
设置所有普通单元格的最小宽度,一般用于列宽自动分配的情况。其优先级低于表头属性中的 `minWidth`
</td>
<td>number</td>
<td>
`60`
</td>
</tr>
<tr>
<td>cellMaxWidth <sup>2.8+</sup></td>
<td>
设置所有普通单元格的最大宽度。其优先级低于表头属性中的 `maxWidth`
</td>
<td>number</td>
<td>-</td>
</tr>
<tr>
<td>lineStyle <sup>2.7+</sup></td>
<td>
用于定义表格的多行样式,如每行的高度等。该参数一旦设置,单元格将会开启多行模式,且鼠标 hover 时会通过显示滚动条的方式查看到更多内容。 请按实际场景使用。<br>示例:`lineStyle: 'height: 95px;'`
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>className <sup>2.7+</sup></td>
<td>用于给表格主容器追加 css 类名,以便更好地扩展表格样式</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>css <sup>2.7+</sup></td>
<td>
用于给当前表格主容器直接设定 css 样式,样式值只会对所在容器有效,不会影响其他表格实例。如:`css: '.layui-table-page{text-align: right;}'`
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>cellExpandedMode <sup>2.8.17+</sup></td>
<td>
用于设置所有单元格默认展开方式,可选值有:
- `tips` 悬浮展开方式
- `default` 多行展开方式(默认)
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>cellExpandedWidth <sup>2.8.17+</sup></td>
<td>
用于设置所有单元格默认展开后的宽度。当 `cellExpandedMode` 属性为默认值时有效。
</td>
<td>number</td>
<td>
`60`
</td>
</tr>
<tr>
<td>escape <sup>2.6+</sup></td>
<td>是否开启对内容的编码(转义 html</td>
<td>boolean</td>
<td>
`true`
</td>
</tr>
<tr>
<td>totalRow</td>
<td>是否开启合计行区域</td>
<td>string</td>
<td>
`false`
</td>
</tr>
<tr>
<td>page</td>
<td>
用于开启分页。<br>
支持传入 [laypage](../laypage/#options) 组件的基础属性jump,elem 除外)
</td>
<td>boolean<br>object</td>
<td>
`false`
</td>
</tr>
<tr>
<td>pagebar <sup>2.7+</sup></td>
<td>
用于开启分页区域的自定义模板,用法同 `toolbar` 属性。
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>limit</td>
<td>
每页显示的条数。值需对应 limits 参数的选项。优先级低于 `page` 属性中的 `limit` 属性。
</td>
<td>number</td>
<td>
`10`
</td>
</tr>
<tr>
<td>limits</td>
<td>每页条数的选择项。</td>
<td>array</td>
<td>
`[10,…,90]`
</td>
</tr>
<tr>
<td>loading</td>
<td>
是否显示加载条。若为 `false`,则在切换分页时,不会出现加载条。必须设置了 `url` 属性才生效。
</td>
<td>boolean</td>
<td>
`true`
</td>
</tr>
<tr>
<td>scrollPos <sup>2.7+</sup></td>
<td>
用于设置重载数据或切换分页时的滚动条位置状态。可选值:
- `fixed` 重载数据时,保持滚动条位置不变
- `reset` 重载数据时,滚动条位置恢复置顶
- `default` 默认方式,无需设置。即重载数据或切换分页时,纵向滚动条置顶,横向滚动条位置不变。
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>editTrigger <sup>2.7+</sup></td>
<td>
是用于设定单元格编辑的事件触发方式。如双击: `dblclick`
</td>
<td>string</td>
<td>
`click`
</td>
</tr>
<tr>
<td>title</td>
<td>定义 table 的大标题(在文件导出等地方会用到)</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>text</td>
<td>自定义文本,如空数据时的异常提示等。</td>
<td>object</td>
<td>
<button class="layui-btn layui-btn-sm layui-btn-primary" lay-layer="{title: 'text 属性默认值'}">
查看默认值
</button>
<div style="display: none;">`text: {none: '无数据'}`</div>
</td>
</tr>
<tr>
<td>autoSort</td>
<td>
是否由组件自动进行前端排序。若为 `false`,则需自主排序,即由后端直接返回排序好的数据。[#详细用法](#on-sort)
</td>
<td>boolean</td>
<td>
`true`
</td>
</tr>
<tr>
<td>initSort</td>
<td>
初始排序状态。用于在数据表格渲染完毕时,按某个字段排序显示。它接受一个 `object` 类型的值,包含属性有:
- `field` 排序字段。对应 `cols` 设定的各字段名
- `type` 排序方式。可选值 : `'asc','desc',null`,即:`升序、降序、默认`
```
initSort: {
field: 'id', // 按 id 字段排序
type: 'desc' // 降序排序
}
```
</td>
<td>object</td>
<td>-</td>
</tr>
<tr>
<td>skin</td>
<td>
设置表格边框风格。可选值:`grid`\|`line`\|`row`\|`nob`
</td>
<td>string</td>
<td>
`grid`
</td>
</tr>
<tr>
<td>size</td>
<td>
设置表格其他尺寸。可选值:`sm`\|`md`|`lg`
</td>
<td>string</td>
<td>
`md`
</td>
</tr>
<tr>
<td>even</td>
<td>
是否开启隔行背景。
</td>
<td>string</td>
<td>
`false`
</td>
</tr>
<tr>
<td>
[before](#options.before) <sup>2.7+</sup>
</td>
<td colspan="3">
<div class="ws-anchor" id="options.before">
数据渲染之前的回调函数。
</div>
```
table.render({
before: function(options){
console.log(options); // 当前实例属性配置项
options.where.abc = 123; // 修改或额外追加 where 属性
},
// … // 其它属性
});
```
</td>
</tr>
<tr>
<td>
[done](#options.done)
</td>
<td colspan="3">
<div class="ws-anchor" id="options.done">
数据渲染完毕的回调函数。返回的参数如下:
</div>
```
table.render({
done: function(res, curr, count, origin){
console.log(res); // 得到当前渲染的数据
console.log(curr); // 得到当前页码
console.log(count); // 得到数据总量
console.log(origin); // 回调函数所执行的来源 --- 2.8.7+
},
// … // 其它属性
});
```
</td>
</tr>
<tr>
<td>error <sup>2.6+</sup></td>
<td colspan="3">
数据请求失败的回调函数。返回两个参数:错误对象、内容。
```
error: function(e, msg) {
console.log(e, msg)
}
```
</td>
</tr>
</tbody>
</table>

View File

@@ -0,0 +1,16 @@
<table class="layui-table" lay-data="{height:315, url:'/static/2.8/json/table/user.json', page:true}" id="ID-table-demo-init">
<thead>
<tr>
<th lay-data="{field:'id', width:80, sort: true}">ID</th>
<th lay-data="{field:'username', width:80}">用户名</th>
<th lay-data="{field:'sex', width:80, sort: true}">性别</th>
<th lay-data="{field:'city'}">城市</th>
<th lay-data="{field:'sign'}">签名</th>
<th lay-data="{field:'experience', sort: true}">积分</th>
<th lay-data="{field:'score', sort: true}">评分</th>
<th lay-data="{field:'classify'}">职业</th>
</tr>
</thead>
</table>
<!-- import layui -->

View File

@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>table 自定义样式 - Layui</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="{{= d.layui.cdn.css }}" rel="stylesheet">
<style>
/* 自定义样式 */
.layui-table-testcss .layui-table-header,
.layui-table-testcss thead tr{background-color: #F8FCF9; color: #16BAAA}
.layui-form-testcss > div{margin-bottom: 6px;}
</style>
</head>
<body>
<div style="padding: 16px;">
<table class="layui-hide" id="ID-table-demo-css"></table>
</div>
<script type="text/html" id="ID-table-demo-css-user">{{!
<ul>
<li><strong>ID:</strong> {{= d.id }} </li>
<li><strong>用户:</strong> {{= d.username }} </li>
<li><strong>性别:</strong> {{= d.sex }} </li>
<li><strong>城市:</strong> {{= d.city }} </li>
</ul>
!}}</script>
<script type="text/html" id="ID-table-demo-css-tool">{{!
<div class="layui-form layui-form-testcss">
<div class="layui-input-wrap">
<input name="AAA" value="{{= d.AAA || '' }}" lay-affix="clear" placeholder="表单 1" class="layui-input" >
</div>
<div class="layui-input-wrap">
<input name="BBB" value="{{= d.BBB || '' }}" lay-affix="clear" placeholder="表单 2" class="layui-input" >
</div>
<div>
<button class="layui-btn layui-btn-fluid" lay-submit lay-filter="demo-css-submit">确认</button>
</div>
</div>
!}}</script>
<script src="{{= d.layui.cdn.js }}"></script>
<script>
layui.use(['table'], function(){
var table = layui.table;
var form = layui.form;
// 创建渲染实例
table.render({
elem: '#ID-table-demo-css',
url:'/static/2.8/json/table/demo1.json', // 此处为静态模拟数据,实际使用时需换成真实接口
page: true,
height: 'full-35',
lineStyle: 'height: 151px;', // 定义表格的多行样式
css: [ // 直接给当前表格主容器重置 css 样式
'.layui-table-page{text-align: center;}' // 让分页栏居中
].join(''),
className: 'layui-table-testcss', // 用于给表格主容器追加 css 类名
cols: [[
{field:'username', width:160, title: '用户', templet: '#ID-table-demo-css-user'},
// 设置单元格样式
{field:'sign', minWidth:100, title: '签名', style:'color: #000;'},
{width:160, title: '操作', templet: '#ID-table-demo-css-tool'}
]]
});
// 表单提交
form.on('submit(demo-css-submit)', function(data){
var field = data.field; // 获取表单字段值
// 显示填写结果,仅作演示用
layer.alert(JSON.stringify(field), {
title: '当前填写的字段值'
});
// 此处可执行 Ajax 等操作
// …
return false; // 阻止默认 form 跳转
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,85 @@
<table class="layui-hide" id="ID-table-demo-data"></table>
<!-- import layui -->
<script>
layui.use('table', function(){
var table = layui.table;
// 已知数据渲染
var inst = table.render({
elem: '#ID-table-demo-data',
cols: [[ //标题栏
{field: 'id', title: 'ID', width: 80, sort: true},
{field: 'username', title: '用户', width: 120},
{field: 'sign', title: '签名', minWidth: 160},
{field: 'sex', title: '性别', width: 80},
{field: 'city', title: '城市', width: 100},
{field: 'experience', title: '积分', width: 80, sort: true}
]],
data: [{ // 赋值已知数据
"id": "10001",
"username": "张三1",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": "116"
}, {
"id": "10002",
"username": "张三2",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": "12",
"LAY_CHECKED": true
}, {
"id": "10003",
"username": "张三3",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": "65"
}, {
"id": "10004",
"username": "张三4",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": "777"
}, {
"id": "10005",
"username": "张三5",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": "86"
}, {
"id": "10006",
"username": "张三6",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": "12"
}, {
"id": "10007",
"username": "张三7",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": "16"
}, {
"id": "10008",
"username": "张三8",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": "106"
}],
//skin: 'line', // 表格风格
//even: true,
page: true, // 是否显示分页
limits: [5, 10, 15],
limit: 5 // 每页默认显示的数量
});
});
</script>

View File

@@ -0,0 +1,371 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>table 组件综合演示 - Layui</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="{{= d.layui.cdn.css }}" rel="stylesheet">
</head>
<body>
<!--
本「综合演示」包含:自定义头部工具栏、获取表格数据、表格重载、自定义模板、单双行显示、单元格编辑、自定义底部分页栏、表格相关事件与操作、与其他组件的结合等相对常用的功能,以便快速掌握 table 组件的使用。
-->
<div style="padding: 16px;">
<table class="layui-hide" id="test" lay-filter="test"></table>
</div>
<script type="text/html" id="toolbarDemo">{{!
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="getCheckData">获取选中行数据</button>
<button class="layui-btn layui-btn-sm" lay-event="getData">获取当前页数据</button>
<button class="layui-btn layui-btn-sm" id="dropdownButton">
下拉按钮
<i class="layui-icon layui-icon-down layui-font-12"></i>
</button>
<button class="layui-btn layui-btn-sm layui-bg-blue" id="reloadTest">
重载测试
<i class="layui-icon layui-icon-down layui-font-12"></i>
</button>
<button class="layui-btn layui-btn-sm layui-btn-primary" id="rowMode">
<span>{{= d.lineStyle ? '多行' : '单行' }}模式</span>
<i class="layui-icon layui-icon-down layui-font-12"></i>
</button>
</div>
!}}</script>
<script type="text/html" id="barDemo">
<div class="layui-clear-space">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-xs" lay-event="more">
更多
<i class="layui-icon layui-icon-down"></i>
</a>
</div>
</script>
<script src="{{= d.layui.cdn.js }}"></script>
<script>
layui.use(['table', 'dropdown'], function(){
var table = layui.table;
var dropdown = layui.dropdown;
// 创建渲染实例
table.render({
elem: '#test',
url: '/static/2.8/json/table/demo1.json', // 此处为静态模拟数据,实际使用时需换成真实接口
toolbar: '#toolbarDemo',
defaultToolbar: ['filter', 'exports', 'print', {
title: '提示',
layEvent: 'LAYTABLE_TIPS',
icon: 'layui-icon-tips'
}],
height: 'full-35', // 最大高度减去其他容器已占有的高度差
css: [ // 重设当前表格样式
'.layui-table-tool-temp{padding-right: 145px;}'
].join(''),
cellMinWidth: 80,
totalRow: true, // 开启合计行
page: true,
cols: [[
{type: 'checkbox', fixed: 'left'},
{field:'id', fixed: 'left', width:80, title: 'ID', sort: true, totalRowText: '合计:'},
{field:'username', width:80, title: '用户'},
{field:'email', title:'邮箱 <i class="layui-icon layui-icon-tips layui-font-14" lay-event="email-tips" title="该字段开启了编辑功能" style="margin-left: 5px;"></i>', fieldTitle: '邮箱', hide: 0, width:150, expandedMode: 'tips', edit: 'text'},
{field:'sex', width:80, title: '性别', sort: true},
{field:'sign', title: '签名', edit: 'textarea', minWidth: 260, expandedWidth: 260, totalRow: '{{!人物:<span class="layui-badge-rim">唐代:{{= d.TOTAL_ROW.era.tang }} </span> <span class="layui-badge-rim">宋代:{{= d.TOTAL_ROW.era.song }}</span> <span class="layui-badge-rim">现代:{{= d.TOTAL_ROW.era.xian }}</span>!}}'},
{field:'experience', width: 100, title: '积分', sort: true, totalRow: '{{!{{= d.TOTAL_NUMS }} 😊!}}'},
{field:'checkin', title:'打卡', width: 100, sort: true, totalRow: '{{!{{= parseInt(d.TOTAL_NUMS) }} 次!}}'},
{field:'ip', title:'IP', width: 120},
{field:'joinTime', title:'加入时间', width: 120},
{fixed: 'right', title:'操作', width: 134, minWidth: 125, toolbar: '#barDemo'}
]],
done: function(){
var id = this.id;
// 下拉按钮测试
dropdown.render({
elem: '#dropdownButton', // 可绑定在任意元素中,此处以上述按钮为例
data: [{
id: 'add',
title: '添加'
},{
id: 'update',
title: '编辑'
},{
id: 'delete',
title: '删除'
}],
// 菜单被点击的事件
click: function(obj){
var checkStatus = table.checkStatus(id)
var data = checkStatus.data; // 获取选中的数据
switch(obj.id){
case 'add':
layer.open({
title: '添加',
type: 1,
area: ['80%','80%'],
content: '<div style="padding: 16px;">自定义表单元素</div>'
});
break;
case 'update':
if(data.length !== 1) return layer.msg('请选择一行');
layer.open({
title: '编辑',
type: 1,
area: ['80%','80%'],
content: '<div style="padding: 16px;">自定义表单元素</div>'
});
break;
case 'delete':
if(data.length === 0){
return layer.msg('请选择一行');
}
layer.msg('delete event');
break;
}
}
});
// 重载测试
dropdown.render({
elem: '#reloadTest', // 可绑定在任意元素中,此处以上述按钮为例
data: [{
id: 'reload',
title: '重载'
},{
id: 'reload-deep',
title: '重载 - 参数叠加'
},{
id: 'reloadData',
title: '仅重载数据'
},{
id: 'reloadData-deep',
title: '仅重载数据 - 参数叠加'
}],
// 菜单被点击的事件
click: function(obj){
switch(obj.id){
case 'reload':
// 重载 - 默认(参数重置)
table.reload('test', {
where: {
abc: '123456',
//test: '新的 test2',
//token: '新的 token2'
},
/*{{!
cols: [[ // 重置表头
{type: 'checkbox', fixed: 'left'},
{field:'id', title:'ID', width:80, fixed: 'left', unresize: true, sort: true, totalRowText: '合计:'},
{field:'sex', title:'性别', width:80, edit: 'text', sort: true},
{field:'experience', title:'积分', width:80, sort: true, totalRow: true, templet: '<div>{{= d.experience }} 分</div>'},
{field:'logins', title:'登入次数', width:100, sort: true, totalRow: true},
{field:'joinTime', title:'加入时间', width:120}
]]
!}}*/
});
break;
case 'reload-deep':
// 重载 - 深度(参数叠加)
table.reload('test', {
where: {
abc: 123,
test: '新的 test1'
},
//defaultToolbar: ['print'], // 重载头部工具栏右侧图标
//cols: ins1.config.cols
}, true);
break;
case 'reloadData':
// 数据重载 - 参数重置
table.reloadData('test', {
where: {
abc: '123456',
//test: '新的 test2',
//token: '新的 token2'
},
scrollPos: 'fixed', // 保持滚动条位置不变 - v2.7.3 新增
height: 2000, // 测试无效参数(即与数据无关的参数设置无效,此处以 height 设置无效为例)
//url: '404',
//page: {curr: 1, limit: 30} // 重新指向分页
});
break;
case 'reloadData-deep':
// 数据重载 - 参数叠加
table.reloadData('test', {
where: {
abc: 123,
test: '新的 test1'
}
}, true);
break;
}
layer.msg('可观察 Network 请求参数的变化');
}
});
// 行模式
dropdown.render({
elem: '#rowMode',
data: [{
id: 'default-row',
title: '单行模式(默认)'
},{
id: 'multi-row',
title: '多行模式'
}],
// 菜单被点击的事件
click: function(obj){
var checkStatus = table.checkStatus(id)
var data = checkStatus.data; // 获取选中的数据
switch(obj.id){
case 'default-row':
table.reload('test', {
lineStyle: null // 恢复单行
});
layer.msg('已设为单行');
break;
case 'multi-row':
table.reload('test', {
// 设置行样式,此处以设置多行高度为例。若为单行,则没必要设置改参数 - 注v2.7.0 新增
lineStyle: 'height: 95px;'
});
layer.msg('即通过设置 lineStyle 参数可开启多行');
break;
}
}
});
},
error: function(res, msg){
console.log(res, msg)
}
});
// 工具栏事件
table.on('toolbar(test)', function(obj){
var id = obj.config.id;
var checkStatus = table.checkStatus(id);
var othis = lay(this);
switch(obj.event){
case 'getCheckData':
var data = checkStatus.data;
layer.alert(layui.util.escape(JSON.stringify(data)));
break;
case 'getData':
var getData = table.getData(id);
console.log(getData);
layer.alert(layui.util.escape(JSON.stringify(getData)));
break;
case 'LAYTABLE_TIPS':
layer.alert('自定义工具栏图标按钮');
break;
};
});
// 表头自定义元素工具事件 --- 2.8.8+
table.on('colTool(test)', function(obj){
var event = obj.event;
console.log(obj);
if(event === 'email-tips'){
layer.alert(layui.util.escape(JSON.stringify(obj.col)), {
title: '当前列属性配置项'
});
}
});
// 触发单元格工具事件
table.on('tool(test)', function(obj){ // 双击 toolDouble
var data = obj.data; // 获得当前行数据
// console.log(obj)
if(obj.event === 'edit'){
layer.open({
title: '编辑 - id:'+ data.id,
type: 1,
area: ['80%','80%'],
content: '<div style="padding: 16px;">自定义表单元素</div>'
});
} else if(obj.event === 'more'){
// 更多 - 下拉菜单
dropdown.render({
elem: this, // 触发事件的 DOM 对象
show: true, // 外部事件触发即显示
data: [{
title: '查看',
id: 'detail'
},{
title: '删除',
id: 'del'
}],
click: function(menudata){
if(menudata.id === 'detail'){
layer.msg('查看操作,当前行 ID:'+ data.id);
} else if(menudata.id === 'del'){
layer.confirm('真的删除行 [id: '+ data.id +'] 么', function(index){
obj.del(); // 删除对应行tr的DOM结构
layer.close(index);
// 向服务端发送删除指令
});
}
},
align: 'right', // 右对齐弹出
style: 'box-shadow: 1px 1px 10px rgb(0 0 0 / 12%);' // 设置额外样式
})
}
});
// 触发表格复选框选择
table.on('checkbox(test)', function(obj){
console.log(obj)
});
// 触发表格单选框选择
table.on('radio(test)', function(obj){
console.log(obj)
});
// 行单击事件
table.on('row(test)', function(obj){
//console.log(obj);
//layer.closeAll('tips');
});
// 行双击事件
table.on('rowDouble(test)', function(obj){
console.log(obj);
});
// 单元格编辑事件
table.on('edit(test)', function(obj){
var field = obj.field; // 得到字段
var value = obj.value; // 得到修改后的值
var data = obj.data; // 得到所在行所有键值
// 值的校验
if(field === 'email'){
if(!/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(obj.value)){
layer.tips('输入的邮箱格式不正确,请重新编辑', this, {tips: 1});
return obj.reedit(); // 重新编辑 -- v2.8.0 新增
}
}
// 编辑后续操作,如提交更新请求,以完成真实的数据更新
// …
layer.msg('编辑成功', {icon: 1});
// 其他更新操作
var update = {};
update[field] = value;
obj.update(update);
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,181 @@
<table class="layui-hide" id="ID-table-demo-editmodes"></table>
{{!<!-- 原生 select 模板(推荐) -->
<script type="text/html" id="TPL-select-primary">
{{# var cityList = d.cityList || ["北京","上海","广州","城市-1"]; }}
<select name="city" class="layui-border select-demo-primary" lay-ignore>
<option value="">原生 select</option>
{{# layui.each(cityList, function(i, v){ }}
<option value="{{= v }}" {{= v === d.city ? 'selected' : '' }}>{{= v }}</option>
{{# }); }}
</select>
</script>
<!-- layui select 在 table 中使用(不推荐。因为当 select 出现在 table 底部时,可能会撑起多余高度) -->
<script type="text/html" id="TPL-select-city">
{{# var cityList = d.cityList || ["北京","上海","广州","城市-1"]; }}
<select name="city" lay-filter="select-demo">
<option value="">select 方式</option>
{{# layui.each(cityList, function(i, v){ }}
<option value="{{= v }}" {{= v === d.city ? 'selected' : '' }}>{{= v }}</option>
{{# }); }}
</select>
</script>
<!-- 推荐 -->
<script type="text/html" id="TPL-dropdpwn-demo">
<button class="layui-btn layui-btn-primary dropdpwn-demo">
<span>{{= d.sex || '保密' }}</span>
<i class="layui-icon layui-icon-down layui-font-12"></i>
</button>
</script>
<!-- laydate -->
<script type="text/html" id="TPL-laydate-demo">
<input class="layui-input laydate-demo" placeholder="选择日期" value="{{= d.fieldname3 || '' }}">
</script>
<!-- colorpicker -->
<script type="text/html" id="TPL-colorpicker-demo">
{{# var color = d.color || ['#16baaa','#16b777','#1E9FFF','#FF5722','#FFB800','#393D49'][Math.round(Math.random()*5)]; }}
<div class="colorpicker-demo" lay-options="{color: '{{= color }}'}"></div>
</script>!}}
<!-- import layui -->
<script>
layui.use(function(){
var $ = layui.$;
var table = layui.table;
var form = layui.form;
var dropdown = layui.dropdown;
var laydate = layui.laydate;
var colorpicker = layui.colorpicker;
// 渲染
table.render({
elem: '#ID-table-demo-editmodes',
url: '/static/2.8/json/table/user.json', // 此处为静态模拟数据,实际使用时需换成真实接口
page: true,
css: [ // 设置单元格样式
// 取消默认的溢出隐藏,并设置适当高度
'.layui-table-cell{height: 50px; line-height: 40px;}',
'.layui-table-cell .layui-colorpicker{width: 38px; height: 38px;}',
'.layui-table-cell select{height: 36px; padding: 0 5px;}'
].join(''),
cols: [[ // 表头
{field: 'id', title: 'ID', width:80, align: 'center', fixed: 'left'},
{field: 'city', title: '原生 select', width:135, unresize: true, templet: '#TPL-select-primary'},
//{field: 'city', title: 'layui select', width:150, templet: '#TPL-select-city'},
{field: 'sex', title: 'dropdown', width:115, unresize: true, align: 'center', templet: '#TPL-dropdpwn-demo'},
{field: 'date', title: 'laydate', width:150, templet: '#TPL-laydate-demo'},
{field: 'color', title: 'color', width:80, unresize: true, align: 'center', templet: '#TPL-colorpicker-demo'},
{field: 'sign', title: '文本', edit: 'textarea'}
]],
done: function(res, curr, count){
var options = this;
// 获取当前行数据
table.getRowData = function(elem){
var index = $(elem).closest('tr').data('index');
return table.cache[options.id][index] || {};
};
// 原生 select 事件
$('.select-demo-primary').on('change', function(){
var value = this.value; // 获取选中项 value
var data = table.getRowData(this); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
// 更新数据中对应的字段
data.city = value;
// 显示 - 仅用于演示
layer.msg('选中值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
});
// layui form select 事件
form.on('select(select-demo)', function(obj){
console.log(obj); // 获取选中项数据
// 获取当前行数据(如 id 等字段,以作为数据修改的索引)
var data = table.getRowData(obj.elem);
// 更新数据中对应的字段
data.city = value;
console.log(data);
});
// dropdown 方式的下拉选择
dropdown.render({
elem: '.dropdpwn-demo',
// trigger: 'hover',
// 此处的 data 值,可根据 done 返回的 res 遍历来赋值
data: [{
title: '男',
id: 100
},{
title: '女',
id: 101
},{
title: '保密',
id: 102
}],
click: function(obj){
var data = table.getRowData(this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
this.elem.find('span').html(obj.title);
// 更新数据中对应的字段
data.sex = obj.title;
// 显示 - 仅用于演示
layer.msg('选中值: '+ obj.title +'<br>当前行数据:'+ JSON.stringify(data));
}
});
// laydate
laydate.render({
elem: '.laydate-demo',
done: function(value, date, endDate){
var data = table.getRowData(this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
// 更新数据中对应的字段
data.date = value;
// 显示 - 仅用于演示
layer.msg('选中值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
}
});
// colorpicker
colorpicker.render({
elem: '.colorpicker-demo',
done: function(value){
var data = table.getRowData(this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
// 更新数据中对应的字段
data.color = value;
// 显示 - 仅用于演示
layer.msg('选中值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
}
});
// 单元格普通编辑事件
table.on('edit(ID-table-demo-editmodes)', function(obj){
var value = obj.value // 得到修改后的值
var data = obj.data // 得到所在行所有键值
var field = obj.field; // 得到字段
// 更新数据中对应的字段
var update = {};
update[field] = value;
obj.update(update);
// 编辑后续操作,如提交更新请求,以完成真实的数据更新
// …
// 显示 - 仅用于演示
layer.msg('编辑值: '+ value +'<br>当前行数据:'+ JSON.stringify(data));
});
// 更多编辑方式……
}
});
});
</script>

View File

@@ -0,0 +1,58 @@
<table class="layui-hide" id="ID-table-demo-editable"></table>
<!-- import layui -->
<script>
layui.use(function(){
var table = layui.table;
var util = layui.util;
// 根据返回数据中某个字段来判断开启该行的编辑
var editable = function(d){
if(d.editable) return 'text'; // 这里假设以 editable 字段为判断依据
};
// 创建表格实例
table.render({
elem: '#ID-table-demo-editable',
url: '/static/2.8/json/table/edit.json', // 此处为静态模拟数据,实际使用时需换成真实接口
page: true,
//,editTrigger: 'dblclick' // 触发编辑的事件类型(默认 click )。 v2.7.0 新增,之前版本固定为单击触发
css: [
// 对开启了编辑的单元格追加样式
'.layui-table-view td[data-edit]{color: #16B777;}'
].join(''),
cols: [[
{checkbox: true, fixed: true},
{field:'id', title: 'ID', width:80, sort: true, fixed: true},
{field:'username', title: '用户名', width:80, edit: editable},
{field:'sex', title: '性别', width:80, sort: true, edit: editable},
{field:'city', title: '城市', width:80, edit: editable},
{field:'sign', title: '签名', edit: editable},
{field:'experience', title: '积分', sort: true, width:80, edit: editable}
]],
height: 310
});
// 单元格编辑后的事件
table.on('edit(ID-table-demo-editable)', function(obj){
var field = obj.field; // 得到修改的字段
var value = obj.value // 得到修改后的值
var oldValue = obj.oldValue // 得到修改前的值 -- v2.8.0 新增
var data = obj.data // 得到所在行所有键值
var col = obj.getCol(); // 得到当前列的表头配置属性 -- v2.8.0 新增
// 值的校验
if(value.replace(/\s/g, '') === ''){
layer.tips('值不能为空', this, {tips: 1});
return obj.reedit(); // 重新编辑 -- v2.8.0 新增
}
// 编辑后续操作,如提交更新请求,以完成真实的数据更新
// …
// 显示 - 仅用于演示
layer.msg('[ID: '+ data.id +'] ' + field + ' 字段更改值为:'+ util.escape(value));
});
});
</script>

View File

@@ -0,0 +1,48 @@
<table class="layui-hide" id="ID-table-demo-filter"></table>
<!-- import layui -->
<script>
layui.use(function(){
var $ = layui.$;
var table = layui.table;
// 渲染
table.render({
elem: '#ID-table-demo-filter',
url:'/static/2.8/json/table/user.json', // 此处为静态模拟数据,实际使用时需换成真实接口
toolbar: 'default',
height: 315,
cols: [function(){
var arr = [
{field:'id', title:'ID', width:80, fixed: 'left'},
{field:'username', title:'用户', width:120},
{field:'sex', title:'性别'},
{field:'city', title:'城市'},
{field:'sign', title:'签名'},
{field:'classify', title:'职业'}
];
// 初始化筛选状态
var local = layui.data('table-filter-test'); // 获取对应的本地记录
layui.each(arr, function(index, item){
if(item.field in local){
item.hide = local[item.field];
}
});
return arr;
}() ],
done: function(){
// 记录筛选状态
var that = this;
that.elem.next().on('mousedown', 'input[lay-filter="LAY_TABLE_TOOL_COLS"]+', function(){
var input = $(this).prev()[0];
// 此处表名可任意定义
layui.data('table-filter-test', {
key: input.name
,value: input.checked
})
});
}
});
});
</script>

View File

@@ -0,0 +1,48 @@
<div class="layui-btn-container">
<button class="layui-btn" lay-on="parseTable">转换为数据表格</button>
</div>
<table lay-filter="parse-table-demo">
<thead>
<tr>
<th lay-data="{field:'name', width:150}">人物</th>
<th lay-data="{field:'nation', width:150}">民族</th>
<th lay-data="{field:'maxim', minWidth: 180}">格言</th>
</tr>
</thead>
<tbody>
<tr>
<td>孔子</td>
<td>华夏</td>
<td>有朋至远方来,不亦乐乎</td>
</tr>
<tr>
<td>孟子</td>
<td>华夏</td>
<td>穷则独善其身,达则兼济天下</td>
</tr>
<tr>
<td>庄子</td>
<td>华夏</td>
<td>朴素而天下莫能与之争美</td>
</tr>
</tbody>
</table>
<!-- import layui -->
<script>
layui.use(function(){
var table = layui.table;
var util = layui.util;
// 事件
util.on('lay-on', {
parseTable: function(){
// 转化静态表格
table.init('parse-table-demo', {
// height: ''
});
}
});
});
</script>

View File

@@ -0,0 +1,56 @@
<table class="layui-hide" id="ID-table-onrowContextmenu"></table>
<!-- import layui -->
<script>
layui.use(['table', 'dropdown', 'util'], function(){
var table = layui.table;
var dropdown = layui.dropdown;
var util = layui.util;
// 渲染
table.render({
elem: '#ID-table-onrowContextmenu',
defaultContextmenu: false, // 是否在 table 行中允许默认的右键菜单
url: '/static/2.8/json/table/user.json', // 此处为静态模拟数据,实际使用时需换成真实接口
page: true,
cols: [[
{field:'id', title:'ID', width:80, fixed: 'left', unresize: true},
{field:'username', title:'用户', width:120},
{field:'sex', title:'性别', width:80},
{field:'city', title:'城市', width:100},
{field:'sign', title:'签名'},
{field:'experience', title:'积分', width:80, sort: true}
]],
});
// 行单击事件
table.on('rowContextmenu(ID-table-onrowContextmenu)', function(obj){
var data = obj.data; // 得到当前行数据
var index = obj.index; // 得到当前行索引
var tr = obj.tr; // 得到当前行 <tr> 元素的 jQuery 对象
var options = obj.config; // 获取当前表格基础属性配置项
// console.log(obj); // 查看对象所有成员
// 右键操作
dropdown.render({
trigger: 'contextmenu',
show: true,
data: [
{title: 'Menu item 1', id: 'AAA'},
{title: 'Menu item 2', id: 'BBB'}
],
click: function(menuData, othis) {
// 显示选中的相关数据 - 仅用于演示
layer.alert(util.escape(JSON.stringify({
dropdown: menuData,
table: obj.data
})));
}
});
// obj.del() // 删除当前行
// obj.update(fields, related); // 修改行数据
obj.setRowChecked({selectedStyle: true}); // 标注行选中状态样式
});
});
</script>

View File

@@ -0,0 +1,42 @@
<table class="layui-hide" id="ID-table-demo-page"></table>
<script type="text/html" id="ID-table-demo-page-pagebar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="footerDemoBtn1">底部按钮1</button>
<button class="layui-btn layui-btn-sm" lay-event="footerDemoBtn2">底部按钮2</button>
</div>
</script>
<!-- import layui -->
<script>
layui.use('table', function(){
var table = layui.table;
// 创建渲染实例
table.render({
elem: '#ID-table-demo-page',
url:'/static/2.8/json/table/user.json', // 此处为静态模拟数据,实际使用时需换成真实接口
page: { // 支持传入 laypage 组件的所有参数某些参数除外jump/elem - 详见文档
layout: ['limit', 'count', 'prev', 'page', 'next', 'skip'], //自定义分页布局
//curr: 5, //设定初始在第 5 页
groups: 1, //只显示 1 个连续页码
first: false, //不显示首页
last: false //不显示尾页
},
pagebar: '#ID-table-demo-page-pagebar', // 分页栏模板
cols: [[
{field:'id', width:80, title: 'ID', sort: true},
{field:'username', width:80, title: '用户名'},
{field:'sex', width:80, title: '性别', sort: true},
{field:'city', width:80, title: '城市'},
{field:'sign', title: '签名', minWidth: 150},
{field:'experience', width:80, title: '积分', sort: true}
]]
});
// 底部分页栏事件
table.on('pagebar(ID-table-demo-page)', function(obj){
var eventValue = obj.event; // 获得按钮 lay-event 值
layer.msg(eventValue);
});
});
</script>

View File

@@ -0,0 +1,40 @@
> 假设这是一段数据源:<a href="/static/2.8/json/table/demo3.json" target="_blank">/static/2.8/json/table/demo3.json</a><br>
尽管它并不符合 table 组件默认规定的数据格式([#详见](#options-async-data)),但可以通过 parseData 回调将其进行转换。
<table class="layui-hide" id="ID-table-demo-parse"></table>
<!-- import layui -->
<script>
layui.use('table', function(){
var table = layui.table;
// 渲染
table.render({
elem: '#ID-table-demo-parse',
url:'/static/2.8/json/table/demo3.json',
page: true,
response: {
statusCode: 200 // 重新规定成功的状态码为 200table 组件默认为 0
},
// 将原始数据解析成 table 组件所规定的数据格式
parseData: function(res){
return {
"code": res.status, //解析接口状态
"msg": res.message, //解析提示文本
"count": res.total, //解析数据长度
"data": res.rows.item //解析数据列表
};
},
cols: [[
{field:'id', title:'ID', width:80, fixed: 'left', unresize: true, sort: true},
{field:'username', title:'用户名', width:120},
{field:'email', title:'邮箱', width:150},
{field:'experience', title:'积分', width:100, sort: true},
{field:'sex', title:'性别', width:80, sort: true},
{field:'sign', title:'签名'},
{field:'joinTime', title:'加入时间', width:120}
]],
height: 315
});
});
</script>

View File

@@ -0,0 +1,77 @@
<form class="layui-form layui-row layui-col-space16">
<div class="layui-col-md4">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-username"></i>
</div>
<input type="text" name="A" value="" placeholder="Field A" class="layui-input" lay-affix="clear">
</div>
</div>
<div class="layui-col-md4">
<div class="layui-input-wrap">
<input type="text" name="B" placeholder="Field B" lay-affix="clear" class="layui-input">
</div>
</div>
<div class="layui-col-md4">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-date"></i>
</div>
<input type="text" name="C" readonly placeholder="Field C" class="layui-input demo-table-search-date">
</div>
</div>
<div class="layui-btn-container layui-col-xs12">
<button class="layui-btn" lay-submit lay-filter="demo-table-search">Search</button>
<button type="reset" class="layui-btn layui-btn-primary">Clear</button>
</div>
</form>
<table class="layui-hide" id="ID-table-demo-search"></table>
<!-- import layui -->
<script>
layui.use(function(){
var table = layui.table;
var form = layui.form;
var laydate = layui.laydate;
// 创建表格实例
table.render({
elem: '#ID-table-demo-search',
url: '/static/2.8/json/table/user.json', // 此处为静态模拟数据,实际使用时需换成真实接口
cols: [[
{type: 'radio', title: '😊', fixed: true}, // 单选框
{field:'id', title: 'ID', width:80, sort: true, fixed: true},
{field:'username', title: '用户名', width:80},
{field:'sex', title: '性别', width:80, sort: true},
{field:'city', title: '城市', width:80},
{field:'sign', title: '签名'},
{field:'experience', title: '积分', sort: true, width:80}
]],
page: true,
height: 310
});
// 日期
laydate.render({
elem: '.demo-table-search-date'
});
// 搜索提交
form.on('submit(demo-table-search)', function(data){
var field = data.field; // 获得表单字段
// 执行搜索重载
table.reload('ID-table-demo-search', {
page: {
curr: 1 // 重新从第 1 页开始
},
where: field // 搜索的字段
});
layer.msg('搜索成功<br>此处为静态模拟数据,实际使用时换成真实接口即可');
return false; // 阻止默认 form 跳转
});
});
</script>

View File

@@ -0,0 +1,61 @@
<table class="layui-hide" id="ID-table-demo-setRowChecked"></table>
<script type="text/html" id="demo-toolbar-setRowChecked">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="getCheckData">获取选中行数据</button>
</div>
</script>
<!-- import layui -->
<script>
layui.use('table', function(){
var table = layui.table;
// 渲染
table.render({
elem: '#ID-table-demo-setRowChecked',
url: '/static/2.8/json/table/user.json', // 此处为静态模拟数据,实际使用时需换成真实接口
page: true,
cols: [[
// {type: 'radio', fixed: 'left'},
{field:'id', title:'ID', width:80, fixed: 'left', unresize: true},
{field:'username', title:'用户', width:120},
{field:'sex', title:'性别', width:80},
{field:'city', title:'城市', width:100},
{field:'sign', title:'签名'},
{field:'experience', title:'积分', width:80, sort: true}
]],
toolbar: '#demo-toolbar-setRowChecked',
initSort: { // 设置初始排序
field: 'experience', // 字段名
type: 'desc' // 倒序
},
height: 366
});
// 行单击事件( 双击事件为: rowDouble )
table.on('row(ID-table-demo-setRowChecked)', function(obj){
var data = obj.data; // 获取当前行数据
// 显示 - 仅用于演示
layer.msg('当前行数据:<br>'+ JSON.stringify(data), {
offset: '65px'
});
// 标注当前点击行的选中状态
obj.setRowChecked({
type: 'radio' // radio 单选模式checkbox 复选模式
});
});
// 头工具栏事件
table.on('toolbar(ID-table-demo-setRowChecked)', function(obj){
var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
switch(obj.event){
case 'getCheckData':
var data = checkStatus.data; // 获取选中行数据
layer.alert(JSON.stringify(data)); // 显示 - 仅用于演示
break;
};
});
});
</script>

View File

@@ -0,0 +1,207 @@
默认风格:
<table class="layui-table">
<colgroup>
<col width="150">
<col width="150">
<col>
</colgroup>
<thead>
<tr>
<th>人物</th>
<th>民族</th>
<th>格言</th>
</tr>
</thead>
<tbody>
<tr>
<td>孔子</td>
<td>华夏</td>
<td>有朋至远方来,不亦乐乎</td>
</tr>
<tr>
<td>孟子</td>
<td>华夏</td>
<td>穷则独善其身,达则兼济天下</td>
</tr>
</tbody>
</table>
行边框表格:
<table class="layui-table" lay-skin="line">
<colgroup>
<col width="150">
<col width="150">
<col>
</colgroup>
<thead>
<tr>
<th>人物</th>
<th>民族</th>
<th>格言</th>
</tr>
</thead>
<tbody>
<tr>
<td>孔子</td>
<td>华夏</td>
<td>有朋至远方来,不亦乐乎</td>
</tr>
<tr>
<td>孟子</td>
<td>华夏</td>
<td>穷则独善其身,达则兼济天下</td>
</tr>
</tbody>
</table>
列边框表格:
<table class="layui-table" lay-skin="row">
<colgroup>
<col width="150">
<col width="150">
<col>
</colgroup>
<thead>
<tr>
<th>人物</th>
<th>民族</th>
<th>格言</th>
</tr>
</thead>
<tbody>
<tr>
<td>孔子</td>
<td>华夏</td>
<td>有朋至远方来,不亦乐乎</td>
</tr>
<tr>
<td>孟子</td>
<td>华夏</td>
<td>穷则独善其身,达则兼济天下</td>
</tr>
</tbody>
</table>
无边框表格:
<table class="layui-table" lay-skin="nob">
<colgroup>
<col width="150">
<col width="150">
<col>
</colgroup>
<thead>
<tr>
<th>人物</th>
<th>民族</th>
<th>格言</th>
</tr>
</thead>
<tbody>
<tr>
<td>孔子</td>
<td>华夏</td>
<td>有朋至远方来,不亦乐乎</td>
</tr>
<tr>
<td>孟子</td>
<td>华夏</td>
<td>穷则独善其身,达则兼济天下</td>
</tr>
</tbody>
</table>
小尺寸表格:
<table class="layui-table" lay-size="sm">
<colgroup>
<col width="150">
<col width="150">
<col>
</colgroup>
<thead>
<tr>
<th>人物</th>
<th>民族</th>
<th>格言</th>
</tr>
</thead>
<tbody>
<tr>
<td>孔子</td>
<td>华夏</td>
<td>有朋至远方来,不亦乐乎</td>
</tr>
<tr>
<td>孟子</td>
<td>华夏</td>
<td>穷则独善其身,达则兼济天下</td>
</tr>
</tbody>
</table>
大尺寸表格:
<table class="layui-table" lay-size="lg">
<colgroup>
<col width="150">
<col width="150">
<col>
</colgroup>
<thead>
<tr>
<th>人物</th>
<th>民族</th>
<th>格言</th>
</tr>
</thead>
<tbody>
<tr>
<td>孔子</td>
<td>华夏</td>
<td>有朋至远方来,不亦乐乎</td>
</tr>
<tr>
<td>孟子</td>
<td>华夏</td>
<td>穷则独善其身,达则兼济天下</td>
</tr>
</tbody>
</table>
开启偶数行背景色:
<table class="layui-table" lay-even>
<colgroup>
<col width="150">
<col width="150">
<col>
</colgroup>
<thead>
<tr>
<th>人物</th>
<th>民族</th>
<th>格言</th>
</tr>
</thead>
<tbody>
<tr>
<td>孔子</td>
<td>华夏</td>
<td>有朋至远方来,不亦乐乎</td>
</tr>
<tr>
<td>孟子</td>
<td>华夏</td>
<td>穷则独善其身,达则兼济天下</td>
</tr>
<tr>
<td>庄子</td>
<td>华夏</td>
<td>朴素而天下莫能与之争美</td>
</tr>
</tbody>
</table>

View File

@@ -0,0 +1,63 @@
<table class="layui-hide" id="ID-table-demo-templet"></table>
<script type="text/html" id="ID-table-demo-templet-user">{{!
<a href="" target="_blank">{{= d.username }}</a>
!}}</script>
<script type="text/html" id="ID-table-demo-templet-switch">{{!
<!-- 这里的 checked 的状态值判断仅作为演示 -->
<input type="checkbox" name="status" value="{{= d.id }}" title="热|" lay-skin="switch" lay-filter="demo-templet-status" {{= d.id == 10001 ? "checked" : "" }}>
!}}</script>
<script type="text/html" id="ID-table-demo-templet-other">{{!
<span class="layui-badge-rim" style="margin-right: 10px;">评分{{= d.score }}</span>
<span class="layui-badge-rim">职业{{= d.classify }}</span>
<!--
<span class="layui-badge-rim">下标{{= d.LAY_INDEX }}</span>
<span class="layui-badge-rim">序号{{= d.LAY_NUM }}</span>
-->
!}}</script>
<!-- import layui -->
<script>
layui.use(['table'], function(){
var table = layui.table;
var form = layui.form;
// 创建渲染实例
table.render({
elem: '#ID-table-demo-templet',
url:'/static/2.8/json/table/user.json', // 此处为静态模拟数据,实际使用时需换成真实接口
page: true,
height: '315px',
cols: [[
{type: 'checkbox', fixed: 'left'},
// 未自定义模板的普通列
{field:'id', fixed: 'left', width:80, title: 'ID', sort: true},
// 模板 - 选择器写法
{field:'username', width:80, title: '用户', templet: '#ID-table-demo-templet-user'},
// 模板 - 函数写法
{field:'sex', width:60, title: '性别', templet: function(d){
if(d.sex === '男'){
return '<span style="color: blue">♂</span>';
} else {
return '<span style="color: pink">♀</span>';
}
}},
// 模板 - 普通字符写法
{field:'city', width:115, title: '城市', templet: '<div><i class="layui-icon layui-icon-location"></i> {{!{{= d.city }}!}}</div>'},
// 模板中可包含任意字段、任意内容(如表单等)
{title: '状态', width:85, templet: '#ID-table-demo-templet-switch'},
{title: '其他', minWidth:200, templet: '#ID-table-demo-templet-other'}
]]
});
// 状态 - 开关操作
form.on('switch(demo-templet-status)', function(obj){
var id = this.value;
var name = this.name;
layer.tips(id + ' ' + name + ': '+ obj.elem.checked, obj.othis);
});
});
</script>

View File

@@ -0,0 +1,53 @@
常用两级表头:
<table class="layui-table" lay-data="{url:'/static/2.8/json/table/demo2.json?v=2', page: true, limit: 6, limits:[6]}" id="ID-table-demo-theads-1">
<thead>
<tr>
<th lay-data="{checkbox:true}" rowspan="2"></th>
<th lay-data="{field:'username', width:80}" rowspan="2">联系人</th>
<th lay-data="{align:'center'}" colspan="3">地址</th>
<th lay-data="{field:'amount'}" rowspan="2">数量</th>
<th lay-data="{fixed: 'right', width: 160, align: 'center', toolbar: '#templet-demo-theads-tool'}" rowspan="2">操作</th>
</tr>
<tr>
<th lay-data="{field:'province', width:100}"></th>
<th lay-data="{field:'city', width:100}"></th>
<th lay-data="{field:'zone', width:100}"></th>
</tr>
</thead>
</table>
更多级表头(支持无限极):
<table class="layui-table" lay-data="{url:'/static/2.8/json/table/demo2.json?v=3', cellMinWidth: 80, page: true}" id="ID-table-demo-theads-2">
<thead>
<tr>
<th lay-data="{field:'username', fixed:'left', width:80}" rowspan="3">联系人</th>
<th lay-data="{field:'amount'}" rowspan="3">数量</th>
<th lay-data="{align:'center'}" colspan="5">地址1</th>
<th lay-data="{align:'center'}" colspan="2">地址2</th>
<th lay-data="{fixed: 'right', width: 160, align: 'center', toolbar: '#templet-demo-theads-tool'}" rowspan="3">操作</th>
</tr>
<tr>
<th lay-data="{field:'province'}" rowspan="2"></th>
<th lay-data="{field:'city'}" rowspan="2"></th>
<th lay-data="{align:'center'}" colspan="3">详细</th>
<th lay-data="{field:'province'}" rowspan="2"></th>
<th lay-data="{field:'city'}" rowspan="2"></th>
</tr>
<tr>
<th lay-data="{field:'street'}" rowspan="2">街道</th>
<th lay-data="{field:'address'}">小区</th>
<th lay-data="{field:'house'}">单元</th>
</tr>
</thead>
</table>
<script type="text/html" id="templet-demo-theads-tool">
<div class="layui-clear-space">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">按钮1</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="edit">按钮2</a>
</div>
</script>
<!-- import layui -->

View File

@@ -0,0 +1,957 @@
---
title: 表格组件 table
toc: true
---
# 表格组件 🔥
> 表格组件 `table` 是 Layui 中使用率极高的一个组件,它以表格的承载方式对数据进行渲染、重载、排序、统计、分页等等一系列交互操作,并提供了丰富的 API 用于扩展,基本涵盖了日常业务所涉及的大部分需求。
<h2 id="examples" lay-toc="{anchor: null}" style="margin-bottom: 0;">示例</h2>
以下所有示例中演示的数据均为「静态模拟数据」,实际使用时换成您的真实接口即可。
<div class="ws-docs-showcase"></div>
<div>
{{- d.include("/table/detail/demo.md") }}
</div>
<h2 id="api" lay-toc="{bold: true, hot: true}">API</h2>
| API | 描述 |
| --- | --- |
| var table = layui.table | 获得 `table` 模块。 |
| [table.set(options)](#set) | 设定全局默认属性项。 |
| [table.render(options)](#render) | table 组件渲染,核心方法。 |
| [table.init(filter, options)](#table.init) | 初始化渲染静态表格。 |
| [table.reload(id, options, deep)](#table.reload) | 表格完整重载。 |
| [table.reloadData(id, options, deep)](#table.reloadData) <sup>2.7+</sup> | 表格数据重载。 |
| [table.renderData(id)](#table.renderData) <sup>2.8.5+</sup> | 重新渲染数据。 |
| [table.checkStatus(id)](#table.checkStatus) | 获取选中行相关数据。 |
| [table.setRowChecked(id, opts)](#table.setRowChecked) <sup>2.8+</sup> | 设置行选中状态。 |
| [table.getData(id)](#table.getData) | 获取当前页所有行表格数据。 |
| [table.cache](#table.cache) | 获取表格缓存数据集(包含特定字段)。 |
| [table.resize(id)](#table.resize) | 重置表格尺寸。 |
| [table.exportFile(id, data, opts)](#table.exportFile) | 导出表格数据到本地文件。 |
| [table.getOptions(id)](#table.getOptions) <sup>2.8+</sup> | 获取表格实例配置项。 |
| [table.hideCol(id, cols)](#table.hideCol) <sup>2.8+</sup> | 设置表格列的显示隐藏属性。 |
| [table.on(\'event(filter)\', callback)](#table.on) | table 相关事件。 |
<h3 id="set" class="ws-anchor ws-bold">全局设置</h3>
- 参数 `options` : 基础属性配置项。[#详见属性](#options)
该方法主要用于初始化设置属性默认值。实际应用时,必须先设置该方法,再执行渲染、重载等操作。
```js
layui.use(function(){
var table = layui.table;
// 全局设置
table.set({
headers: {token: '123'}
});
// 渲染
table.render(options);
});
```
<h3 id="render" lay-toc="{level: 2}" class="ws-anchor ws-bold">渲染</h3>
table 提供了以下三种渲染模式,在实际使用时,一般按情况选择其中一种即可。
| 渲染方式 | 描述 |
| --- | --- |
| [方法配置渲染](#table.render) | 通过 table 组件提供的核心方法 `table.render(options)` 完成的渲染。<sup>推荐</sup> |
| [模板配置渲染](#view-render) | 通过 `<table>` 标签的 `lay-options="{}"` 属性定义模板,组件自动对其进行解析并完成渲染。 |
| [静态表格渲染](#table.init) | 对一段已经包含数据内容的静态表格进行动态化转换,使其具备 table 组件的相关功能。 |
<h4 id="table.render" lay-pid="render" class="ws-anchor ws-bold">方法配置渲染</h4>
`table.render(options);`
- 参数 `options` : 基础属性配置项。[#详见属性](#options)
该方法返回当前实例对象,包含可操作当前表格的一些成员方法。
```html
<table id="test"></table>
<!-- import layui -->
<script>
layui.use(function(){
var table = layui.table;
// 渲染,并获得实例对象
var inst = table.render({
elem: '#test', // 绑定元素选择器
// 其他属性
// …
});
// 实例对象成员
inst.config; // 当前表格配置属性
inst.reload(options, deep); // 对当前表格的完整重载。参数 deep 表示是否深度重载。
inst.reloadData(options, deep); // 对当前表格的数据重载。参数 deep 同上。
inst.resize(); // 对当前表格重新适配尺寸
inst.setColsWidth() // 对当前表格重新分配列宽
})
</script>
```
<h4 id="view-render" lay-pid="render" class="ws-anchor ws-bold">模板配置渲染</h4>
`<table>` 元素中直接书写 `lay-options="{}"` 属性,组件将自动对其进行解析并完成渲染。
```
<!-- 此处 `lay-options` 定义基础属性 -->
<table class="layui-table" lay-options="{url: ''}" id="test">
<thead>
<tr>
<!-- 此处 `lay-options` 定义表头属性 -->
<th lay-options="{field: 'title'}">Title</th>
</tr>
</thead>
</table>
```
> 2.8 之前版本通过 `lay-data="{}"` 定义属性配置项;<br>
> 2.8+ 版本推荐采用 `lay-options`,但同时兼容 `lay-data`。
<h4 id="table.init" lay-pid="render" class="ws-anchor ws-bold">静态表格渲染</h4>
`table.init(filter, options);`
- 参数 `filter` : `<table>` 元素对应的 `lay-filter` 属性值
- 参数 `options` : 基础属性配置项。[#详见属性](#options)
该方法用于将已输出在页面中的静态表格内容转换为动态 table 组件。[#参考相关示例](#demo-init)
```html
<table lay-filter="test">
表格内容
</table>
<!-- import layui -->
<script>
layui.use(function(){
var table = layui.table;
// 将静态表格进行动态化
table.init('test', {
height: 366,
// 其他属性
// …
});
});
</script>
```
<h2 id="options-intro" lay-toc="{level: 2}">属性 🔥</h2>
属性是指 table *渲染、重载* 时的配置选项(`options`),它本身是一个 `object` 参数。如:
```
// 渲染
table.render({
// options
elem: '',
cols: [[]],
// …
});
// 重载
table.reload(id, {
// options
});
若为模板配置渲染,则 lay-options 或 lay-data 的属性值即为属性的配置选项(:
<table lay-options="{url: ''}"> … </table>
```
table 的属性众多,我们大致分为以下几种:
| 属性类别 | 描述 |
| --- | --- |
| [基础属性](#options) | - |
| [异步属性](#options.ajax) | 用于和异步数据请求相关的基础属性,由于相关属性成员较多,所以单独提取介绍。 |
| [表头属性](#options.cols) | 基础属性 `cols` 的子属性集。 |
<h3 id="options" lay-toc="{level: 3, hot: true}" class="ws-bold">基础属性</h3>
<div>
{{- d.include("/table/detail/options.md") }}
</div>
<h3 id="options.ajax" lay-toc="{level: 3, hot: true}" class="ws-bold">异步属性</h3>
异步属性本质也是基础属性,当开启 `url` 属性时才有效,由于相关属性成员较多,所以单独提取介绍。
<div>
{{- d.include("/table/detail/options.ajax.md") }}
</div>
<h3 id="options.cols" lay-toc="{level: 3, hot: true}" class="ws-bold">表头属性</h3>
表头属性是基础属性 `cols` 的子集,其使用频率甚至超过基础属性本身。
<div>
{{- d.include("/table/detail/options.cols.md") }}
</div>
<h3 id="reload" lay-toc="{level: 2}" class="ws-anchor ws-bold">重载</h3>
即对一段已经渲染好的表格重新设置属性并渲染,可分为以下几种重载方式:
| 重载方式 | API |
| --- | --- |
| [完整重载](#table.reload) | [table.reload(id, options, deep)](#table.reload) |
| [仅数据重载](#table.reloadData) | [table.reloadData(id, options, deep)](#table.reloadData) |
重载的使用方式完全相同,区别只是在于参与重载时的属性差异及其对应的效果差异。一般按照实际需求选择使用。
<h4 id="table.reload" lay-pid="reload" class="ws-anchor ws-bold">完整重载</h4>
`table.reload(id, options, deep);`
- 参数 `id` : table 渲染时的 `id` 属性值
- 参数 `options` : 为基础属性配置项
- 参数 `deep` <sup>2.6+</sup> : 是否采用深度重载(即重载时始终携带初始时及上一次重载时的参数),默认 false。<div style="margin-top:5px;"><button type="button" class="layui-btn layui-btn-sm layui-btn-primary" lay-layer="{content: '#DOCS-table-reload-comp'}">2.6 之前版本的 <code>table.reload()</code> 方法兼容性说明</button></div>
<div style="display: none;" id="DOCS-table-reload-comp">
<div class="layui-text">
<p>由于 2.6 之前的版本是采用深度重载,所以如果您之前利用了该机制,那么升级 Layui 时,需通过以下任一方式进行相应的兼容性适配:</p>
<strong>方法一:</strong>
<p>追加参数兼容:<pre><code>table.reload(id, options, true);</code></pre></p>
<strong>方法二:</strong>
<p>方法重写兼容。将以下代码放入您的公共 JS 代码中</p>
<pre><code>// 对 2.6 之前版本的 table.reload() 方法兼容
var tableReload = table.reload;
table.reload = function(){
var args = [];
layui.each(arguments, function(index, item){
args.push(item);
});
args[2] === undefined && (args[2] = true);
return tableReload.apply(null, args);
}; </code></pre>
</div>
</div>
该方法用于对表格的视图和数据在内的全部重载,所有属性均会参与到重载中,对应的表格会有一个直观的刷新效果。
```
// 渲染
table.render({
elem: '', // 绑定元素选择器
id: 'test', // 自定义 id 索引
// 其他属性 …
});
// 完整重载 - 所有属性属性(options)均可参与到重载中
table.reload('test', {
where: { // 传递数据异步请求时携带的字段
aaa: '111',
bbb: '222'
//…
},
height: 1000 // 重设高度
});
```
<h4 id="table.reloadData" lay-pid="reload" class="ws-anchor ws-bold">仅数据重载 <sup>2.7+</sup></h4>
`table.reloadData(id, options, deep);`
- 参数同 `table.reload(id, options, deep)` 参数
该方法用于对表格的数据重载,与数据无关的属性不会参与到重载中。因此若只是更新数据,该方法可大幅提升体验。
```
// 渲染
table.render({
elem: '', // 绑定元素选择器
id: 'test', // 自定义 id 索引
// 其他属性 …
});
// 数据重载 - 仅与数据相关的属性(options)能参与到重载中
table.reloadData('test', {
where: {}, // 数据异步请求时携带的字段集 --- 属性设置有效,因属于数据相关属性
scrollPos: true, // 设定重载数据或切换分页时的滚动条的位置状态 --- 属性设置有效
// …
height: 2000 // 高度 --- 属性设置无效,因不属于数据相关属性
});
```
<h3 id="table.renderData" lay-pid="api" class="ws-anchor ws-bold">重新渲染数据 <sup>2.8.5+</sup></h3>
`table.renderData(id);`
- 参数 `id` : table 渲染时的 `id` 属性值
该方法用于重新渲染数据,一般在修改 `table.cache` 后使用。
```js
// 渲染
table.render({
elem: '', // 绑定元素选择器
id: 'test', // 自定义 id 索引
// 其他属性 …
});
// 获取当前实例的数据缓存
var data = table.cache['test'];
// 获取某行数据,并从 data 中移除该行
var item = data.splice(index, 1) // index 为当前行下标,一般可在事件中通过 obj.index 得到
// 将某行数据移动到另外某行
data.splice(newIndex, 0, item[0]);
// 根据 table.cache 重新渲染数据
table.renderData('test');
```
<h3 id="table.checkStatus" lay-pid="api" class="ws-anchor ws-bold">获取选中行</h3>
`table.checkStatus(id);`
- 参数 `id` : table 渲染时的 `id` 属性值
该方法用于获取表格当前选中行相关数据
```js
// 渲染
table.render({
elem: '', // 绑定元素选择器
id: 'test', // 自定义 id 索引
// 其他属性 …
});
// 获取选中行相关数据
var tableStatus = table.checkStatus('test');
console.log(checkStatus.data) // 选中行的数据
console.log(checkStatus.data.length) // 选中行数量,可作为是否有选中行的条件
console.log(checkStatus.isAll ) // 表格是否全选
```
<h3 id="table.setRowChecked" lay-pid="api" class="ws-anchor ws-bold">设置行选中状态 <sup>2.8+</sup></h3>
`table.setRowChecked(id, opts);`
- 参数 `id` : table 渲染时的 `id` 属性值
- 参数 `opts` : 设置行选中时的可选属性,详见下表
| opts | 描述 | 类型 | 默认值 |
| --- | --- | --- | --- |
| type | 选中方式。可选值: `checkbox,radio` | string | `checkbox` |
| index | 选中行的下标。即数据的所在数组下标(`0` 开头)。<br>可设置 `all` 表示全选。 | number<br>string | - |
| checked | 选中状态值。 <ul><li>若传递该属性,则赋值固定值。</li><li>若不传递该属性(默认),则 `checkbox` 将在 `true\|false` 中自动切换值,而 `radio` 将赋值 `true` 固定值。<sup>2.8.4+</sup></li></ul> | boolean | - |
该方法用于设置行的选中样式及相关的特定属性值 `LAY_CHECKED`
```js
// 渲染
table.render({
elem: '', // 绑定元素选择器
id: 'test', // 自定义 id 索引
// 其他属性 …
});
// 设置某行选中
table.setRowChecked('test', {
index: 0, // 选中行的下标。 0 表示第一行
});
// 取消选中行
table.setRowChecked('test', {
index: 'all', // 所有行
checked: false
});
```
<h3 id="table.getData" lay-pid="api" class="ws-anchor ws-bold">获取当前页接口数据</h3>
`table.getData(id);`
- 参数 `id` : table 渲染时的 `id` 属性值
该方法用于获取表格当前页的数据,它对应的是接口返回的原始数据,不包含 table 组件内部的特定字段。
```
// 渲染
table.render({
elem: '', // 绑定元素选择器
id: 'test', // 自定义 id 索引
// 其他属性 …
});
// 获取当前页接口数据
var data = table.getData('test');
console.log(data);
```
<h3 id="table.cache" lay-pid="api" class="ws-anchor ws-bold">获取表格缓存数据集</h3>
`var tableCache = table.cache;`
`table.cache` 是一段存储当前页表格所有实例的当前页的临时数据,通过 id 作为索引,它包含接口返回的原始数据和组件内部的特定字段。 使用该静态属性可对表格数据进行*读写*操作。
```
// 渲染
table.render({
elem: '', // 绑定元素选择器
id: 'test', // 自定义 id 索引
// 其他属性 …
});
// 获取对应 table 的临时数据
var thisCache = table.cache['test'] || {};
// 变更对应 table 的临时数据中的某个字段值
thisCache.fieldName = 123;
```
<h3 id="table.resize" lay-pid="api" class="ws-anchor ws-bold">重置尺寸</h3>
`table.resize(id);`
- 参数 `id` : table 渲染时的 `id` 属性值
该方法用于重置表格尺寸和结构,其内部完成了*固定列高度平铺、动态分配列宽、容器滚动条宽高补丁* 等适配。它一般用于修复特殊情况下导致的列宽适配异常(如浏览器窗口尺寸改变导致的表格父容器宽度变化),以保证表格尺寸依旧能友好展示。
```
// 渲染
table.render({
elem: '', // 绑定元素选择器
id: 'test', // 自定义 id 索引
// 其他属性 …
});
// 重置对应 table 的尺寸,一般写在表格外部容器宽高发生变化后的段落
table.resize('test');
```
<h3 id="table.exportFile" lay-pid="api" class="ws-anchor ws-bold">导出数据</h3>
`table.exportFile(id, data, opts);`
- 参数 `id` : table 渲染时的 `id` **或** 要导出的数据表头(当 `id``array` 类型时)。
- 参数 `data` : 要导出的自定义数据,参数可选。
- 参数 `opts` <sup>2.7+</sup>: 导出数据时的属性可选项,支持: `type,title`
该方法用于外部导出对应 table 的数据和任意自定义数据。
```
// 渲染
table.render({
elem: '', // 绑定元素选择器
id: 'test', // 自定义 id 索引
// 其他属性 …
});
// 外部导出对应 table 的数据
table.exportFile('test');
// 导出自定义数据
table.exportFile(['名字','性别','年龄'], [
['张三','男','20'],
['李四','女','18'],
['王五','女','19']
], {
type: 'csv', // 导出的文件格式,支持: csv,xls
title: '导出的文件标题'
});
```
<h3 id="table.getOptions" lay-pid="api" class="ws-anchor ws-bold">获取配置项 <sup>2.8+</sup></h3>
`table.getOptions(id);`
- 参数 `id` : table 渲染时的 `id` 属性值
该方法用于外部获取对应 table 实例的属性配置项。
```
// 渲染
table.render({
elem: '', // 绑定元素选择器
id: 'test', // 自定义 id 索引
// 其他属性 …
});
// 获取配置项
var thisOptions = table.getOptions('test');
console.log(thisOptions);
```
<h3 id="table.hideCol" lay-pid="api" class="ws-anchor ws-bold">设置列显示或隐藏 <sup>2.8+</sup></h3>
`table.hideCol(id, cols);`
- 参数 `id` : table 渲染时的 `id` 属性值
- 参数 `cols` : 设置列(表头)显示或隐藏状态
该方法用于外部设置对应 table 列的显示与隐藏状态。
```
// 渲染
table.render({
elem: '', // 绑定元素选择器
id: 'test', // 自定义 id 索引
// 其他属性 …
});
// 设置对应列的显示或隐藏
table.hideCol('test', {
field: 'title', // 对应表头的 field 属性值
hide: true // `true` or `false`
});
// 同时设置多列的显示或隐藏
table.hideCol('test', [{
field: 'title1',
hide: true
}, {
field: 'title2',
hide: false
}, {
field: 'title3',
hide: false
}]);
// 显示或隐藏全部列
table.hideCol('test', false); // `true` or `false`
```
<h2 id="table.on" lay-toc="{hot: true}">事件</h2>
`table.on('event(filter)', callback);`
- 参数 `event(filter)` 是事件的特定结构。 `event` 为事件名,支持的事件见下表。`filter` 为元素属性 `lay-filter` 对应的值。
- 参数 `callback` 为事件执行时的回调函数,并返回一个包含各项成员的 `object` 类型的参数。
| event | 描述 |
| --- | --- |
| [toolbar](#on-toolbar) | 头部工具栏事件 |
| [sort](#on-sort) | 表头排序切换事件 |
| [colTool](#on-colTool) <sup>2.8.8+</sup> | 表头自定义元素工具事件 |
| [colResized](#on-colResized) <sup>2.8+</sup> | 列拖拽宽度后的事件 |
| [colToggled](#on-colToggled) <sup>2.8+</sup> | 列筛选(显示或隐藏)后的事件 |
| [row / rowDouble](#on-row) | 行单击和双击事件 |
| [rowContextmenu](#on-rowContextmenu) <sup>2.8+</sup> | 行右键菜单事件 |
| [edit](#on-edit) | 单元格编辑事件 |
| [tool / toolDouble](#on-tool) 🔥 | 单元格工具事件。可在该事件中实现行的更新与删除操作。 |
| [checkbox](#on-checkbox) | 复选框事件 |
| [radio](#on-radio) | 单选框事件 |
| [pagebar](#on-pagebar) <sup>2.7+</sup> | 尾部分页栏事件 |
<h3 id="on-toolbar" lay-pid="table.on" class="ws-anchor ws-bold">头部工具栏事件</h3>
`table.on('toolbar(filter)', callback);`
点击头部工具栏区域设定了属性为 `lay-event=""` 的元素时触发。如:
```html
<!-- 原始容器 -->
<table id="test" lay-filter="test"></table>
<!-- 工具栏模板 -->
<script type="text/html" id="toolbarDemo">
<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>
<!-- import layui -->
<script>
layui.use(function(){
var table = layui.table;
// 渲染
table.render({
elem: '#test',
toolbar: '#toolbarDemo',
// … // 其他属性
});
// 头部工具栏事件
table.on('toolbar(test)', function(obj){
var options = obj.config; // 获取当前表格属性配置项
var checkStatus = table.checkStatus(options.id); // 获取选中行相关数据
console.log(obj); // 查看对象所有成员
// 根据不同的事件名进行相应的操作
switch(obj.event){ // 对应模板元素中的 lay-event 属性值
case 'add':
layer.msg('添加');
break;
case 'delete':
layer.msg('删除');
break;
case 'update':
layer.msg('编辑');
break;
};
});
});
</script>
```
<h3 id="on-sort" lay-pid="table.on" class="ws-anchor ws-bold">排序切换事件</h3>
`table.on('sort(filter)', callback);`
点击表头排序时触发,它通常在设置 `autoSort: false ` 基础属性时使用,以呈现后端的排序,而不是默认的前端排序。
```js
var table = layui.table;
// 禁用前端自动排序,以便由服务端直接返回排序好的数据
table.render({
elem: '#test',
autoSort: false, // 禁用前端自动排序。
// … // 其他属性
});
// 触发排序事件
table.on('sort(test)', function(obj){
console.log(obj.field); // 当前排序的字段名
console.log(obj.type); // 当前排序类型desc降序、asc升序、null空对象默认排序
console.log(this); // 当前排序的 th 对象
// 尽管我们的 table 自带排序功能,但并没有请求服务端。
// 有些时候,你可能需要根据当前排序的字段,重新向后端发送请求,从而实现服务端排序,如:
table.reload('test', {
initSort: obj, // 记录初始排序,如果不设的话,将无法标记表头的排序状态。
where: { // 请求参数(注意:这里面的参数可任意定义,并非下面固定的格式)
field: obj.field, // 排序字段
order: obj.type // 排序方式
}
});
});
```
<h3 id="on-colTool" lay-pid="table.on" class="ws-anchor ws-bold">表头自定义元素工具事件 <sup>2.8.8+</sup></h3>
`table.on('colTool(filter)', callback);`
点击表头单元格中带有 `lay-event` 属性的自定义元素触发,可充分借助该事件扩展 table 更多的操作空间。
```js
var table = layui.table;
// 渲染
table.render({
elem: '#test',
cols: [[
{field:'username', title:'用户名 <i class="layui-icon layui-icon-username" lay-event="username"></i>'
]]
// … // 其他属性
});
// 表头自定义元素工具事件
table.on('colTool(test)', function(obj){
var col = obj.col; // 获取当前列属性配置项
var options = obj.config; // 获取当前表格基础属性配置项
var layEvent = obj.event; // 获得自定义元素对应的 lay-event 属性值
console.log(obj); // 查看对象所有成员
});
```
<h3 id="on-colResized" lay-pid="table.on" class="ws-anchor ws-bold">列拖拽宽度后的事件 <sup>2.8+</sup></h3>
`table.on('colResized(filter)', callback);`
在表头列分割线拖拽宽度后触发。
```js
var table = layui.table;
// 渲染
table.render({
elem: '#test',
// … // 其他属性
});
// 列拖拽宽度后的事件
table.on('colResized(test)', function(obj){
var col = obj.col; // 获取当前列属性配置项
var options = obj.config; // 获取当前表格基础属性配置项
console.log(obj); // 查看对象所有成员
});
```
<h3 id="on-colToggled" lay-pid="table.on" class="ws-anchor ws-bold">列筛选(显示或隐藏)后的事件 <sup>2.8+</sup></h3>
`table.on('colToggled(filter)', callback);`
点击头部工具栏右上角的字段筛选列表时触发。
```js
var table = layui.table;
// 渲染
table.render({
elem: '#test',
// … // 其他属性
});
// 列筛选(显示或隐藏)后的事件
table.on('colToggled(test)', function(obj){
var col = obj.col; // 获取当前列属性配置项
var options = obj.config; // 获取当前表格基础属性配置项
console.log(obj); // 查看对象所有成员
});
```
<h3 id="on-row" lay-pid="table.on" class="ws-anchor ws-bold">行单击和双击事件</h3>
- 行单击事件:`table.on('row(filter)', callback);`
- 行双击事件:`table.on('rowDouble(filter)', callback);`
单击或双击 table 行任意区域触发,两者用法相同。<br>
<sup>2.8.4+</sup>:在 table 模板中或任意内部元素中设置 `lay-unrow` 属性,可阻止该元素执行 `row` 事件
```js
var table = layui.table;
// 渲染
table.render({
elem: '#test',
// … // 其他属性
});
// 行单击事件
table.on('row(test)', function(obj){
var data = obj.data; // 得到当前行数据
var dataCache = obj.dataCache; // 得到当前行缓存数据,包含特定字段 --- 2.8.8+
var index = obj.index; // 得到当前行索引
var tr = obj.tr; // 得到当前行 <tr> 元素的 jQuery 对象
var options = obj.config; // 获取当前表格基础属性配置项
console.log(obj); // 查看对象所有成员
// obj.del() // 删除当前行
// obj.update(fields, related); // 修改行数据
// obj.setRowChecked(opts); // 设置行选中状态
});
```
<h3 id="on-rowContextmenu" lay-pid="table.on" class="ws-anchor ws-bold">行右键菜单事件 <sup>2.8+</sup></h3>
`table.on('rowContextmenu(filter)', callback);`
右键单击行时触发。
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', layout: ['code', 'preview'], tools: ['full'], toolsEvent: function(oi, type){
if(type === 'full'){
layui.table.resize('ID-table-onrowContextmenu');
}
}}">
<textarea>
{{- d.include("/table/examples/onrowContextmenu.md") }}
</textarea>
</pre>
<h3 id="on-edit" lay-pid="table.on" class="ws-anchor ws-bold">单元格编辑事件</h3>
`table.on('edit(filter)', callback);`
单元格被编辑,且值发生改变时触发。
```js
var table = layui.table;
var layer = layui.layer;
// 单元格编辑事件
table.on('edit(test)', function(obj){
var field = obj.field; // 得到修改的字段
var value = obj.value // 得到修改后的值
var oldValue = obj.oldValue // 得到修改前的值 -- v2.8.0 新增
var data = obj.data // 得到所在行所有键值
var col = obj.getCol(); // 得到当前列的表头配置属性 -- v2.8.0 新增
console.log(obj); // 查看对象所有成员
// 值的校验
if(value.replace(/\s/g, '') === ''){
layer.tips('值不能为空', this, {tips: 1});
return obj.reedit(); // 重新编辑 -- v2.8.0 新增
}
// 编辑后续操作,如提交更新请求,以完成真实的数据更新
// …
// 更新当前缓存数据
var update = {};
update[field] = value;
obj.update(update, true); // 参数 true 为 v2.7 新增功能,即同步更新其他包含自定义模板并可能存在关联的列视图
});
```
<h3 id="on-tool" lay-pid="table.on" class="ws-anchor ws-bold">单元格工具事件</h3>
- 单元格工具事件「单击触发」: `table.on('tool(filter)', callback);`
- 单元格工具事件「双击触发」: `table.on('toolDouble(filter)', callback);`
单击或双击单元格中带有 `lay-event=""` 属性的元素时触发。在表格主体的单元格中,经常需要进行很多的动态操作,比如编辑、删除等操作,这些均可以在单元格工具事件中完成。
{{!
```html
<!-- 表头某列 templet 属性指向的模板 -->
<script type="text/html" id="toolEventDemo">
<a class="layui-btn layui-btn-xs" lay-event="detail">查看</a>
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
<!-- 支持任意的 laytpl 组件语法 -->
{{# if(d.auth > 2){ }}
<a class="layui-btn layui-btn-xs" lay-event="check">审核</a>
{{# } }}
</script>
<table id="test" lay-filter="test"></table>
<!-- import layui -->
<script>
layui.use(function(){
var table = layui.table;
// 渲染
table.render({
elem: '#test',
cols: [[
{title: '操作', width: 200, templet: '#toolEventDemo'}
]]
// … // 其他属性
});
// 单元格工具事件
table.on('tool(test)', function(obj){
var data = obj.data; // 得到当前行数据
var dataCache = obj.dataCache; // 得到当前行缓存数据,包含特定字段 --- 2.8.8+
var index = obj.index; // 得到当前行索引
var layEvent = obj.event; // 获得元素对应的 lay-event 属性值
var tr = obj.tr; // 得到当前行 <tr> 元素的 jQuery 对象
var options = obj.config; // 获取当前表格基础属性配置项
var col = obj.getCol(); // 得到当前列的表头配置属性 -- v2.8.3 新增
console.log(obj); // 查看对象所有成员
// 根据 lay-event 的值执行不同操作
if(layEvent === 'detail'){ //查看
// do somehing
} else if(layEvent === 'del'){ //删除
layer.confirm('确定删除吗?', function(index){
obj.del(); // 删除对应行tr的 DOM 结构,并更新缓存
layer.close(index);
// 向后端发送删除请求,执行完毕后,可通过 reloadData 方法完成数据重载
/*
table.reloadData(id, {
scrollPos: 'fixed' // 保持滚动条位置不变 - v2.7.3 新增
});
*/
});
} else if(layEvent === 'edit'){ //编辑
// do something
// 同步更新缓存对应的值
// 该方法仅为前端层面的临时更新,在实际业务中需提交后端请求完成真实的数据更新。
obj.update({
username: '123',
title: 'abc'
});
// 若需更新其他包含自定义模板并可能存在关联的列视图,可在第二个参数传入 true
obj.update({
username: '123'
}, true); // 注:参数二传入 true 功能为 v2.7.4 新增
// 当发送后端请求成功后,可再通过 reloadData 方法完成数据重载
/*
table.reloadData(id, {
scrollPos: 'fixed' // 保持滚动条位置不变 - v2.7.3 新增
});
*/
}
});
});
</script>
```
!}}
<h3 id="on-checkbox" lay-pid="table.on" class="ws-anchor ws-bold">复选框事件</h3>
`table.on('checkbox(filter)', callback);`
当 table 开启复选框,且点击复选框时触发。
```js
var table = layui.table;
// 复选框事件
table.on('checkbox(test)', function(obj){
console.log(obj); // 查看对象所有成员
console.log(obj.checked); // 当前是否选中状态
console.log(obj.data); // 选中行的相关数据
console.log(obj.type); // 若触发的是全选则为all若触发的是单选则为one
});
```
<h3 id="on-radio" lay-pid="table.on" class="ws-anchor ws-bold">单选框事件</h3>
`table.on('radio(filter)', callback);`
当 table 开启单选框,且点击单选框时触发。
```js
var table = layui.table;
// 单选框事件
table.on('radio(test)', function(obj){
console.log(obj); // 当前行的一些常用操作集合
console.log(obj.checked); // 当前是否选中状态
console.log(obj.data); // 选中行的相关数据
});
```
<h3 id="on-pagebar" lay-pid="table.on" class="ws-anchor ws-bold">尾部分页栏事件 <sup>2.7+</sup></h3>
`table.on('pagebar(filter)', callback);`
点击尾部分页栏自定义模板中属性为 `lay-event=""` 的元素时触发。用法跟 toolbar 完全一致。
```js
var table = layui.table;
// 渲染
table.render({
elem: '#demo',
pagebar: '#pagebarDemo' // 分页栏模板所在的选择器
// … // 其他参数
});
// 分页栏事件
table.on('pagebar(test)', function(obj){
console.log(obj); // 查看对象所有成员
console.log(obj.config); // 当前实例的配置信息
console.log(obj.event); // 属性 lay-event 对应的值
});
```
## 小贴士
若表头数量太多及每页呈现的数据量太大,为了性能考虑,建议采用 [静态表格](#demo-static) 渲染,配合 [laypage](../laypage/#options) 组件实现分页。