关于BootStrapTable对复选框checkbox借助JQuery动态选中指定行记录的方法探究
业务需求
从数据库中读出指定用户的角色,并可在前端分配角色表中进行查看该用户已有的角色。
例:A用户是超级管理员,则在前端分配角色表中 A用户 超级管理员角色 已被选中。
效果如图:
1 实现逻辑
1.1 数据库前置条件
- 所有角色位于一张角色表
- 用户所拥有的角色位于一张用户角色表
角色POJO类:
1.2 具体思路
- 从数据库读出所有角色,返回一个全角色列表 A
- 从数据库读出指定用户已拥有的角色,返回一个部分角色列表B
- 前端Table元素先渲染 全角色列表A,再根据指定的角色列表B中行记录 位于全角色列表A的位置(Index)来 对相应的角色记录进行选中,最后重新渲染 前端的Table元素
2 测试用例使用的BootStrapTable的初始化结构
.html文件(前端页面的table演示元素)
//前端HTML页面测试用的表格元素id为allotRoleTable
<table id="allotRoleTable" class="table table-striped"></table>
.js文件(初始化BootStrapTable)
$("#allotRoleTable").bootstrapTable({
pagination: true,
sortName: "roleName",
sortOrder: "asc",
//注意使用的客户端分页方式
sidePagination: "client",
pageSize: 5,
dataType: "json",
undefinedText: "*",
columns: [{
field: 'checked',
checkbox: true
},{
field: "roleName",
title: "角色名"
}, {
field: "comments",
title: "备注"
},{
field: "crtime",
title: "创建时间"
}],
});
注意在js文件中对BootStrapTable初始化时为 所有行记录的复选框 设置了其相应的field名称为:“checked”,便于后期动态修改时进行引用。
3 使用的BootStrapTable主要方法
3.1 对BootStrapTable进行加载数据的方法(客户端分页方式)
//配合客户端分页方式加载数据,使用BootStrapTable加载数据的接口方法“load”, roleList为Ajax向服务器请求后返回的数据(此处详情未做展示)。
$("#allotRoleTable").bootstrapTable("load", roleList);
3.2 获取BootStrapTable记录(行记录)
原表格数据:
//获取行记录, 使用BootStrapTable的接口方法: “getData”
let rowData = $("#allotRoleTable").bootstrapTable("getData");
console.log("当前所有数据", rowData);
在浏览器控制台对getData方法的输出展示(可以看出是JS对象数组,其中含两个元素,1个元素为1条行记录)
3.3 对BootStrapTable指定行记录(相应Index) 单列属性的修改以实现动态选中复选框(对复选框列“checked”的修改)
配合初始化BootStrapTable表时,所有行记录复选框列的field域命名为“checked” (详见2中BootStrapTable的初始化)
{
field: 'checked',
checkbox: true
},
具体修改代码:
let rowData = $("#allotRoleTable").bootstrapTable("getData");
//对指定Index的行记录的checked域进行修改,“checked”为true 则 复选框被选中
rowData[currentIndex].checked = true;
4 具体实现代码
4.1 借助JQuery的$.ajax()获得: (此处代码省略)
- 全角色列表A:roleList
- 指定用户角色列表B:allotted
4.2 根据roleList先让前端Table元素渲染全部角色列表:
function loadAllotRoleTable(roleList) {
$("#allotRoleTable").bootstrapTable("destroy");
$("#allotRoleTable").bootstrapTable({
pagination: true,
sortName: "roleName",
sortOrder: "asc",
//注意使用的客户端分页方式
sidePagination: "client",
pageSize: 5,
dataType: "json",
undefinedText: "*",
columns: [{
field: 'checked',
checkbox: true
},{
field: "roleName",
title: "角色名"
}, {
field: "comments",
title: "备注"
},{
field: "crtime",
title: "创建时间"
}],
});
$("#allotRoleTable").bootstrapTable("load", roleList);
}
4.3 借助角色类的属性uuid(非整个角色类比较)进行比较 获取Index(可以通过其他方式获取Index,不唯一)
即:为指定用户的部分角色列表中的每一个角色的uuid,和全角色类别中的uuid进行比较,相同则返回当前的位置索引 Index (借助自定义生成的辅助全列表uuid数组的元素顺序 和 先前前端Table元素渲染的全角色列表的顺序一致的特点)
原理如图:
具体代码:
// 根据数据库查询当前用户的已有角色动态选中复选框
function loadAllottedRole(allotted, roleList) {
//将两个列表的uuid生成两个辅助数组便于比较
let allottedRoleUuid = [];
let roleListUuid = [];
let rowData = $("#allotRoleTable").bootstrapTable("getData");
for(let index in allotted){
allottedRoleUuid.push(allotted[index].uuid);
}
for(let index2 in roleList){
roleListUuid.push(roleList[index2].uuid);
}
for(let i=0; i<allotted.length; i++){
let currentIndex = roleListUuid.indexOf(allottedRoleUuid[i]);
if(currentIndex > -1){
// 对当前行记录的"checked"属性进行动态选中,结合前期column对每行记录的复选框的field设置为"checked"
rowData[currentIndex].checked = true;
}
}
// 动态选中复选框后重新载入新的数据
$("#allotRoleTable").bootstrapTable("load",rowData);
}
4.4 最终结果
前端展示效果:
控制台具体HTML代码:
5 注意事项(坑向)
5.1 不推荐借助相应的选择器动态选中复选框(建议根据表初始化时 行记录中的checkbox域属性值进行修改,即 3.3所示)
BootStrapTable 自动生成的复选框的选择,可以借助相应的选择器动态选中复选框,但是在使用BootStrapTable的“getSelections”方法时,会导致页面当前选中的记录行不在“getSelections”方法的返回值中
使用JQuery选择器选中标签后,对“checked”属性进行动态设置
let target = $("#allotRoleTable tbody td input")[currentIndex];
$(target).attr("checked",true);
但是使用getSelections方法后其返回值为空,当前选中的记录按照BootStrapTable的getSelections方法逻辑 未被获取
5.2 测试代码
let currentRows = $("#allotRoleTable").bootstrapTable('getSelections');
console.log("获取选中数据", currentRows);
5.3 测试结果
可以看出虽然借助选择器将复选框选中,但是调用getSelections方法后,该记录按照BootstrapTable复选框被选中的逻辑,该行记录实际并未被选中。