必须用templet自定义checkbox列,保留name="layTableCheckbox",显式控制disabled和LAY_CHECKED,手动过滤table.checkStatus()结果并拦截禁用项事件。

必须用 templet 自定义 checkbox 列,不能用 {type: 'checkbox'}
内置 {type: 'checkbox'} 列不支持按行禁用,写 disabled: true 在数据里完全无效。Layui 渲染时会忽略该字段,复选框照常响应点击。唯一可靠方式是删掉原 checkbox 列,改用普通列 + templet 手动生成 <input type="checkbox">,并在模板中动态插入 disabled 属性。
关键点有三个:
- name="layTableCheckbox" 必须保留,这是 Layui 内部识别多选行的硬性约定,漏掉就无法被 table.checkStatus() 识别
- disabled 和 checked 都要显式控制,不能只靠 d.layChecked 字段——它不会自动映射到 DOM 的 checked 状态
- 禁用逻辑必须基于当前行数据 d(如 d.status === 'closed'),不能依赖外部变量或异步状态
示例模板:
<script type="text/html" id="checkboxTpl">
<input type="checkbox" name="layTableCheckbox"
{{# if(d.status === 'closed'){ }} disabled {{# } }}
{{# if(d.LAY_CHECKED){ }} checked {{# } }}
lay-id="{{d.id}}">
</script>
table.checkStatus() 仍返回禁用行,必须手动过滤
Layui 不管 disabled,只看 DOM 元素是否存在。table.checkStatus('demo').data 会把所有行(包括 disabled 的)全塞进来。哪怕 checkbox 灰了、点了没反应,结果里照样包含它们。
真实可用的已勾选数据得自己筛:
const cache = table.cache['demo']; const validChecked = cache.filter(d => d.status !== 'closed' && d.LAY_CHECKED);
注意字段名是 LAy_CHECKED(全大写),不是 layChecked 或 checked。
全选判断也不能看 res.count,得比对:
validChecked.length === cache.filter(d => d.status !== 'closed').length
点击操作按钮时防止行被意外选中
操作列按钮(比如 lay-event="edit")点下去,行却自动勾上了——这是事件冒泡导致的,默认行为没被拦住。
在 table.on('tool(filter)') 回调里第一行加 layui.stope(event):
table.on('tool(test)', function(obj){
const event = obj.event;
layui.stope(event); // ✅ 必须放第一行
if(event === 'edit'){
console.log(obj.data);
}
});event 必须从 obj.event 拿,传错参数 stope 就失效。别写 onclick="return false",Layui 事件是委托绑定的,内联写法压根不生效。
监听 checkbox 事件时必须拦截禁用项
光加 disabled 属性不够。用户点击全选框后,禁用行的 checkbox 状态不会变,但 table.on('checkbox(test)') 仍可能触发(取决于是否真渲染了 input)。
稳妥做法是在事件回调开头加判断:
table.on('checkbox(test)', function(obj){
if(obj.disabled) return;
// 后续逻辑
});否则后续处理会把禁用行当成有效选中项参与计算,导出、批量操作都可能出错。
禁用只是 UI 层遮蔽,Layui 状态管理完全 unaware——这是最易被忽略的一点:它的内部状态(包括 LAy_CHECKED 字段、全选逻辑、父子联动)都不感知 disabled。你写的 disabled 对它来说就像不存在。


















