Jquery Datatables如何修改代码支持Shift/Ctrl多选HTML预定义复选框
问题背景
你已经基于jQuery Datatables实现了表格复选框的单选、全选、行高亮功能,现在需要新增快捷键多选能力:
- 按住Shift选中连续多条记录
- 按住Ctrl可追加选中不连续记录
- 不允许使用JS动态生成复选框,必须保留HTML预定义的复选框结构
你参考的Shift批量选中代码仅能修改复选框状态,无法同步行高亮和选中ID数组,下面是具体修改方案:
修改步骤
1. HTML部分调整
给所有预定义的复选框添加统一的data属性标记,方便选择器匹配:
<!-- 表头全选复选框 --> <th><input name="select_all" value="1" type="checkbox" autocomplete="off" data-chkbox-shiftsel="dt-group"></th> <!-- 每行的复选框 --> <td><input type="checkbox" name="deleteProduct" autocomplete="off" data-chkbox-shiftsel="dt-group"></td>
2. JS部分调整
2.1 变量声明调整
将选中ID数组、上一次点击记录变量提升到同一作用域,避免作用域隔离无法访问:
$(document).ready(function (){ var rows_selected = []; // 移到最外层,替换原来内部声明的同名变量 var lastChecked = null; // 新增变量,记录上一次点击的复选框元素 // 原有updateDataTableSelectAllCtrl函数完全保留不变 function updateDataTableSelectAllCtrl(table){ // 原有逻辑不需要修改 } // 原有Datatables初始化逻辑保留,仅调整rowCallback的数组引用 var table = $('#example').DataTable({ // 原有响应式、列重排、固定头等配置完全保留 'rowCallback': function(row, data, dataIndex){ var rowId = data[6]; // 去掉原来的注释,直接引用外部的rows_selected数组 if($.inArray(rowId, rows_selected) !== -1){ $(row).find('input[type="checkbox"]').prop('checked', true); $(row).addClass('selected'); } } });
2.2 重写复选框点击事件逻辑
替换原有的复选框点击事件,新增快捷键判断和批量同步逻辑:
// 替换原有$('#example tbody').on('click', 'input[type="checkbox"]' 事件代码 $('#example tbody').on('click', 'input[type="checkbox"]', function(e){ var $currentChk = $(this); var $currentRow = $currentChk.closest('tr'); var currentData = table.row($currentRow).data(); var currentRowId = currentData[6]; var currentChecked = $currentChk.prop('checked'); // Ctrl键逻辑:仅切换当前行状态,保留原有选中项 if(!e.shiftKey && e.ctrlKey){ var index = $.inArray(currentRowId, rows_selected); if(currentChecked && index === -1){ rows_selected.push(currentRowId); $currentRow.addClass('selected'); }else if(!currentChecked && index !== -1){ rows_selected.splice(index, 1); $currentRow.removeClass('selected'); } } // Shift键逻辑:选中两次点击之间的所有行 else if(e.shiftKey && lastChecked){ var $allChk = $('#example tbody input[type="checkbox"]'); var start = $allChk.index(this); var end = $allChk.index(lastChecked); var targetState = $(lastChecked).prop('checked'); // 遍历中间所有复选框,同步状态、高亮、选中数组 $allChk.slice(Math.min(start,end), Math.max(start,end)+ 1).each(function(){ var $chk = $(this); var $row = $chk.closest('tr'); var rowId = table.row($row).data()[6]; var idx = $.inArray(rowId, rows_selected); $chk.prop('checked', targetState); if(targetState && idx === -1){ rows_selected.push(rowId); $row.addClass('selected'); }else if(!targetState && idx !== -1){ rows_selected.splice(idx, 1); $row.removeClass('selected'); } }); } // 无快捷键逻辑:清除原有选中,仅保留当前点击项 else{ rows_selected = []; $('#example tbody tr').removeClass('selected'); $('#example tbody input[type="checkbox"]').prop('checked', false); if(currentChecked){ rows_selected.push(currentRowId); $currentRow.addClass('selected'); $currentChk.prop('checked', true); } } // 记录本次点击的复选框作为下次Shift选中的锚点 lastChecked = this; // 更新全选按钮状态 updateDataTableSelectAllCtrl(table); e.stopPropagation(); });
3. 兼容说明
- 原有全选、表单提交、表格展开折叠逻辑完全保留,不需要修改
- 不需要引入Datatables Select扩展,所有复选框都是原有HTML预定义结构
- 表格分页、排序后功能依然生效,连续区间判断基于当前页的DOM元素索引
内容的提问来源于stack exchange,提问作者cindyhows
相关产品推荐
相关产品推荐

