DataTables自定义排序:数字优先、文本次之、空值置底实现
DataTables 自定义排序:数字优先、文本次之、空值置底
问题描述
需要对DataTables表格的Age列实现自定义排序,规则为:
- 优先排序数字值
- 其次排序文本值
- 空值始终置于表格底部
当前通过$.fn.dataTable.ext.oSort重写排序方法未达到预期效果,需调整实现逻辑。
解决方案
原代码仅处理了空值,未区分数字与文本的优先级。需在排序函数中先判断值的类型(数字/文本/空值),赋予不同优先级后再进行比较:
核心排序逻辑
- 空值处理:任何非空值都排在空值前面
- 类型优先级:数字 > 文本,数字值优先排在文本值前面
- 同类型比较:数字按数值大小排序,文本按字符串字典序排序(统一大小写避免区分)
修改后的排序函数
$(document).ready(function() { $.fn.dataTable.ext.errMode = 'none'; // 判断是否为数字的辅助函数 function isNumeric(val) { return !isNaN(parseFloat(val)) && isFinite(val); } $.fn.dataTable.ext.oSort['nullsort-asc'] = function(a, b) { // 处理空值:空值排最后 if (a === "" && b === "") return 0; if (a === "") return 1; if (b === "") return -1; const aIsNum = isNumeric(a); const bIsNum = isNumeric(b); // 数字优先于文本 if (aIsNum && !bIsNum) return -1; if (!aIsNum && bIsNum) return 1; // 同类型比较 if (aIsNum) { return parseFloat(a) - parseFloat(b); } else { // 文本统一转小写,避免大小写影响排序 const aLower = a.toLowerCase(); const bLower = b.toLowerCase(); return aLower.localeCompare(bLower); } }; $.fn.dataTable.ext.oSort['nullsort-desc'] = function(a, b) { // 处理空值:空值排最后 if (a === "" && b === "") return 0; if (a === "") return 1; if (b === "") return -1; const aIsNum = isNumeric(a); const bIsNum = isNumeric(b); // 数字优先于文本(降序时数字仍在前,只是数值从大到小) if (aIsNum && !bIsNum) return -1; if (!aIsNum && bIsNum) return 1; // 同类型比较 if (aIsNum) { return parseFloat(b) - parseFloat(a); } else { const aLower = a.toLowerCase(); const bLower = b.toLowerCase(); return bLower.localeCompare(aLower); } }; $('#example').DataTable({ columnDefs: getColumnDef() }); }); function getColumnDef(){ return [ { type: 'nullsort', targets: 3 }, { type: 'nullsort', targets: 4} ]; }
完整HTML代码
<table id="example" class="display" cellspacing="0" width="100%"> <thead> <tr> <th>Name</th> <th>Position</th> <th>Office</th> <th>Age</th> <th>Salary</th> </tr> </thead> <tfoot> <tr> <th>Name</th> <th>Position</th> <th>Office</th> <th>Age</th> <th>Salary</th> </tr> </tfoot> <tbody> <tr> <td>Tiger Nixon</td> <td>System Architect</td> <td>Edinburgh</td> <td></td> <td>$320,800</td> </tr> <tr> <td>James Nixon</td> <td>System Architect</td> <td>Edinburgh</td> <td></td> <td>$320,800</td> </tr> <tr> <td>Garrett Winters</td> <td>Accountant</td> <td>Tokyo</td> <td>63</td> <td></td> </tr> <tr> <td>Cedric Kelly</td> <td>Senior Javascript Developer</td> <td>Edinburgh</td> <td>22</td> <td>$433,060</td> </tr> <tr> <td>Airi Satou</td> <td>Accountant</td> <td>Tokyo</td> <td></td> <td>$162,700</td> </tr> <tr> <td>Brielle Williamson</td> <td>Integration Specialist</td> <td>New York</td> <td>61</td> <td></td> </tr> <tr> <td>Herrod Chandler</td> <td>Sales Assistant</td> <td>San Francisco</td> <td>59</td> <td>$137,500</td> </tr> <tr> <td>Rhona Davidson</td> <td>Integration Specialist</td> <td>Tokyo</td> <td>55</td> <td>$327,900</td> </tr> <tr> <td>Colleen Hurst</td> <td>Javascript Developer</td> <td>San Francisco</td> <td>39</td> <td>$205,500</td> </tr> <tr> <td>Sonya Frost</td> <td>Software Engineer</td> <td>Edinburgh</td> <td>A</td> <td>$103,600</td> </tr> <tr> <td>Jena Gaines</td> <td>Office Manager</td> <td>London</td> <td>30</td> <td>$90,560</td> </tr> <tr> <td>ADam Gaines</td> <td>Office Manager</td> <td>London</td> <td>Denis</td> <td>$90,560</td> </tr> <tr> <td>nancy Gaines</td> <td>Office Manager</td> <td>London</td> <td>zibra</td> <td>$90,560</td> </tr> <tr> <td>James Gaines</td> <td>Office Manager</td> <td>London</td> <td>capital</td> <td>$90,560</td> </tr> </tbody> </table>
效果说明
点击Age列头时:
- 升序:数字从小到大排列 → 文本按小写字典序排列 → 空值在最后
- 降序:数字从大到小排列 → 文本按小写字典序反向排列 → 空值仍在最后
内容的提问来源于stack exchange,提问作者Jordan
相关产品推荐
相关产品推荐

