如何让jQuery DataTables在隐藏值上排序,但在显示值上搜索?

42

我有一个简单的DataTables网格,其中包含日期列。我在JSON数据集中为日期提供了两个值,一个用于显示,另一个专门设计用于DataTables排序。我的Web应用程序允许用户选择各种不同的日期格式,因此需要具有灵活性。

这是从Web服务器通过sAjaxSource获取的JSON数据,供DataTables使用。

{
  Reports : [
    { Date: { Sort = "20101131133000", Display : "11/31/2010 1:30 PM" } }, 
    { Date: { Sort = "20100912120000", Display : "1200 EST 2010-09-12" } }, 
  ]
}

使用 fnRender(),可以很容易地告诉 DataTables 基于 Date.SortValue 属性进行排序,并使 Display 属性对用户可见。这让我达成了目标的一半。

var dataTableConfig = {
  sAjaxSource: "/getreports",
  sAjaxDataProp: "Reports",
  aoColumns: [
    { mDataProp: "User" },
    { mDataProp: "Date.Sort", 
      bSortable: true, 
      sName: "Date", 
      bUseRendered: false, 
      fnRender: function (oObj) {
        return oObj.aData[oObj.oSettings.aoColumns[oObj.iDataColumn].sName].Display;
      }
    }
  ]
};

这是我的问题。我想允许用户根据显示的值输入筛选条件(使用DataTables提供的内置筛选输入),但他们不能这样做。

例如,如果用户输入“EST”,他们将得到零个结果,因为datatables基于mDataProp中指定的值进行过滤,而不是基于fnRender返回的值进行过滤。

有谁能帮助我解决如何对日期列进行排序和筛选的问题吗?谢谢。


自从datatables更新以来,这个问题的正确答案已经改变。我不确定SO政策是更改接受的答案还是更新答案,但其中之一可能会很方便? - Tim Ogilvy
我很乐意更改被接受的答案。我不再使用DataTables了,你能建议哪一个更好吗? - jessegavin
CW Spear在Nov 5 '13 at 7:12标记的答案似乎是正确的,并且对我有用。 - Tim Ogilvy
@jessegavin 你在用什么? - Leandro Bardelli
9个回答

84

我认为现有的答案已经过时,因为DataTables进行了更新。HTML5支持属性,DataTables可以使用这些属性轻松地对列进行排序,特别是data-sort属性。(参见https://datatables.net/examples/advanced_init/html5-data-attributes.html)

我可以像下面这样轻松地对表格进行排序:

<table>
  <thead>
    <tr>
      <td>Name</td>
      <td>Age</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John Doe</td>
      <td data-sort="37">2/1/78 (37 years old)</td>
    </tr>
    <tr>
      <td>Jane Doe</td>
      <td data-sort="35">12/1/80 (35 years old)</td>
    </tr>
  </tbody>
</table>

无论“年龄”列包含数字、符号和字母,DataTables 都将使用“data-sort”属性进行排序。


2
工作得很好,但是在1.10.4版本中,如果第一行具有空的data-sort值,则会出现问题:它不会使用其他行的属性。因此,请确保您的HTML中从未输出data-sort ="" - youen
5
注意,如果您是通过Ajax/json填充表格,则此解决方案无法正常工作。 - Martin Wickman
2
哦,我的天啊,这真的帮了我很多,之前试过很多愚蠢的方法。聪明而简单。谢谢! - mcleodm3
2
这是一个适用于所有人的最佳解决方案。谢谢。 - Razib Al Mamun
1
谢谢,这解决了我在同一个td上有多个日期的问题。 - deep_netprog

25

这是一篇旧文章,但希望能对其他遇到类似问题的人有所帮助。

在更新版本的DataTables中,bUseRenderedfnRender已经被弃用。

mRender是新的解决方法,具有略微不同的方法。

你可以使用以下方式解决你的问题:

...
{ mDataProp: "Date.Sort"
  bSortable: true, 
  sName: "Date", 
  // this will return the Display value for everything
  // except for when it's used for sorting,
  // which then it will use the Sort value
  mRender: function (data, type, full) {
    if(type == 'sort') return data.Sort;
    return data.Display
  }
}
...

确认。这个有效。所请求的调用数据类型 - 这将是“过滤器”、“显示”、“类型”或“排序”。还有人在使用datatables吗? - Jess
这是完美的答案!谢谢! - Eric Mill
现在已经不推荐使用iDataSort,因此被接受的答案是错误的,这个答案才是正确的。 - Tim Ogilvy
@Sebastianb,我已经使用数据表格有一段时间了。我感到困惑的是,所有旧的数据表格属性名称都采用匈牙利命名法。在一个数据表格版本中,匈牙利命名法被取消了。所有这些旧的文档使得情况非常混乱。 - Jess

20

嗯...不要再经过所有这些繁琐的步骤,直接在前面添加一个隐藏的 span 元素来显示你的“排序方式”:

<td><span style="display:none;">20101131133000</span>11/31/2010 1:30 PM</td>

注意:这意味着他们可以根据隐藏或显示的值进行搜索...这可能是您无法接受的后果。


我真的很喜欢这个解决问题的方案。 - rii
1
太厉害了!你刚刚帮我省了很多工作!虽然我已经在考虑这个方向,而且我尝试过一个HTML注释 <!-- sortvalue --> - 但是你的方法起作用了。 - Keith Grey

20

尝试一种略微不同的方法:

将两列都放入表格中(我将它们称为DateDisplay和DateSort),不使用渲染函数,只需隐藏DateSort列。然后在列DateDisplay的aoColumns数组中,放置{"iDataSort": 2},其中2是DateSort列的索引。

这样,DateDisplay列将显示原始数据,并且过滤将通过此列进行,但排序将通过DateSort列中的值进行。

有关iDataSort属性的更多详细信息,请参见datatables网站或http://www.codeproject.com/KB/scripting/JQuery-DataTables.aspx部分“配置排序”。


1
@CWSpear的答案更容易实现,我认为。 - Jess
2
此答案适用于传统数据表,现已被弃用。 - Tim Ogilvy

11

+1 JocaPC

我想补充一下JocaPC的答案,提醒大家JavaScript使用零索引数组。

例如:

HiddenSortString (0) | Date (1)                   | Some Text (2)
...................................................................
1349035566           | 2012年9月30日 下午2:06         | blah blah
1349118137           | 2012年10月1日 下午1:02         | blah blah
1349371297           | 2012年10月4日 上午11:21        | blah blah
...................................................................

要使用隐藏字符串排序日期字段,请使用以下代码:

$('.mytable').dataTable({
    "aoColumns": [{"bVisible": false},{"iDataSort": 0},null]
});

感谢JakeJ...为清理示例的CWSpear +1。 - Brian

5

在td上使用data-sort属性,例如:

<td data-sort="12342345434">Thursday, May 9th 11</td>

4

既然您已经有了可排序和可显示的数据格式,那么这就是您所需要的全部代码。

它将使用Date.Sort进行排序,使用Date.Display进行展示。这在此处有详细记录。

columns: [{
    data: 'Date',
    render: {
        _:   'Display',
        sort: 'Sort'
    }
}]

3

如果您使用ajax数据源,可以使用Orthogonal data。例如,在您的ajax响应中,将其中一列作为一个对象返回,包括一个显示值和一个排序值(类似于OP所做的):

{
   "data":[
      {
         "customer":"JOHN DOE",
         "rating":{
            "display": "★★★",
            "sort":"3"
         },
      },
      {
         "customer":"BILLY NOAH",
         "rating":{
            "display": "★★★★★",
            "sort":"5"
         },
      }
   ]
}

现在,在您的表选项中,您可以像这样使用columns()

"columns" : [
   {
      "data":"customer"
   },
   {
      "data":"rating",
      "render":{
         "_":"display",
         "sort":"sort"
      }
   }
]

0

你需要通过一个隐藏的列(Sort)来对列进行排序。为了实现这一点,你需要包含一个包含排序数据的列,隐藏该列,并通过隐藏的列对显示列进行排序。

   "aoColumnDefs:[
    {"sTitle": "Display", "iDataSort":1, "aTargets":[2]},
    {"bVisible": false, "aTargets":[2]}
    ], 

aoColumns: [
    { mData: "User" },
    { mData: "Display"},
    { mData: "Sort"}
  ]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接