datatables合并行(带分页、筛选)

本文介绍了一种在Datatables中实现行合并的方法,并解决了在数据筛选或分页后的还原问题。通过SQL查询分组和rowspan属性实现了指定数据单元的行合并。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于项目的需要,datatables表格需要对一些相同的数据单元进行行合并,但是网上搜索了半天,能实现行的合并,但是在经过数据筛选或者分页后又会还原。在此记录下自己的解决办法,希望能帮到需要的人。。。

1、合并原理

在datatables中,对于行的合并好像并没有给出具体的api,这里行的合并都是通过rowspan来实现,所以要合并多少行,这里需奥数据来标明。所以我做sql查询的时候,把数据进行了分组,然后给出一个字段来表示需要设置rowsapn的值,根据此值来添加相应的rowspan属性,从而实现合并行。

2、具体实现

1、查询的数据格式

在查询出来的数据中,有ROWN和MAXNUM两列,ROWN表示组内的顺序,MAXNUM表示组内最大的ROW值。

2、JS代码

网上的合并行都是将合并代码写在createdCell 当中,但是在对表格进行重绘后就会产生还原的问题,所以在下面的代码中我仅仅是把代码写到rowCallback 中而已,具体代码看下面:

首先在这里封装了一个datatables的方法:

var $table;
/**
 * 初始化Datatablas 包含分页,单列排序
 * @param {any} url 请求路径
 * @param {any} columns 列初始化
 * @param {any} columnDefs 自定义列显示
 */
function initTable(url, columns, columnDefs, loadSuccess, rowCallBack) {
    $table = $('#data-table').DataTable({
        "language": {
            "url": _datatablesLangUrl //全局变量,定义在_layout中
        },
        "dom": _defaultDom,
        "ordering": true,
        //"lengthChange": false, //是否允许用户改变表格每页显示的记录数,false时隐藏,默认true
        'order': [],//初始排序列
        //'select': true,
        "processing": true,
        "serverSide": true,
        "pageLength": 25,
        "scrollX": true,
        "scrollY": '50vh',
        "scrollCollapse": true,
        "destroy": true,
        "ajax": {
            "url": url,
            "type": "POST"
        },
        "rowCallback": function (row, data, index) {
            //console.log(data);
            if (rowCallBack)
                rowCallBack(row, data, index);
        },
        "columns": columns,
        "columnDefs": columnDefs
    });
    $table.on('init.dt', function () {
        if (loadSuccess)
            loadSuccess();
    })
}

 

loadSuccess和rowCallBack都是回调方法。

 var columns = [
                {"title":"", data: null, "visible": true },
                {"title":"",  data: null, "visible": true },
                {"title":"",  "width": "30px", "data": null },// 序号列
                {"title":"",  "data": "ID", "visible": false },
                {"title":"EXPRESSNUMBER",  "data": "EXPRESSNUMBER" },
                {"title":"EXPRESSCOMPANY",  "data": "EXPRESSCOMPANY" },
                {"title":"INVOICENO",  "data": "INVOICENO" },//6
                {"title":"CUSTOMERCODE",  "data": "CUSTOMERCODE" },
                {"title":"CUSTOMERFULLNAME",  "data": "CUSTOMERFULLNAME" },
                {"title":"CREATEUSERNAME",  "data": "CREATEUSERNAME", orderable: !1 },
                {"title":"CREATETIME",  "data": "CREATETIME", orderable: !1 },
                {"title":"LOGUSERNAME",  "data": "LOGUSERNAME", orderable: !1 },
                {"title":"LOGTIME",  "data": "LOGTIME", orderable: !1 },
                {"title":"EXPRESSENCODINGID",  "data":"EXPRESSENCODINGID","visible":false},
                {"title":"rown",  "data":"rown","visible":false},
                {"title":"maxnum",  "data":"maxnum","visible":false},
            ];

 

var columnDefs = [{
                targets: 0, 
                orderable: !1,
                render: function (data, type, row, meta) {
                   //在列渲染时做的一些额外操作,比如颜色字体等等
                },
                {
                },
                ...........
            }

上面都是为表格初始化做的一些列定义等操作,网上搜索有详细的教程,下面就是行合并了,代码就是在rowCallBack当中:

function rowCallBack(row, data, index){
                //row代表表格的每一行,每行数据都会进入这个方法走一遍
                console.log(data)//data,就是当前行的数据
                if(data.rown == data.maxnum){
                    $(row).find("td").eq(3).attr('rowspan', data.maxnum);
                    $(row).find("td").eq(4).attr('rowspan', data.maxnum);
                }else{
                    $(row).find("td").eq(3).remove();
                    $(row).find("td").eq(3).remove();
                }
            }

在这个rowCallBack当中,我对数据进行了判断,就是将rown和maxnum相等的行合并,不相等的删除掉。当然这里的操作,得看自己的数据格式,如果对于数据库查询出来的数据,每一组内的rown并不是从大到小的,而是从小到达的,你也可以判断data.rown == 1的时候进行行合并 ,其他条件下进行单元格的删除。 上面代码中eq(n)这个值由自己决定合并哪一列(从左到右 数起,其实为0),这里解释下上面代码中为什么会对eq(3)进行两次remove(),这是因为在第一次对eq(3)进行remove操作后,本来的....eq(4).remove(),由于前一列被删除,这里的第4列就变成列第3列,所以第二次对eq(3)的remove就是对eq(4)的remove()。

对于上面sql查询出来的数据格式,主要是用了Oracle的partition by分析函数,下面简单介绍下原理:

 对于数据表的数据,我分为三个步骤得到上面的数据格式:

1、第一次,使用partition by分析函数分组:

select row_number() over(partition by t.expressnumber order by t.createtime desc) rown ,t.* from temp t

上面的sql可以得到一个分组的数据,也就得到了需要用到的 rown

2、

SELECT MAX(tt.rown) maxnum,tt.expressnumber from t2 tt group by tt.expressnumber

这里的t2表就是第一步查询得出的结果集,这个可以使用Oracle的with实现

3、对上面的两个结果集进行left join

with t2 as --第一步
(
   select row_number() over(partition by t.expressnumber order by t.logtime desc) rown ,t.* from temp t
),
t3 as --第二步
(
  SELECT MAX(tt.rown) maxnum,tt.expressnumber from t2 tt group by tt.expressnumber
)
--第三步
select tt2.*,tt3.maxnum from t2  tt2
left join  t3 tt3
on tt2.expressnumber = tt3.expressnumber 

上面的代码基本就能得到数据,如果发现组内顺序或者组外顺序不尽人意,进行下组外组内排序就能得到数据了。

 

上面只是我自己的一些见解,请大家批评指正。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值