DataTable 自定义排序功能有效但不更新表格显示

Posted

技术标签:

【中文标题】DataTable 自定义排序功能有效但不更新表格显示【英文标题】:DataTable custom sorting function works but doesn't update table display 【发布时间】:2018-12-10 23:47:40 【问题描述】:

我正在尝试对名为“优先级”的列进行排序。此列有 5 个可能的值:高、中、低、无优先级和 N/A。我希望能够按该顺序(升序)或反向(降序)对它们进行排序。我的方法是根据我发现的here 创建一个自定义排序函数。这就是我所做的:

option["columnDefs"] = [
  
    "render":function(data,type,row) 
      var $select;
      switch(data) 
       case: "High":
         $select = $('<div class="my-class-high" priority="high">High</div');
         break;
       case: "Medium":
         $select = $('<div class="my-class-medium" priority="medium">Medium</div');
         break;  
       // etc. for other values. 
      
      return $select.prop("outerhtml");
     ,
     "targets" : 7,
     "sType" : "priority" 
   
];

function getRank(cellHtml) 
  switch ($(cellHtml).attr("priority")) 
  case "high":
    return 0;
  case "medium":
    return 1;
  case "low":
    return 2;
  case "unprioritized":
    return 3;
  case "notapplicable":
    return 4;
  default:
    throw "Unrecognized priority.";
  


jQuery.fn.dataTableExt.oSort["priority-desc"] = function (x, y) 
  return getRank(x) < getRank(y);
;

jQuery.fn.dataTableExt.oSort["priority-asc"] = function (x, y) 
  return getRank(x) > getRank(y);
;

//further down...
   $(#mytable).DataTable(option);

所有代码,包括排序函数,都按预期命中。当我单击优先级列时,字形会翻转。我的问题是显示的排序顺序永远不会改变:它保持升序,正确显示在表格顶部的高优先级。

我创建了一个临时事件处理函数来检查事情:

$(tableLookup).on('order.dt',function() 
   var order = table.order();
);

有了这个,我可以进一步验证每次单击列标题时排序顺序是否在变化(至少在内部),即使显示的顺序没有更新。

我正在运行 jquery.dataTables.js 版本 1.10.4。

我也尝试过使用数据排序属性,正如 Anjani 的回答 here 中所建议的那样。这对排序顺序没有任何影响——表格仍然使用显示的文本按字母顺序对列进行排序。

任何想法可能导致我看到的这些问题以及如何让排序工作?

【问题讨论】:

【参考方案1】:

这似乎有效:

var example = $('#example').DataTable(
  columns: [
    null, 
    null, 
    
      sType : "priority",
      render: function(data,type,row) 
        var retVal = $("<div/>");
        switch(data) 
          case "High":
            retVal = retVal
              .addClass("my-class-"+data.toLowerCase())
              .attr("data-priority", data.toLowerCase())
              .text(data);
            break;
          case "Medium":
            retVal = retVal
              .addClass("my-class-"+data.toLowerCase())
              .attr("data-priority", data.toLowerCase())
              .text(data)
            break;  
          case "Low":
            retVal = retVal
              .addClass("my-class-"+data.toLowerCase())
              .attr("data-priority", data.toLowerCase())
              .text(data)
            break;  
          case "Unprioritized":
            retVal = retVal
              .addClass("my-class-"+data.toLowerCase())
              .attr("data-priority", data.toLowerCase())
              .text(data)
            break;  
          case "N/A":
            retVal = retVal
              .addClass("my-class-notapplicable")
              .attr("data-priority", "notapplicable")
              .text(data)
            break;
        
        return retVal.prop("outerHTML");
      
    
  ]
);
function getRank(data) 
  switch (data) 
    case "high":
      return 0;
    case "medium":
      return 1;
    case "low":
      return 2;
    case "unprioritized":
      return 3;
    case "notapplicable":
      return 4;
    default:
      throw "Unrecognized priority.";
  

jQuery.extend(jQuery.fn.dataTableExt.oSort, 
  "priority-pre": function ( a ) 
    return getRank($(a).data("priority"));
  ,
  "priority-asc": function( a, b ) 
    return ((a < b) ? -1 : ((a > b) ? 1 : 0));
  ,
  "priority-desc": function(a,b) 
    return ((a < b) ? 1 : ((a > b) ? -1 : 0));
  
);

您的渲染案例功能很糟糕,所以我不确定您是否真的在调用您的订单功能,最好检查一下控制台的内容。

我敢说 order 函数可以整理,我不知道为什么我不喜欢 switch 语句,但我真的非常喜欢。虽然是 YMMV。希望有帮助,工作 JSFiddle here。

【讨论】:

【参考方案2】:

您可以使用渲染功能来做到这一点。渲染函数的第二个参数是 DataTables 要求的数据版本。当它是sort 时,它会询问应该用于排序的值。有了这个,你就不需要自定义排序方法了。

var example = $('#example').DataTable(
  columns: [
    null, 
    null, 
    
      render: function(data,type,row) 
        if(type == 'sort')
            return getRank(data.toLowerCase());
        
        switch(data) 
        case "N/A":
            return '<div class="my-class-notapplicable">' + data + '</div>';
        default:
            return '<div class="my-class-' + data.toLowerCase() + '">' + data + '</div>';
        
      
    
  ]
);
function getRank(data) 
  switch (data) 
    case "high":
      return 0;
    case "medium":
      return 1;
    case "low":
      return 2;
    case "unprioritized":
      return 3;
    case "n/a":
      return 4;
    default:
      throw "Unrecognized priority.";
  

https://datatables.net/reference/option/columns.render

【讨论】:

【参考方案3】:

答案拯救了我的一天:https://***.com/a/25319252/1554947

        var table = $('#table');
        table = table.DataTable(
            columns: [
                 data: "link" ,
                 data: "code" ,
                 data: "entryDateTime" 
            ],
            columnDefs: [
                
                    targets: 2,
                    render: function (data, type) 
                        if (type == "display") 
                            var date = new Date(data);
                            var options =  year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "numeric" ;
                            return date.toLocaleDateString('tr-TR', options);
                        

                        return data;
                    
                
            ],
            order: [[2, "desc"]] // default order when page loaded
        );

【讨论】:

以上是关于DataTable 自定义排序功能有效但不更新表格显示的主要内容,如果未能解决你的问题,请参考以下文章

jQuery dataTable 列的自定义排序

dataTable 自定义排序

DataTable:td内日期的自定义排序

DataGridView(部分)数据绑定自定义排序

如何修改bootstrap中 datatable 表格的样式?

DataTable CAST 成集合后,进行自定义排序再转换回DataTable