Datatable-如何每次从渲染的 html 元素中按不同的值对一列进行自定义排序

问题描述 投票:0回答:1

我们假设数据表的单元格呈现如下:

      columnDefs: [
            {
                targets: 0,
                type: 'percent',
                render: function (data, type, full, meta) {
                    let html = '<span class="sort-value">' + data + '</span>';
                    html += "(<span class='sort-percent'>" + full.percent + "</span>%)";
                    return html;
                }
            }
      }
  • 此时,通过点击标题,我想使用带有渲染的HTML元素的

    sort-value
    类名的值,以ASC方向进行第一次排序。

  • 第二个排序相同,但 DESC 方向按带有

    sort-value
    类名的值。

  • 对于第三种排序,我想按具有

    sort-percent
    类名的值在 ASC 方向上排序。

  • 对于第四种排序,我想按具有

    sort-percent
    类名的值在 DESC 方向上排序。

然后我想一遍又一遍地重复这个序列。

那么,第四次排序的时候,应该是这样的:

enter image description here

因此我为此创建了逻辑并引入了以下两个变量:

var previously_sorted_index = 0;
var sort_state = 0;         // 0: default, 1: sort-value ASC, 2: sort-value DESC, 3: percentage ASC, 4: percentage DESC

每当单击标题并执行排序时,

sort_state
值就会更新,这效果很好。为了更好地理解,这是我的代码:

$('#table thead th').on('click', function() {
    var colIdx = $(this).index();

    if(previously_sorted_index == colIdx) {
        sort_state ++;
        if(sort_state == 5)
            sort_state = 1;
    } else {
        previously_sorted_index = colIdx;
        sort_state = 1;
    }
});

问题是我使用数据表的排序插件自定义了排序,但它没有按预期工作。

它只是使用单元格的 HTML 元素执行字符串排序。

这是我的自定义代码

$.extend($.fn.dataTableExt.oSort, {
        "percent-pre": function (a) {
            let div = document.createElement('div');
            div.innerHTML = a;
            let sort_val_el = div.getElementsByClassName("sort-value");
            let sort_percent_el = div.getElementsByClassName("sort-percent");

            let sort_val = parseFloat(sort_val_el.length > 0 ? sort_val_el[0].innerHTML : 0);
            let percentage_val = parseFloat(sort_percent_el.length > 0 ? sort_percent_el[0].innerHTML : 0);

            return [sort_val, percentage_val];
        },
      
        "percent-asc": function (a, b) {
            if(sort_state == 1) {
                return a[0] > b[0] ? 1 : -1;
            } else if(sort_state == 3) {                        // percentage ASC/DESC
                return a[1] > b[1] ? 1 : -1;
            }
            return 0;
        },
      
        "percent-desc": function (a, b) {
            if (sort_state == 2) {                              // sort-value ASC/DESC
                return b[0] > a[0] ? 1 : -1;
            } else if(sort_state == 4) {                        // percentage ASC/DESC
                return b[1] > a[1] ? 1: -1;
            }
            return 0;
        }
    });

我调试了一下,

sort_state
的值完全按照预期更新了。

percent-pre
返回单个值而不是像我的代码中那样的数组时(例如,仅
percent
值),排序将完全基于该值进行。

如果返回一个数组并根据

sort_state
值对数组中任意元素的值进行排序是行不通的。

我的代码有问题吗?

谢谢!

javascript jquery dom datatable
1个回答
1
投票

正如@andrewJames提到的,Datatable v1.x不提供带有自定义排序插件的

-asc
-desc
选项。

所以我更新了Datatable到v2.0,它提供了以上两个选项,但是有一种不进行排序的状态(状态0 - 默认顺序),所以连续按排序就会按ASC排序, DESC,然后是Default(未排序)状态。然后,在第4次排序时,又变成ASC,所以这样的话,一个周期就是6次。 我无法使用v2.0的排序功能,因为我希望一个周期是4次

可能还有删除默认状态的功能。在默认情况下(未排序状态),我们必须强制绘制排序箭头方向才能有 4 个排序周期...

我用 v1.x 解决了这个问题,如下:

数据表列定义中有

orderDataType: 
选项。

     columnDefs: [
            {
                targets: 1,
                type: 'percent',
                render: function (data, type, full, meta) {
                    let html = '<span class="sort-value">' + data + '</span>';
                    html += "(<span class='sort-percent'>" + full.percent + "</span>%)");
                    return html;
                },
                orderDataType: 'custom-sort'
            },
            ....
      ]

点击表头时,数值更新为4次循环。

    var previously_sorted_index = 0;
    var sort_state = 0;                 // 0: default, 1: sort-value ASC, 2: sort-value DESC, 3: percentage ASC, 4: percentage DESC

    $('#table thead th').on('click', function() {
        var colIdx = $(this).index();
        
        if(previously_sorted_index == colIdx) {
            sort_state ++;
            if(sort_state == 5)
                sort_state = 0;
        } else {
            previously_sorted_index = colIdx;
            sort_state = 1;
        }
    });

使用订单插件自定义排序功能。

    $.fn.dataTable.ext.order['custom-sort'] = function(settings, colIdx) {
        return this.api().column(colIdx, {order: 'index'}).nodes().map(function(td, i) {
            let sortValue = $(td).find('.sort-value').text();
            let sortPercent = $(td).find('.sort-percent').text();
            if (sort_state % 4 < 2) {
                // First two sorts use sort-value
                return parseFloat(sortValue) || 0;
            } else {
                // Next two sorts use sort-percent
                return parseFloat(sortPercent) || 0;
            }
        });
    };

这里重要的是

type: 'percent'
如果删除此选项,自定义订单功能将无法使用。

© www.soinside.com 2019 - 2024. All rights reserved.