I have a query that is similar, but not the same as, this question.
The difference is I'm trying to filter by a data attribute on the row rather than the column. The tr
element, not the td
element. This contains a primary key and I'm trying to remove duplicates. Duplicate rows may differ in actual column data, so I can't do it that way. The key is a combination of three numeric fields separated by underscores.
<tr data-primarykey="12345678_12_34"><td>...
Then, inside a javascript
function called on page load...
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;
}
}
);
I suspect that part of the problem is that table
object not being defined anywhere. 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.
Update 2016/12/12
I have made some progress with a version that uses the actual data attributes. This version has a working table
DataTable object and I think correctly gets the row and converts it to jquery. However, attempting to get the data-attribute results in 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;
}
}
);
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.
You need to have a if
check to limit your filter to work on only specified tables.
if (settings.nTable.id === "yourTableId" || settings.nTable.id === "anotherTableId") {
}
you can also do the if
check on class
if ($(settings.nTable).hasClass('yourClass')) {
}
// I want rowkey to be the data-primarykey attribute of the tr element
You can get that with in the settings
variable in the callback and using the counter
variable too in combination.
So all you need to do is to have this line
var rowkey = $(settings.aoData[counter].nTr).data('primarykey');
Here is a Working example where I use this filter logic.
Note: The above example has a static HTML table which I think is not a problem as we are more concentrated on the filter
logic. Also the filter works only when you type in something in the search box.
So the final logic would look like below
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;
}
}
}
);