DataTables分页时如何实现连续且不受排序影响的行号计数?
DataTables分页时如何实现连续且不受排序影响的行号计数?
我之前用DataTables处理用户数据表格的分页和排序,数据来自MySQL数据库,通过.NET应用获取。当时需要第一列显示不受排序影响的行序号,一开始用了CSS计数的方案,代码如下:
JavaScript 初始化代码
new DataTable('#employees', { info: false, paging: true, "aLengthMenu": [5, 10, 20], // "dom": 'rtip', });
CSS 样式代码
.dt-column-order:before { margin-bottom: 1px; } th { outline: none !important; } .dt-paging { margin-top: 15px !important; } .pagination { justify-content: flex-end; } /* CSS row count */ table { counter-reset: row-num; } table tbody tr { counter-increment: row-num; } table tbody tr td:first-child::before { content: counter(row-num) ""; }
HTML 结构代码
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js"></script> <script src="https://cdn.datatables.net/2.1.8/js/dataTables.min.js"></script> <script src="https://cdn.datatables.net/2.1.8/js/dataTables.bootstrap5.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.datatables.net/2.1.8/css/dataTables.bootstrap5.min.css" rel="stylesheet" /> <div class="container-fluid my-2"> <h2>Data Tables</h2> <table id="employees" class="table table-bordered table-striped mx-1"> <thead> <tr> <th data-dt-order="disable">No</th> <th>Name</th> <th>Position</th> <th>Office</th> <th>Age</th> <th>Start date</th> <th>Salary</th> </tr> </thead> <tbody> <tr> <td></td> <td>Tiger Nixon</td> <td>System Architect</td> <td>Edinburgh</td> <td>61</td> <td>2011-04-25</td> <td>$320,800</td> </tr> <tr> <td></td> <td>Garrett Winters</td> <td>Accountant</td> <td>Tokyo</td> <td>63</td> <td>2011-07-25</td> <td>$170,750</td> </tr> <tr> <td></td> <td>Ashton Cox</td> <td>Junior Technical Author</td> <td>San Francisco</td> <td>66</td> <td>2009-01-12</td> <td>$86,000</td> </tr> <tr> <td></td> <td>Cedric Kelly</td> <td>Senior Javascript Developer</td> <td>Edinburgh</td> <td>22</td> <td>2012-03-29</td> <td>$433,060</td> </tr> <tr> <td></td> <td>Ștefan Popa</td> <td>Accountant</td> <td>Tokyo</td> <td>33</td> <td>2008-11-28</td> <td>$162,700</td> </tr> <tr> <td></td> <td>Brielle Williamson</td> <td>Integration Specialist</td> <td>New York</td> <td>61</td> <td>2012-12-02</td> <td>$372,000</td> </tr> <tr> <td></td> <td>Herrod Chandler</td> <td>Sales Assistant</td> <td>San Francisco</td> <td>59</td> <td>2012-08-06</td> <td>$137,500</td> </tr> <tr> <td></td> <td>Rhona Davidson</td> <td>Integration Specialist</td> <td>Tokyo</td> <td>55</td> <td>2010-10-14</td> <td>$327,900</td> </tr> <tr> <td></td> <td>Colleen Hurst</td> <td>Javascript Developer</td> <td>San Francisco</td> <td>39</td> <td>2009-09-15</td> <td>$205,500</td> </tr> <tr> <td></td> <td>Sonya Frost</td> <td>Software Engineer</td> <td>Edinburgh</td> <td>23</td> <td>2008-12-13</td> <td>$103,600</td> </tr> <tr> <td></td> <td>Jena Gaines</td> <td>Office Manager</td> <td>London</td> <td>30</td> <td>2008-12-19</td> <td>$90,560</td> </tr> <tr> <td></td> <td>Quinn Flynn</td> <td>Support Lead</td> <td>Edinburgh</td> <td>22</td> <td>2013-03-03</td> <td>$342,000</td> </tr> </tbody> </table> </div>
但这个方案有个明显的问题:当数据量需要分页时,每一页的行号都会从1重新开始,完全达不到跨分页连续计数的需求。所以我想找个基于JavaScript的解决方案,而且最好能兼容排序后的行号保持连续。
问题解答
1. DataTables有没有内置的解决方案?
很遗憾,DataTables并没有直接提供这种“跨分页连续且不受排序影响”的行号内置功能,但它提供了非常灵活的API,我们可以用这些API轻松实现这个需求。
2. 可行的解决方案是什么?
我们可以利用DataTables的drawCallback回调函数——这个函数会在表格每次重绘(包括分页切换、排序、搜索操作后)时触发,正好适合用来动态计算并更新行号。
具体实现步骤如下:
- 初始化DataTables时,添加
drawCallback配置项 - 通过DataTables的
page.info()方法获取当前分页的信息,计算当前页的起始行号 - 遍历当前页的所有行,把计算好的行号填充到第一列中
修改后的JavaScript代码如下:
new DataTable('#employees', { info: false, paging: true, "aLengthMenu": [5, 10, 20], // "dom": 'rtip', drawCallback: function() { var table = this.api(); // 获取当前分页信息:page是当前页码(从0开始),length是每页行数 var pageInfo = table.page.info(); // 计算当前页的起始行号 var startNumber = pageInfo.page * pageInfo.length + 1; // 遍历当前页的行,设置行号 table.rows({page: 'current'}).every(function(index) { $(this.node()).find('td:first').text(startNumber + index); }); } });
同时,你可以把HTML中第一列的空<td>标签留空,或者直接写个占位符,JS会自动覆盖填充。
这个方案的优势:
- 不管怎么切换分页,行号都会连续递增(比如第二页第一行是6,第三页第一行是11,以此类推)
- 排序操作后,行号依然保持连续,而且第一列因为设置了
data-dt-order="disable",不会被排序影响位置 - 完全基于DataTables的官方API实现,稳定性和兼容性都有保障
备注:内容来源于stack exchange,提问作者Razvan Zamfir
相关产品推荐
相关产品推荐

