使用行跨度对数据表进行分页

Paginate datatables with rowspans

我在使用 rowspans 对数据 table 进行分页时遇到了一些问题。我的问题是,在指示“pageLength”属性时,它会考虑所有 trs。例如,如果我有这样的东西,我需要使用 "pageLength": 3.

--------------------------------------------
                     |
tr with rowspan = 2  | tr inside #1
                     |----------------------
                     |
                     | tr inside #2
--------------------------------------------

我的问题是,因此,当沿着 table 的不同页面进行分页时,可能会发生某些 tr 最终成为“孤儿”的情况。例如,如果页面以 tr #1 结尾,则 tr #2 可能会在下一页上“单独”出现(没有 rowspan = 2 的 tr)。有什么方法可以对这些 table 进行分页,只考虑那些“父”行,即带有 rowspan 的行?

我不知道有什么方法可以完全按照您的要求进行操作。话虽如此,我在下面提供了一些注释,以防它们是可以接受的替代方案。


您可以创建一个伪造的 rowspan 效果,无论您在哪个页面,它都会始终在第一列显示相关值:

但即便如此,您仍然可能会在一页底部的跨度中看到一些行,而在下一页的顶部看到跨度中的其余行。我看不出有任何解决办法(除了这个答案末尾提到的一种可能情况)。

作为替代方案,您可能需要查看 row group 扩展。但是,同样不能保证整个组总是只出现在一页上。


如果您对“假行跨度”感兴趣,这里有一个例子。它通过操纵每个页面上的 DOM 节点来工作,以便不显示第一列中的重复值(并且单元格的 border-top 行被删除)。

DataTable 本身的数据没有改变,所以如果您搜索“Edinburgh”,您仍然会找到所有 3 条记录。

var dataSet = {
  "data": [
    {
      "id": "1",
      "name": "Tiger Nixon",
      "position": "System Architect",
      "salary": "0,800",
      "start_date": "2011/04/25",
      "office": "Edinburgh",
      "extn": "5421"
    },
    {
      "id": "2",
      "name": "Garrett Winters",
      "position": "Accountant",
      "salary": "0,750",
      "start_date": "2011/07/25",
      "office": "Tokyo",
      "extn": "8422"
    },
    {
      "id": "3",
      "name": "Ashton Cox",
      "position": "Junior Technical Author",
      "salary": ",000",
      "start_date": "2009/01/12",
      "office": "Tokyo",
      "extn": "1562"
    },
    {
      "id": "4",
      "name": "Cedric Kelly",
      "position": "Senior Javascript Developer",
      "salary": "3,060",
      "start_date": "2012/03/29",
      "office": "New York",
      "extn": "6224"
    },
    {
      "id": "5",
      "name": "Airi Satou",
      "position": "Accountant",
      "salary": "2,700",
      "start_date": "2008/11/28",
      "office": "Tokyo",
      "extn": "5407"
    },
    {
      "id": "6",
      "name": "Brielle Williamson",
      "position": "Integration Specialist",
      "salary": "2,000",
      "start_date": "2012/12/02",
      "office": "New York",
      "extn": "4804"
    },
    {
      "id": "7",
      "name": "Herrod Chandler",
      "position": "Sales Assistant",
      "salary": "7,500",
      "start_date": "2012/08/06",
      "office": "San Francisco",
      "extn": "9608"
    },
    {
      "id": "8",
      "name": "Rhona Davidson",
      "position": "Integration Specialist",
      "salary": "7,900",
      "start_date": "2010/10/14",
      "office": "Tokyo",
      "extn": "6200"
    },
    {
      "id": "9",
      "name": "Colleen Hurst",
      "position": "Javascript Developer",
      "salary": "5,500",
      "start_date": "2009/09/15",
      "office": "San Francisco",
      "extn": "2360"
    },
    {
      "id": "10",
      "name": "Sonya Frost",
      "position": "Software Engineer",
      "salary": "3,600",
      "start_date": "2008/12/13",
      "office": "Edinburgh",
      "extn": "1667"
    },
    {
      "id": "11",
      "name": "Jena Gaines",
      "position": "Office Manager",
      "salary": ",560",
      "start_date": "2008/12/19",
      "office": "London",
      "extn": "3814"
    },
    {
      "id": "12",
      "name": "Quinn Flynn",
      "position": "Support Lead",
      "salary": "2,000",
      "start_date": "2013/03/03",
      "office": "Edinburgh",
      "extn": "9497"
    }
  ]
};

var previous = '';
 
$(document).ready(function() {

var table = $('#example').DataTable( {
  data: dataSet.data,
  "order": [[ 0, 'asc' ]],
  columns: [
    { title: "Office", data: "office" },
    { title: "Name", data: "name" },
    //{ title: "Office2", data: "office" },
    { title: "Position", data: "position" },
    { title: "Start date", data: "start_date" },
    { title: "Salary", data: "salary" }
  ],
  "initComplete": function(settings, json) {
    // in case the initial sort order leads to 
    // cells needing to be altered:
    processColumnNodes( $('#example').DataTable() );
  }
} ); 
    
table.on( 'draw', function () {
  processColumnNodes( $('#example').DataTable() );
} );

function processColumnNodes(tbl) {
  // see https://datatables.net/reference/type/selector-modifier
  var selector_modifier = { order: 'current', page: 'current', search: 'applied' }

  var previous = '';
  var officeNodes = tbl.column(0, selector_modifier).nodes();
  var officeData = tbl.column(0, selector_modifier).data();
    for (var i = 0; i < officeData.length; i++) {
    var current = officeData[i];
    if (current === previous) {
      officeNodes[i].textContent = '';
      officeNodes[i].setAttribute("style", "border-top:none;");
    } else {
      officeNodes[i].textContent = current;
    }
    previous = current;
  }
}

} );
  <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
  <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
  <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">

<div style="margin: 20px;">

    <table id="example" class="cell-border" style="width:100%">
    </table>

</div>

当您运行上面的代码片段时,您将在第 1 页末尾的“东京”的 4 行中看到 2 行。您将在第 2 页顶部 - 但您还会看到“东京”标签。


如果您的 rowspan 尺寸始终恰好为“2”,那么您还可以将“页面长度”下拉列表中的值设置为仅使用偶数:

"lengthMenu": [ 10, 20, 50, 100 ]

这样你就不会在不同的页面上出现任何“孤儿”。