layui表格合并

先看一下最终合并之后的效果,能对单选、复选框进行按照某一列的合并

在这里插入图片描述
最开始的解决方案来自于这篇博客介绍的方法:https://blog.csdn.net/guishifoxin/article/details/81480136
但是还是存在没能解决的问题。
在完善之后达到的效果:

一:单选、复选
原来加入开启了单选或者多选之后会将全部的单选按钮都合并了。
在这里插入图片描述
也传入合并列名field,layui默认是0。
在这里插入图片描述
其实这个时候就需要结合业务去控制了,需要知道是根据哪一个字段将整个表格分为几个单选的行,使用之前的代码会将全部的单选按钮合并。
改造之后效果:

1、按照不同的字段进行合并


在这里插入图片描述
在这里插入图片描述

2、checkbox也能合并


在这里插入图片描述
二、多表格混乱或不显示
layui的每一个表格都会有一个index作为标识,并且是01234…这样的顺序。所以在使用的时候指定需要进行行合并的表格序号。
在这里插入图片描述

全部代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>表格合并行工具</title>
<script type="text/javascript" src="你的layui等静态文件地址"></script>
	<script>
	var teatTable1Data = [
		{"location":"西南","cityName":"昆明","province":"云南","area":"100平方千米","prople":"300万"},
        {"location":"西南","cityName":"曲靖","province":"云南","area":"100平方千米","prople":"700万"},
        {"location":"西南","cityName":"玉溪","province":"云南","area":"100平方千米","prople":"600万"},
        {"location":"西南","cityName":"成都","province":"四川","area":"100平方千米","prople":"400万"},
        {"location":"西南","cityName":"宜宾","province":"四川","area":"100平方千米","prople":"400万"},
        {"location":"西北","cityName":"银川","province":"宁夏","area":"100平方千米","prople":"500万"},
        {"location":"西北","cityName":"乌鲁木齐","province":"新疆","area":"100平方千米","prople":"600万"},
        {"location":"西北","cityName":"喀什","province":"新疆","area":"100平方千米","prople":"600万"},
        {"location":"西北","cityName":"西宁","province":"青海","area":"100平方千米","prople":"500万"},
        {"location":"西北","cityName":"兰州","province":"甘肃","area":"100平方千米","prople":"400万"},
        {"location":"西北","cityName":"酒泉","province":"甘肃","area":"100平方千米","prople":"300万"},
	];
    var teatTable2Data = [
        {"location2":"亚洲","cityName22":"北京","province2":"中国","area2":"100平方千米","prople2":"300万"},
        {"location2":"亚洲","cityName2":"孟买","province2":"印度","area2":"100平方千米","prople2":"700万"},
        {"location2":"亚洲","cityName2":"东京","province2":"日本","area2":"100平方千米","prople2":"600万"},
        {"location2":"欧洲","cityName2":"巴黎","province2":"法国","area2":"100平方千米","prople2":"400万"},
        {"location2":"欧洲","cityName2":"伦敦","province2":"英国","area2":"100平方千米","prople2":"400万"},
        {"location2":"欧洲","cityName2":"伦敦2","province2":"英国","area2":"100平方千米","prople2":"500万"},
        {"location2":"欧洲","cityName2":"柏林","province2":"德国","area2":"100平方千米","prople2":"600万"},
        {"location2":"美洲","cityName2":"纽约","province2":"美国","area2":"100平方千米","prople2":"600万"},
        {"location2":"美洲","cityName2":"纽约2","province2":"美国","area2":"100平方千米","prople2":"500万"},
        {"location2":"美洲","cityName2":"华盛顿","province2":"美国","area2":"100平方千米","prople2":"400万"},
        {"location2":"美洲","cityName2":"多伦多","province2":"加拿大","area2":"100平方千米","prople2":"300万"},
    ];
    var teatTable3Data = [
        {"location3":"银河系","cityName3":"地球","province3":"太阳系","area3":"100平方千米","prople3":"300万"},
        {"location3":"银河系","cityName3":"月球","province3":"太阳系","area3":"100平方千米","prople3":"700万"},
        {"location3":"银河系","cityName3":"土星","province3":"太阳系","area3":"100平方千米","prople3":"600万"},
        {"location3":"银河系","cityName3":"水星","province3":"太阳系","area3":"100平方千米","prople3":"400万"},
        {"location3":"银河系","cityName3":"金星","province3":"太阳系","area3":"100平方千米","prople3":"400万"},
        {"location3":"银河系","cityName3":"旅行者1号","province3":"太阳系","area3":"100平方千米","prople3":"500万"},
        {"location3":"银河系","cityName3":"旅行者2号","province3":"太阳系","area3":"100平方千米","prople3":"600万"},
        {"location3":"银河系","cityName3":"天王星","province3":"太阳系","area3":"100平方千米","prople3":"600万"},
        {"location3":"三体星系","cityName3":"三体星1","province3":"半人马座三星","area3":"100平方千米","prople3":"500万"},
        {"location3":"三体星系","cityName3":"三体星2","province3":"半人马座三星","area3":"100平方千米","prople3":"400万"},
        {"location3":"三体星系","cityName3":"三体星2","province3":"半人马座三星","area3":"100平方千米","prople3":"300万"},
    ];

    layui.use('table', function(){
        var table = layui.table;
        table.render({
            data:teatTable1Data,
            title: '测试表格1',
            elem: '#test-table1',
            defaultToolbar: false,
            page: false,
            cols: [[
                {type: 'radio', align: 'center'},
                {field: 'location', title: '位置区域', align: 'center'},
                {field: 'province', title: '省份', align: 'center'},
                {field: 'area', title: '面积', align: 'center'},
                {field: 'cityName', title: '城市', align: 'center'},
                {field: 'prople', title: '人口数量', align: 'center'}
            ]],
            done:function () {
                /**
                 * 参数1  需要合并列的数组,0代表的是合并单选按钮或者是复选框 radio/checkbox 后端需要将这些字段进行排序
                 * 参数2  当前表格的index (用于在一个页面中有使用了多个表格的情况,如果只有一个表格填0就行
                 * 		  index这个值是表格加载的顺序,从0开始,如果页面上表格很多建议debug用 $(".layui-table-body")[index]看一下就拿到了)
                 * 参数3  是按照html元素合并,还是按照标签中的text内容合并,建议填true
                 * 参数4  radio/checkbox根据哪一行去合并
                 */
                layuiRowspan(['0','location', 'province', 'prople'],"0",true,"location");
            }
        });

        table.render({
            data:teatTable2Data,
            title: '测试表格2',
            elem: '#test-table2',
            defaultToolbar: false,
            page: false,
            cols: [[
                {type: 'checkbox', align: 'center'},
                {field: 'location2', title: '位置区域', align: 'center'},
                {field: 'province2', title: '省份', align: 'center'},
                {field: 'area2', title: '面积', align: 'center'},
                {field: 'cityName2', title: '城市', align: 'center'},
                {field: 'prople2', title: '人口数量', align: 'center'}
            ]],
            done:function () {
                /**
                 * 参数1  需要合并列的数组,0代表的是合并单选按钮或者是复选框 radio/checkbox 后端需要将这些字段进行排序
                 * 参数2  当前表格的index (用于在一个页面中有使用了多个表格的情况,如果只有一个表格填0就行
                 * 		  index这个值是表格加载的顺序,从0开始,如果页面上表格很多建议debug用 $(".layui-table-body")[index]看一下就拿到了)
                 * 参数3  是按照html元素合并,还是按照标签中的text内容合并,建议填true
                 * 参数4  radio/checkbox根据哪一行去合并
                 */
                layuiRowspan(['0','location2', 'province2', 'prople2'],"1",true,"location2");
            }
        });

        table.render({
            data:teatTable3Data,
            title: '测试表格3',
            elem: '#test-table3',
            defaultToolbar: false,
            page: false,
            cols: [[
                {type: 'radio', align: 'center'},
                {field: 'location3', title: '位置区域', align: 'center'},
                {field: 'province3', title: '省份', align: 'center'},
                {field: 'area3', title: '面积', align: 'center'},
                {field: 'cityName3', title: '城市', align: 'center'},
                {field: 'prople3', title: '人口数量', align: 'center'}
            ]],
            done:function(){
                /**
                 * 参数1  需要合并列的数组,0代表的是合并单选按钮或者是复选框 radio/checkbox 后端需要将这些字段进行排序
                 * 参数2  当前表格的index (用于在一个页面中有使用了多个表格的情况,如果只有一个表格填0就行
				 * 		  index这个值是表格加载的顺序,从0开始,如果页面上表格很多建议debug用 $(".layui-table-body")[index]看一下就拿到了)
                 * 参数3  是按照html元素合并,还是按照标签中的text内容合并,建议填true
                 * 参数4  radio/checkbox根据哪一行去合并
                 */
                layuiRowspan(['0','location3', 'province3', 'prople3'],"2",true,"location3");
            }
        });
    });


    //行合并 start
    function execRadioRows(childFilterArr,ckChildFilterArr,flag){
        //获取td的个数和种类
        var chChildFilterTextObj = {};
        var chText = [];
        var chIndex = [];

        for(var i = 0; i < ckChildFilterArr.length; i++){
            var chChildText = flag?ckChildFilterArr[i].innerHTML:ckChildFilterArr[i].textContent;
            if(chChildFilterTextObj[chChildText] == undefined){
                chChildFilterTextObj[chChildText] = 1;
                chText.push(chChildText);
            }else{
                var num = chChildFilterTextObj[chChildText];
                chChildFilterTextObj[chChildText] = num*1 + 1;
            }
        }
        for (var i = 0; i < chText.length; i++) {
            var chNum = 0;
            for (var j = 0; j < ckChildFilterArr.length ; j++) {
                var chChildText = flag?ckChildFilterArr[j].innerHTML:ckChildFilterArr[j].textContent;
                if(chText[i] == chChildText){
                    chNum = chNum +1
                }
            }
            chIndex.push(chNum);
        }
        var newIndex = [];
        for (var i = 0; i < chIndex.length; i++) {
            if(i == 0){
                newIndex.push(0);
            }else {
                var newNum = 0;
                for (var j = 0; j < chIndex.length; j++) {
                    if(j<i){
                        newNum = newNum +chIndex[j];
                    }
                }
                newIndex.push(newNum);
            }
        }
        chIndex = newIndex;

        for (var j = 0; j < childFilterArr.length; j++) {
            var findFlag = false;
            for (var k = 0; k < chIndex.length; k++) {
                if(j == chIndex[k]){
                    findFlag = true;
                    if(chIndex[k+1] != null){
                        childFilterArr[j].setAttribute("rowspan",chIndex[k+1] - j);
                        $(childFilterArr[j]).find("div.rowspan").parent("div.layui-table-cell").addClass("rowspanParent");
                        $(childFilterArr[j]).find("div.layui-table-cell")[0].style.height= (chIndex[k+1] - j)*38-10 +"px";

                    }else {
                        childFilterArr[j].setAttribute("rowspan",childFilterArr.length - j);
                        $(childFilterArr[j]).find("div.rowspan").parent("div.layui-table-cell").addClass("rowspanParent");
                        $(childFilterArr[j]).find("div.layui-table-cell")[0].style.height= (childFilterArr.length - j)*38-10 +"px";
                    }
                }
            }
            if(findFlag == false){
                childFilterArr[j].style.display = "none";
            }
        }
    }
    function execRowspan (fieldName,index,flag,ckRows){
        var fixedNode = $(".layui-table-body")[index];
        var child = $(fixedNode).find("td");
        var childFilterArr = [];
        for(var j = 0; j < child.length; j++){
            child[j].getAttribute('data-field')
            if(child[j].getAttribute("data-field") == fieldName){
                childFilterArr.push(child[j]);
            }
        }

        var ckChildFilterArr = [];
        if(fieldName == "0"){
            for(var j = 0; j < child.length; j++){
                child[j].getAttribute('data-field')
                if(child[j].getAttribute("data-field") == ckRows){
                    ckChildFilterArr.push(child[j]);
                }
            }
            execRadioRows(childFilterArr,ckChildFilterArr,flag);
            return;
        }

        //获取td的个数和种类
        var childFilterTextObj = {};
        for(var i = 0; i < childFilterArr.length; i++){
            var childText = flag?childFilterArr[i].innerHTML:childFilterArr[i].textContent;
            if(childFilterTextObj[childText] == undefined){
                childFilterTextObj[childText] = 1;
            }else{
                var num = childFilterTextObj[childText];
                childFilterTextObj[childText] = num*1 + 1;
            }
        }
        var canRowspan = true;
        var maxNum;//以前列单元格为基础获取的最大合并数
        var finalNextIndex;//获取其下第一个不合并单元格的index
        var finalNextKey;//获取其下第一个不合并单元格的值
        for(var i = 0; i < childFilterArr.length; i++){
            (maxNum >9000 || !maxNum)&&(maxNum = $(childFilterArr[i]).prev().attr("rowspan")&&fieldName!="8"?$(childFilterArr[i]).prev().attr("rowspan"):9999);
            var key = flag?childFilterArr[i].innerHTML:childFilterArr[i].textContent;//获取下一个单元格的值
            var nextIndex = i+1;
            var tdNum = childFilterTextObj[key];
            var curNum = maxNum<tdNum?maxNum:tdNum;
            if(canRowspan){
                for(var j =1;j<=curNum&&(i+j<childFilterArr.length);){//循环获取最终合并数及finalNext的index和key
                    finalNextKey = flag?childFilterArr[i+j].innerHTML:childFilterArr[i+j].textContent;
                    finalNextIndex = i+j;
                    if((key!=finalNextKey&&curNum>1)||maxNum == j){
                        canRowspan = true;
                        curNum = j;
                        break;
                    }
                    j++;
                    if((i+j)==childFilterArr.length){
                        finalNextKey=undefined;
                        finalNextIndex=i+j;
                        break;
                    }
                }
                childFilterArr[i].setAttribute("rowspan",curNum);
                if($(childFilterArr[i]).find("div.rowspan").length>0){//设置td内的div.rowspan高度适应合并后的高度
                    $(childFilterArr[i]).find("div.rowspan").parent("div.layui-table-cell").addClass("rowspanParent");
                    $(childFilterArr[i]).find("div.layui-table-cell")[0].style.height= curNum*38-10 +"px";
                }
                canRowspan = false;
            }else{
                childFilterArr[i].style.display = "none";
            }
            if( --childFilterTextObj[key] == 0 | --maxNum==0 | --curNum==0 | (finalNextKey!=undefined && nextIndex==finalNextIndex)){
                canRowspan = true;
            }
        }
    }
    function layuiRowspan(fieldNameTmp,index,flag,ckRows){
        var fieldName = [];
        if(typeof fieldNameTmp == "string"){
            fieldName.push(fieldNameTmp);
        }else{
            fieldName = fieldName.concat(fieldNameTmp);
        }
        for(var i = 0;i<fieldName.length;i++){
            execRowspan(fieldName[i],index,flag,ckRows);
        }
    }
    //行合并 end
</script>
</head>
<body>
<div class="layui-fluid">
	<div class="layui-row layui-col-space10">
		<div class="layui-col-sm4">
			<div class="grid-demo grid-demo-bg1">
				<table class="layui-table" id="test-table1" lay-filter="test-table1"></table>
			</div>
		</div>
		<div class="layui-col-sm4">
			<div class="grid-demo">
				<table class="layui-table" id="test-table2" lay-filter="test-table2"></table>
			</div>
		</div>
		<div class="layui-col-sm4">
			<div class="grid-demo">
				<table class="layui-table" id="test-table3" lay-filter="test-table3"></table>
			</div>
		</div>

	</div>
</div>
</body>
</html>

依然存在的问题(但不影响使用):

1、radio或者是checkbox按钮没有垂直居中。
2、选中样式或者是鼠标移动样式没有调整(还是会蛇皮拐弯)。
在这里插入图片描述





  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
layui table是一款基于layui框架的数据表格插件,可以实现表格分页、排序、过滤等功能,而且还支持合并单元格。 合并单元格主要是指在表格合并相邻的单元格,将它们合并成一个单元格,从而可以显示更加复杂的数据。 在layui table中,合并单元格有两种方式实现: 第一种方式是通过设置colspan和rowspan属性来合并单元格。具体使用方法如下: table.render({ elem: '#test', cols: [[ //表头 {field: 'id', title: 'ID', width: 80}, {field: 'username', title: '用户名', width: 120}, {field: 'sex', title: '性别', width: 80}, {field: 'city', title: '城市', width: 100}, {field: 'sign', title: '签名', width: 200}, {field: 'experience', title: '积分', width: 100}, {field: 'score', title: '评分', width: 100}, {field: 'classify', title: '职业', width: 100}, {field: 'wealth', title: '财富', width: 100} ]], data: [], done: function(res, curr, count){ //合并单元格 var index = 0; var data = res.data; for(var i=0;i<data.length;i++){ layui.$('#test tr:eq('+index+') td:eq(0)').attr('rowspan', 2); layui.$('#test tr:eq('+index+') td:eq(1)').attr('rowspan', 2); layui.$('#test tr:eq('+index+') td:eq(2)').attr('rowspan', 2); index += 2; } } }); 第二种方式是通过设置lay-id属性来合并单元格。具体使用方法如下: table.render({ elem: '#test', url: '/demo/table/user/', method: 'get', cols: [[ {field:'id', title:'ID', width:80, sort:true, fixed: 'left'} ,{field:'username', title:'用户名', width:120} ,{field:'sex', title:'性别', width:80, sort:true} ,{field:'city', title:'城市', width:100} ,{field:'sign', title:'签名', width:200} ,{field:'experience', title:'积分', width:100, sort:true} ,{field:'score', title:'评分', width:100, sort:true} ,{field:'classify', title:'职业', width:100} ,{field:'wealth', title:'财富', width:135, sort:true, fixed: 'right'} ]], id: 'test', page: true, limit: 10, height: 'full-200', done:function(res, curr, count){ //合并单元格 var data = res.data; var mergeList = ['username','city','classify']; for(var i=0;i<mergeList.length;i++){ var mergeArray = []; var mergeCount = 1; for(var j=0;j<data.length;j++){ if(j==data.length-1){ mergeArray.push(mergeCount); }else{ if(data[j][mergeList[i]]==data[j+1][mergeList[i]]){ mergeCount++; }else{ mergeArray.push(mergeCount); mergeCount = 1; } } } var id = '#' + layui.table.config.id; layui.$(id + ' tbody tr').each(function(rowIndex){ var td = layui.$(this).find('td[data-field='+mergeList[i]+']'); for(var k = 0;k<td.length;k++){ if(mergeArray[rowIndex] && mergeArray[rowIndex]>1){ layui.$(td[k]).attr('rowspan', mergeArray[rowIndex]); mergeArray[rowIndex]--; } } }) } } }); 以上是两种实现layui table合并单元格的方法,具体根据实际需求而定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值