描述:layui的table合并单元格,根据某一列的分组情况给其他列进行合并,特定列分组的单元为其他列最大的合并单元,不可超出。
前序要求:需要后台返回的数据根据要求分组排序后送到前端,js合并的核心是判断上下两个单元格内容是否相同,同时会依据特定合并单元格长度强制跳出合并。
- table渲染后回调:
table.render({// 数据表格生成
elem: '#demo',
height: "full-250",
url: xx,
page: {
layout: ['count', 'limit', 'prev', 'page', 'next', 'skip']
}, //开启分页
limit :1000,
limits :[1000,10000],
cols: [
[ //表头
/*{
field: 'id',
type: 'checkbox',
fixed: 'left',
align: 'center'
}, */{
field: 'orderNumber',
title: '序号',
width: 80,
align: 'center'
}, {
field: 'reagentName',
title: '试剂盒名称',
width: 385,
align: 'center'
}, {
field: 'chineseVulgo',
title: '中文俗称',
width: 430,
align: 'center'
}, {
field: 'component',
title: '组分',
width: 360,
align: 'center'
}, {
field: 'specifications',
title: '规格',
width: 95,
sort : true,
align: 'center'
}, {
field: 'componentShelf',
title: '组分货号',
width: 130,
sort : true,
align: 'center'
}, {
field: 'remarks',
title: '备注',
width: 300,
align: 'center'
}
],
],
done:function(res,curr,count) {
//回调执行合并单元格逻辑
merge(res)
},
- 执行合并
function merge(res) {
//初始化分割点
var indexPoint = [0];
var data = res.data;
var mergeIndex = 0;//定位需要添加合并属性的行数
var mark = 1; //这里涉及到简单的运算,mark是计算每次需要合并的格子数
//列名集合["orderNumber","reagentName","chineseVulgo","component","specifications","componentShelf","remarks"];
/**
* 执行第一列,已序号分组为准,产生分割点并保存
*/
var trArr = $(".layui-table-body>.layui-table").find("tr");//所有行
for (var i = 1; i < res.data.length; i++) { //这里循环表格当前的数据
var tdCurArr = trArr.eq(i).find("td").eq(0);//获取当前行的当前列
var tdPreArr = trArr.eq(mergeIndex).find("td").eq(0);//获取相同列的第一列
// console.log(k);
if (data[i].orderNumber === data[i - 1].orderNumber) { //后一行的值与前一行的值做比较,相同就需要合并
mark += 1;
//相同列的第一列增加rowspan属性
tdPreArr.each(function () {
$(this).attr("rowspan", mark);
});
//当前行隐藏
tdCurArr.each(function () {
$(this).css("display", "none");
});
}else {
//保存分割点
indexPoint.push(i)
mergeIndex = i;
mark = 1;//一旦前后两行的值不一样了,那么需要合并的格子数mark就需要重新计算
}
}
//补全最后一个分割点
indexPoint.push(res.data.length)
// console.log("合并索引点集合:",indexPoint)
//依据拿到的分割点,对其他6列进行合并处理
for(var i = 0;i<indexPoint.length;i++){
var startIndex=0;
if(i!=0){
startIndex = indexPoint[i-1];
}
for(var j=startIndex;j<indexPoint[i];j++){
//以第一列产生的区域分割点为基准,执行后面6列合并逻辑
mergeSomeRows(1,startIndex,indexPoint[i],trArr,data,'reagentName');
mergeSomeRows(2,startIndex,indexPoint[i],trArr,data,'chineseVulgo');
mergeSomeRows(3,startIndex,indexPoint[i],trArr,data,'component');
mergeSomeRows(4,startIndex,indexPoint[i],trArr,data,'specifications');
mergeSomeRows(5,startIndex,indexPoint[i],trArr,data,'componentShelf');
mergeSomeRows(6,startIndex,indexPoint[i],trArr,data,'remarks');
}
}
}
- 单行合并
/** * * @param colIndex:table中列索引 * @param startIndex:合并单元格起始索引 * @param endIndex:合并单元格结束索引 * @param trArr:单列单元格元素集合 * @param data:后端返回数据集合 * @param colName:当前列字段名 */ function mergeSomeRows(colIndex,startIndex,endIndex,trArr,data,colName){ var mark = 1; for(var j=startIndex+1;j<endIndex;j++){ ++mark; var tdCurArr = trArr.eq(j).find("td").eq(colIndex);//获取当前行的当前列 var tdPreArr = trArr.eq(startIndex).find("td").eq(colIndex);//获取相同列的第一列 if (data[j][colName] === data[j - 1][colName]) { //后一行的值与前一行的值做比较,相同就需要合并 //相同列的第一列增加rowspan属性 tdPreArr.each(function () { $(this).attr("rowspan", mark); }); //当前行隐藏 tdCurArr.each(function () { $(this).css("display", "none"); }); }else { mark=1; startIndex=j; } } }