w2ui Grid 中实现按条件禁用特定行的多选功能

5次阅读

w2ui Grid 中实现按条件禁用特定行的多选功能

本文详解如何在 w2ui grid 启用 multiselect 的前提下,动态控制某些行不可被选中(如基于业务规则或数据状态),通过拦截 `onselect` 事件并调用 `Event.preventdefault()` 实现精细化选择控制。

在使用 w2ui Grid 构建数据表格时,multiSelect: true 可启用多行复选框选择,但默认不提供“按行粒度禁用选择”的内置配置。若需实现「仅允许部分记录可被选中」(例如:灰显/禁用某些只读、已锁定或权限不足的行),必须借助事件拦截机制——核心在于捕获用户点击选择动作,并根据当前行数据决定是否阻止默认行为。

✅ 正确实现方式:利用 onSelect 事件 + event.preventDefault()

w2ui 提供了 onSelect 回调,该事件在用户点击复选框(或按 Ctrl/Cmd + 点击行)时触发,且在实际选中逻辑执行前。此时可通过 event.recid 获取目标行 ID,并结合 grid.records 或自定义元数据判断该行是否应被禁止选择:

let grid = new w2grid({     name: 'grid',     box: '#grid',     multiSelect: true,     show: {         selectColumn: true     },     columns: [         { field: 'recid', text: 'ID', size: '10px', sortable: true, attr: 'align="center"' },         { field: 'field', text: '内容', size: '500px', sortable: true }     ],     records: [         { recid: 1, field: 'You cannot select this', selectable: false },         { recid: 2, field: 'neither this', selectable: false },         { recid: 3, field: 'but you can select this', selectable: true },         { recid: 4, field: 'or this', selectable: true },         { recid: 5, field: 'and what do you think about this?', selectable: true },         { recid: 6, field: 'Ok no, not this one', selectable: false },         { recid: 7, field: 'as even this must be disabled', selectable: false }     ],     // 关键:监听 onSelect 并动态拦截     onSelect(event) {         const record = this.get(event.recid);         // 若 record.selectable === false,则阻止选择         if (record && record.selectable === false) {             event.preventDefault();         }     } });

? 提示:建议在 records 数据中显式添加 selectable: Boolean 字段(或其他语义化字段如 locked, disabled),便于统一判断,避免硬编码 recid 列表,提升可维护性。

⚠️ 注意事项与最佳实践

  • event.preventDefault() 是唯一可靠方式:不要尝试在 onClick 或 onDblClick 中处理,它们无法阻止复选框状态变更;onSelect 是专为选择控制设计的钩子。
  • 兼容全选操作(Select All):当用户点击表头复选框时,onSelect 会为每一行单独触发。上述逻辑会自动对每条不满足条件的记录生效,无需额外处理。
  • 视觉反馈建议:w2ui 不自动禁用复选框 UI,因此推荐配合 CSS 隐藏或禁用对应行的 checkbox
    .w2ui-grid .w2ui-row[aria-disabled="true"] .w2ui-checkbox {     opacity: 0.4;     pointer-events: none; }

    并在 onRender 中动态设置属性(需结合 this.refresh() 或 this.reload() 触发):

    onRender(event) {     this.rows.forEach(row => {         const record = this.get(row.recid);         if (record && record.selectable === false) {             $(this.box).find(`.w2ui-row[data-recid="${row.recid}"]`).attr('aria-disabled', 'true');         }     }); }
  • 性能考量:onSelect 属于高频事件,确保内部判断逻辑轻量(如避免同步 ajax 或复杂遍历),推荐使用预置字段直接判断。

✅ 总结

通过合理利用 onSelect 事件与 event.preventDefault(),你可以在 w2ui Grid 中精准实现「条件化行级选择控制」,既保留多选能力,又满足业务层对数据操作的约束要求。关键在于将选择权限逻辑前置到事件拦截阶段,并辅以清晰的数据标记和可选的 UI 呼应,从而构建出专业、可控的表格交互体验。

text=ZqhQzanResources