Browse Source

refactor(table): 重构 table.setRowChecked() 方法 (#2146)

* refactor(table): 重构 table.setRowChecked() 方法

* feat: 进一步优化 `table.setRowChecked()`
fix: 修复单选时未移除其他行数据选中状态的问题

* refactor: 剔除多余判断

* docs: 优化 checked 选项说明
pull/2171/head
贤心 3 months ago committed by GitHub
parent
commit
4545ec151a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      docs/table/index.md
  2. 2
      examples/table-test.html
  3. 79
      src/modules/table.js

4
docs/table/index.md

@ -381,8 +381,8 @@ console.log(tableStatus.isAll ) // 表格是否全选
| opts | 描述 | 类型 | 默认值 | | opts | 描述 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| type | 选中方式。可选值: `checkbox,radio` | string | `checkbox` | | type | 选中方式。可选值: `checkbox,radio` | string | `checkbox` |
| index | 选中行的下标。支持以下几种情况:<ul><li>若值为 `number` 类型,则表示行所在的数组下标(`0` 开头)</li><li>若值为 `array` 类型 <sup>2.9.1+</sup>,则表示批量下标。</li><li>若值为 `string` 类型,则可设置 `all` 操作全选。</li></ul> | number<br>array<br>string | - | | index | 选中行的下标。支持以下几种情况:<ul><li>若值为 `number` 类型,则表示行所在的数组下标(`0` 开头)</li><li>若值为 `array` 类型 <sup>2.9.1+</sup>,则表示多选下标。</li><li>若值为 `string` 类型,则可设置 `all` 操作全选。</li></ul> | number<br>array<br>string | - |
| checked | 选中状态值。 <ul><li>若传递该属性,则赋值固定值。</li><li>若不传递该属性(默认),则 `checkbox` 将在 `true\|false` 中自动切换值,而 `radio` 将赋值 `true` 固定值。<sup>2.8.4+</sup></li></ul> | boolean | - | | checked | 选中状态值。 <ul><li>若传递该属性,则赋值固定值。</li><li>若不传递该属性(默认),则 `checkbox` 将在 `true\|false` 中自动切换值,而 `radio` 将赋值 `true` 固定值。<sup>2.8.4+</sup><br>**注意**:若 `index` 指定为多选或全选,`checked` 应当显式传递固定值</li></ul> | boolean | - |
该方法用于设置行的选中样式及相关的特定属性值 `LAY_CHECKED` 该方法用于设置行的选中样式及相关的特定属性值 `LAY_CHECKED`

2
examples/table-test.html

@ -84,7 +84,7 @@
(function(off){ (function(off){
if(!off) return; if(!off) return;
layui.disuse('table').extend({ layui.disuse('table').extend({
table: '{/}https://cdn.staticfile.net/layui/2.7.6/layui.js' table: '{/}https://cdn.jsdelivr.net/gh/layui/layui@2.7.6/src/modules/table'
}); });
})(); })();

79
src/modules/table.js

@ -1722,10 +1722,12 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
var options = that.config; var options = that.config;
var isCheckAll = opts.index === 'all'; // 是否操作全部 var isCheckAll = opts.index === 'all'; // 是否操作全部
var isCheckMult = layui.type(opts.index) === 'array'; // 是否操作多个 var isCheckMult = layui.type(opts.index) === 'array'; // 是否操作多个
var needDisableTransition= isCheckAll || isCheckMult; // 减少回流 var isCheckAllOrMult = isCheckAll || isCheckMult; // 是否全选或多选
if(needDisableTransition){ // 全选或多选时
that.layBox.addClass(DISABLED_TRANSITION); if (isCheckAllOrMult) {
that.layBox.addClass(DISABLED_TRANSITION); // 减少回流
if (opts.type === 'radio') return; // radio 不允许全选或多选
} }
if(isCheckMult){ if(isCheckMult){
@ -1737,13 +1739,14 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
} }
// 匹配行元素 // 匹配行元素
var selector = (isCheckAll || isCheckMult) ? 'tr' : 'tr[data-index="'+ opts.index +'"]'; var tbody = that.layBody.children('.layui-table').children('tbody');
var selector = isCheckAllOrMult ? 'tr' : 'tr[data-index="'+ opts.index +'"]';
var tr = function(tr) { var tr = function(tr) {
return isCheckAll ? tr : tr.filter(isCheckMult ? function() { return isCheckAll ? tr : tr.filter(isCheckMult ? function() {
var dataIndex = $(this).data('index'); var dataIndex = $(this).data('index');
return opts.index[dataIndex]; return opts.index[dataIndex];
} : '[data-index="'+ opts.index +'"]'); } : '[data-index="'+ opts.index +'"]');
}(that.layBody.find(selector)); }(tbody.children(selector));
// 默认属性 // 默认属性
opts = $.extend({ opts = $.extend({
@ -1759,61 +1762,46 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
return opts.type === 'radio' ? true : (existChecked ? opts.checked : !value) return opts.type === 'radio' ? true : (existChecked ? opts.checked : !value)
}; };
var ignoreTrIndex = {}; var radioCheckedIndex;
// 设置选中状态
layui.each(thisData, function(i, item){ // 给匹配行设置选中状态
tr.each(function() {
var el = $(this);
var i = el.attr('data-index');
var item = thisData[i];
if (!i) return; // 此时 el 通常为静态表格嵌套时的原始模板
// 绕过空项和禁用项 // 绕过空项和禁用项
if(layui.type(item) === 'array' || item[options.disabledName]){ if (layui.type(item) === 'array' || item[options.disabledName]) {
ignoreTrIndex[i] = true;
return; return;
} }
// 匹配条件
var matched = isCheckAll || (
isCheckMult ? opts.index[i] : Number(opts.index) === i
);
// 设置匹配项的选中值
if(matched){
// 标记数据选中状态 // 标记数据选中状态
var checked = item[options.checkName] = getChecked(item[options.checkName]); var checked = item[options.checkName] = getChecked(el.hasClass(ELEM_CHECKED));
// 标记当前行背景色 // 标记当前行背景色
// 此处只更新 radio 和 单个 checkbox el.toggleClass(ELEM_CHECKED, !!checked);
if(!isCheckAll && !isCheckMult){
var currTr = tr.filter('[data-index="'+ i +'"]');
currTr[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED);
// 若为 radio 类型,则取消其他行选中背景色 // 若为 radio 类型,则取消其他行选中背景色
if(opts.type === 'radio'){ if (opts.type === 'radio') {
currTr.siblings().removeClass(ELEM_CHECKED); radioCheckedIndex = i;
} el.siblings().removeClass(ELEM_CHECKED);
}
} else if(opts.type === 'radio') {
delete item[options.checkName];
} }
}); });
if(isCheckAll){ // 若为 radio 类型,移除其他行数据选中状态
tr.each(function(i){ if (radioCheckedIndex) {
var index = this.getAttribute('data-index'); layui.each(thisData, function(i, item) {
if(!ignoreTrIndex[index]){ if (Number(radioCheckedIndex) !== Number(i)) {
var el = $(this); delete item[options.checkName];
el.toggleClass(ELEM_CHECKED, !!getChecked(thisData[index][options.checkName]))
}
});
}else if(isCheckMult){
tr.each(function(i){
var index = this.getAttribute('data-index');
if(opts.index[index] && !ignoreTrIndex[index]){
var el = $(this);
el.toggleClass(ELEM_CHECKED, !!getChecked(thisData[index][options.checkName]))
} }
}); });
} }
// 若存在复选框或单选框,则标注选中状态样式 // 若存在复选框或单选框,则标注选中状态样式
var checkedElem = tr.find('input[lay-type="'+ ({ var td = tr.children('td').children('.layui-table-cell');
var checkedElem = td.children('input[lay-type="'+ ({
radio: 'layTableRadio', radio: 'layTableRadio',
checkbox: 'layTableCheckbox' checkbox: 'layTableCheckbox'
}[opts.type] || 'checkbox') +'"]:not(:disabled)'); }[opts.type] || 'checkbox') +'"]:not(:disabled)');
@ -1826,7 +1814,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
that.syncCheckAll(); that.syncCheckAll();
if(needDisableTransition){ if(isCheckAllOrMult){
setTimeout(function(){ setTimeout(function(){
that.layBox.removeClass(DISABLED_TRANSITION); that.layBox.removeClass(DISABLED_TRANSITION);
},100) },100)
@ -2438,9 +2426,10 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
index: index, index: index,
checked: checked checked: checked
}); });
layui.stope(e);
} }
layui.stope(e);
// 事件 // 事件
layui.event.call( layui.event.call(
checkbox[0], checkbox[0],

Loading…
Cancel
Save