首页 > 解决方案 > 使用 N/A 值对动态列进行排序

问题描述

我在项目中使用数据。该表正在使用 ajax 填充。

$.ajax({
    url: "<?php echo $ajaxurl;?>",
    type: "POST",
    success : function(html){
        $("#response").html(html);
        $('#loadingmessage').hide(); // hide the loading message
        $('#databuttons').show(); // show the buttons
        var t = $('#table').DataTable({
            "columnDefs": [ {
                "searchable": false,
                "orderable": false,
                "targets": 0
            }],
            "deferRender": true,
            "order": [[ 1, 'asc' ]],
            "language": {
              "search": "Search within results:"
            },
            "dom": 'B<"clear">lfrtip',
            buttons: [
                'copy', 'csv', 'excel', 'print'
            ],
            "responsive":true
        });

        t.on( 'order.dt search.dt', function () {
            t.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
                cell.innerHTML = i+1;
            });
        } ).draw();
        $('.dt-button').css('visibility','hidden');
    }
});

最重要的是,列的数量和它们的顺序是动态的。

我想要实现的是对可能包含数值以及“N/A”值的任意列进行排序。

现在排序不能正常工作。

排序

在此处输入图像描述

如图所示,排序不正确,因为某些值包含 N/A 值。

我希望 N/A 位于表格底部。

我发现了以下教程

但这里的问题是我们必须指定目标:

"columnDefs":      [{ type: 'percent', targets: 6 },{ "type": "percent", "targets": 4 }]

我的表可能包含 2 列、3 列,因此它是动态的,在这种情况下如何指定目标?

我还发现了绝对排序插件

但问题与我们必须指定目标列相同。

当我们有动态列时如何处理这个问题?

标签: javascriptjquerydatatables

解决方案


首先,我强烈建议不要使用 jQuery$.ajax()方法来填充您的 DataTable,因为这种方法会遇到一大堆问题。我建议使用 DataTablesajax选项,而不是:

var t = $('#table').DataTable({
    ajax: {
        url: "<?php echo $ajaxurl;?>",
        type: 'POST'
    },
    ...
});

至于你的具体问题,它有两个部分:

1.以自定义方式对您的数据进行排序;

2.将自定义类型(排序所需)分配给任意列。

基本上,第一个问题的解决方案归结为引入您在/选项population中指定的自定义数据类型(例如 ) :columnDefscolumns

var t = $('#table').DataTable({
    columns: [
        ...
        {data: 'population', title: 'population', type: 'population'},
    ]
    ...
});

有了它,您可以实现您的自定义排序逻辑:

Object.assign($.fn.DataTable.ext.oSort, {
      'population-asc': (a,b) => b=='N/A' ? -1: a=='N/A' ? 1 : Number(a.replace(/,/g,''))-Number(b.replace(/,/g,'')),
      'population-desc': (a,b) => b=='N/A' ? -1: a=='N/A' ? 1 : Number(b.replace(/,/g,''))-Number(a.replace(/,/g,''))
    })

第二个问题是通过向后端(在 DataTables 初始化之前)抛出 AJAX 调用来解决的,以便根据您的标准获取列定义(我在您的原始帖子中没有看到,但是,我相信您可以相应地进行调整):

$(document).ready(() => {
    //get dynamically defined columns
    $.ajax({
        url: "/getcols"
    })
    .done(columns => {
        //initialize datatables
        const dataTable = $("table").DataTable({
            ...
            ajax: {
                url: "/getdata",
                dataSrc: ""
            },
            columns: columns
        });
    })
});

作为对调用的回报/getcols,您的后端必须使用有效的column/columnDefs选项定义进行响应,包括 type为必要的列设置为“人口”,例如:

[
  { "title": "country", "data": "country" },
  { "title": "population", "data": "population", "type": "population" },
  { "title": "year", "data": "year" }
]

下面的实时代码片段演示了排序部分,对于完整的演示,您可以使用浏览器的 DevTools检查以下沙箱。

//source data sample
const src1 = [
  {country: 'India', population: '1,368,737,513', year: 2019},
  {country: 'China', population: '1,420,062,022', year: 2019},
  {country: 'USA', population: '329,093,110', year: 2019},
  {country: 'Ukraine', population: '43,795,220', year: 2019},
  {country: 'North Korea', population: 'N/A', year: 2019},
  {country: 'Russian Federation', population: 'N/A', year: 2019}
];
//initialize datatables
const dataTable = $('table').DataTable({
  data: src1,
  dom: 't',
  columns: [
    { "title": "country", "data": "country" },
    { "title": "population", "data": "population", "type": "population" },
    { "title": "year", "data": "year" }
  ]
});
//custom sorting plug-in
Object.assign($.fn.DataTable.ext.oSort, {
  'population-asc': (a,b) => b=='N/A' ? -1: a=='N/A' ? 1 : Number(a.replace(/,/g,''))-Number(b.replace(/,/g,'')),
  'population-desc': (a,b) => b=='N/A' ? -1: a=='N/A' ? 1 : Number(b.replace(/,/g,''))-Number(a.replace(/,/g,''))
});
<!doctype html><html><head><link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/jq-3.3.1/dt-1.10.18/rg-1.1.0/datatables.min.css" /><script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script><script type="text/javascript" src="https://cdn.datatables.net/v/dt/jq-3.3.1/dt-1.10.18/rg-1.1.0/datatables.min.js"></script></head><body><table></table></body></html>


推荐阅读