I'm using DataTables, and added some custom dropdowns for filtering that have values of <tr>
data attributes. Everything I've read mentions how to filter by data attributes to <td>
. I'm not sure how to implement this as I'm not incredibly familiar with DataTables.
Created a Fiddle: https://jsfiddle.net/pegues/4bw5s0gd/1/
HTML:
<select id="custom-select-filter-1">
<option value="">Please select filter 1...</option>
<option value="one">One</option>
<option value="two">Two</option>
<option value="three">Three</option>
</select>
<select id="custom-select-filter-2">
<option value="">Please select filter 2...</option>
<option value="four">Four</option>
<option value="five">Five</option>
<option value="six">Six</option>
</select>
<table id="example">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Category</th>
</tr>
</thead>
<tbody>
<tr data-testattribute1="one" data-testattribute2="four">
<td>1</td>
<td>Apples</td>
<td>Fruit</td>
</tr>
<tr data-testattribute1="two" data-testattribute2="five">
<td>2</td>
<td>Oranges</td>
<td>Fruit</td>
</tr>
<tr data-testattribute1="three" data-testattribute2="six">
<td>3</td>
<td>Lexus</td>
<td>Cars</td>
</tr>
<tr data-testattribute1="one" data-testattribute2="five">
<td>4</td>
<td>Winchester</td>
<td>Guns</td>
</tr>
</tbody>
</table>
JavaScript:
$(document).ready(function(){
$('#example').DataTable({
order: [[1, 'Name']],
});
$('#custom-select-filter-1').on('change', function(){
var selectVal = $(this).val();
console.log(selectVal);
});
$('#custom-select-filter-2').on('change', function(){
var selectVal = $(this).val();
console.log(selectVal);
});
});
I've reviewed the DataTables documentation, but do not understand how I could filter based on data attributes for rows, not column cells.
E.g., if one
is selected from the first dropdown, then show all rows with the match as in <tr data-testattribute1="one">
. If the first dropdown is one
and the second dropdown is five
, then show all <tr data-testattribute1="one" data-testattribute2="five">
, and hide all other rows.
Any help is appreciated.
You can create a custom filter for this using the DataTables search plugin
$.fn.dataTable.ext.search.push(function (settings, data, dataIndex)
This defines your filter conditions and pushes that function onto an array of filter functions used by DataTables whenever the data is redrawn (triggered by a user action such as paging, sorting, and filtering).
In your case the logic would be something like the following:
$.fn.dataTable.ext.search.push(function (settings, data, dataIndex) {
var trNode = settings.aoData[dataIndex].nTr;
var attr1 = trNode.getAttribute("data-testattribute1");
var attr2 = trNode.getAttribute("data-testattribute2");
var val1 = $('#custom-select-filter-1').val();
var val2 = $('#custom-select-filter-2').val();
if ( (val1 === "" || val1 === attr1)
&& (val2 === "" || val2 === attr2) ) {
return true;
}
return false;
});
You can access the <tr>
node for the DataTable data row via the table's settings object: settings.aoData[dataIndex].nTr
.
From there, it's a matter of getting the attributes and comparing them to the user inputs. An empty string (empty input) means "no filter".
Here is a runnable demo:
$.fn.dataTable.ext.search.push(function (settings, data, dataIndex) {
var trNode = settings.aoData[dataIndex].nTr;
var attr1 = trNode.getAttribute("data-testattribute1");
var attr2 = trNode.getAttribute("data-testattribute2");
var val1 = $('#custom-select-filter-1').val();
var val2 = $('#custom-select-filter-2').val();
if ( (val1 === "" || val1 === attr1)
&& (val2 === "" || val2 === attr2) ) {
return true;
}
return false;
});
$(document).ready(function(){
var table = $('#example').DataTable({
order: [[1, 'Name']],
});
$('#custom-select-filter-1').on('change', function(){
table.draw();
});
$('#custom-select-filter-2').on('change', function(){
table.draw();
});
});
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.0.js"></script>
<script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
</head>
<body>
<div style="margin: 20px;">
<select id="custom-select-filter-1">
<option value="">Please select filter 1...</option>
<option value="one">One</option>
<option value="two">Two</option>
<option value="three">Three</option>
</select>
<select id="custom-select-filter-2">
<option value="">Please select filter 2...</option>
<option value="four">Four</option>
<option value="five">Five</option>
<option value="six">Six</option>
</select>
<table id="example">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Category</th>
</tr>
</thead>
<tbody>
<tr data-testattribute1="one" data-testattribute2="four">
<td>1</td>
<td>Apples</td>
<td>Fruit</td>
</tr>
<tr data-testattribute1="two" data-testattribute2="five">
<td>2</td>
<td>Oranges</td>
<td>Fruit</td>
</tr>
<tr data-testattribute1="three" data-testattribute2="six">
<td>3</td>
<td>Lexus</td>
<td>Cars</td>
</tr>
<tr data-testattribute1="one" data-testattribute2="five">
<td>4</td>
<td>Winchester</td>
<td>Guns</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Note the use of table.draw();
to trigger the re-draw; and note that the table
variable has been added to the code which creates the DataTable, to support the draw()
call:
var table = $('#example').DataTable({ ...