在 TR 数据属性上过滤 jquery 数据表

Filtering a jquery datatable on a TR data-attribute

我有一个与 .

相似但不同的查询

不同之处在于我试图按行而不是列上的数据属性进行过滤。 tr 元素,而不是 td 元素。这包含一个主键,我正在尝试删除重复项。重复行在实际列数据中可能不同,所以我不能那样做。键是由下划线分隔的三个数字字段的组合。

<tr data-primarykey="12345678_12_34"><td>... 

然后,在页面加载时调用的 javascript 函数中...

  var rows = [];
  $.fn.DataTable.ext.search.push(
    function( settings, data, dataIndex, rowObj, counter ) {
      if(counter === 0) rows = [];

      // I want rowkey to be the data-primarykey attribute of the tr element
      var rowkey = table.row(dataIndex).data('primarykey');

      // If we've seen the row before (already in the array), filter it out.
      // Otherwise, return true and add it to the array
      if ($.inArray(rowkey,rows) > -1) return false;
      else {
        rows.push(rowkey);
        return true;
      }
    }
  );

我怀疑部分问题是 table 对象没有在任何地方定义。此过滤器适用于多个 table,因此如果可能,它需要是当前正在过滤的任何 table。每个 table 都有一个独特的 id,但共享一个 class 属性。

更新2016/12/12

我在使用实际数据属性的版本上取得了一些进展。这个版本有一个有效的 table DataTable 对象,我认为正确地获取了行并将其转换为 jquery。但是,尝试获取 undefined.

中的数据属性结果
$.fn.DataTable.ext.search.push(
    function( settings, data, dataIndex, rowObj, counter ) {
      if(counter === 0) rowkeys = [];

      // I want rowkey to be the data-primarykey attribute of the tr element
      var tableID = $(settings.nTable).attr("id");
      var table = $('#'.tableID).DataTable(); // Correct DataTable
      //var row = table.rows(dataIndex).nodes().to$(); // Correct row?
      var rowkey = table.rows(dataIndex).nodes().to$().data("primarykey");
      console.log('key: '+rowkey); // Shows 'key: undefined' in console.

      // If we've seen the row before (already in the array), filter it out.
      // Otherwise, return true and add it to the array
      if ($.inArray(rowkey,rowkeys) > -1) return false;
      else {
        rowkeys.push(rowkey);
        return true;
      }
    }
  );   

我的调试工作受到了我的 ajax 函数的阻碍,该函数仅将返回的行添加到 table 中,如果它们在结果中检测到 <tr> 则重新绘制。但是,由于我现在将开口更改为 <tr data-primarykey="...">,它永远不会匹配,永远不会重新绘制行,因此永远不会调用过滤器函数。

修复此问题后,我开始收到错误消息 Requested unknown parameter '10' for row 0. 查看 DataTables documentation on this error 让我 none 变得更聪明。

我做了一个解决方法,允许我在不使用 data- 属性的情况下过滤键。我为键在数据 table 中添加了一个额外的列,并为该列的 thtd 元素提供了具有 display: none;css 样式。然后我像这样过滤了此列中的重复项...

var rowkeys = [];

$.fn.DataTable.ext.search.push(
    function( settings, data, dataIndex, rowObj, counter ) {
      if(counter === 0) rowkeys = [];
      // I want rowkey to be the data-primarykey attribute of the tr element
      var rowkey = data[11] || '';

      // If we've seen the row before (already in the array), filter it out.
      // Otherwise, return true and add it to the array
      if ($.inArray(rowkey,rowkeys) > -1) return false;
      else {
        rowkeys.push(rowkey);
        return true;
      }
    }
);

虽然这个答案已经解决了我的问题,并且对于试图做类似事情的人来说可能是一个很好的解决方法,但我不会将其标记为已接受的答案,因为我认为这个问题的正确答案是能够在 tr.

中使用 data-attribute 的人

This filter is applying to multiple tables, so it would need to be whatever table is currently being filtered, if possible. Each table has a unique id, but share a class attribute.

您需要进行 if 检查以限制您的过滤器仅在指定的 table 上工作。

 if (settings.nTable.id === "yourTableId" || settings.nTable.id === "anotherTableId") { 

 }

您还可以在 class

上进行 if 检查
if ($(settings.nTable).hasClass('yourClass')) { 

}

// I want rowkey to be the data-primarykey attribute of the tr element

您可以在回调中使用 settings 变量并结合使用 counter 变量。

所以你需要做的就是让这条线

var rowkey = $(settings.aoData[counter].nTr).data('primarykey');

这是我使用此过滤器逻辑的 Working example

注意:上面的例子有一个静态的HTML table,我认为这不是问题,因为我们更专注于filter 逻辑。此外,只有当您在搜索框中输入内容时,过滤器才会起作用。

所以最终逻辑如下所示

var rows = [];

$.fn.dataTableExt.afnFiltering.push(
  function(settings, data, dataIndex, rowObj, counter) {
    if (settings.nTable.id === "yourTableId") {   // change (1)
      if (counter === 0) rows = [];

      // I want rowkey to be the data-primarykey attribute of the tr element
      var rowkey = $(settings.aoData[counter].nTr).data('primarykey'); // change (2)

      // If we've seen the row before (already in the array), filter it out.
      // Otherwise, return true and add it to the array
      if ($.inArray(rowkey, rows) > -1) return false;
      else {
        rows.push(rowkey);
        return true;
      }
    }
  }
);