Reputation: 2935
In my requirement, I have to filter data by expert area. Each row could have one or more expert areas, if it is more then values will be stored in comma separated.
First I tried to filter data using following way,
$(document).ready(function() {
$('#example').DataTable({
initComplete: function () {
this.api().columns(1).every( function () {
var column = this;
var select = $('<select class="form-control"><option value="">Select All</option></select>')
.appendTo( $('#expert').empty().append('<label>Filter by Expert Area:</label>') )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex($(this).val());
column.search(val).draw();
} );
var nameArr = ['Accounting', 'Audit', 'IT', 'Finance', 'Tax'];
nameArr.forEach(function(number) {
var optionExists = ($("#language option[value='"+number+"']").length > 0);
select.append( '<option value="'+number+'">'+number+'</option>' );
});
});
}
});
} );
Then I had faced issue to filter data for exact word, for example if I select "IT" from the dropdown, I got following results,
As you can see, even "Audit" row was filtered for "IT" keyword. Therefore I tried to filter result by exact word.
To do that I changed column.search().draw()
function like below,
column.search("(^"+val+"$)",true,false).draw();
But then column search can not identify comma separated values, Someone please explain how could I do that?
Running code jsfiddle
Upvotes: 2
Views: 1558
Reputation: 171690
You can create a custom search function that extends the built in defaults and then just call draw()
in a change event listener
demoInit()
function filterSearch(settings, data, dataIndex) {
const filterVal = $('#filter').val();
if (!filterVal) {
return true;
}
const arr = data[1].split(',').map(v => v.trim());
return arr.includes(filterVal);
}
// extend the search functions
$.fn.dataTable.ext.search.push(filterSearch);
var table = $('#example').DataTable();
$('#filter').change(function() {
table.draw();
});
function demoInit() {
var nameArr = ['Accounting', 'Audit', 'IT', 'Finance', 'Tax'];
$('#filter').append(nameArr.map(v => new Option(v, v)));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.24/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.js"></script>
<select id="filter">
<option value=""> -- Filter --</option>
</select>
<table id="example" class="def-table1" cellspacing="0" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Key Areas</th>
</tr>
</thead>
<tbody>
<tr>
<td>One</td>
<td>Accounting, Tax</td>
</tr>
<tr>
<td>Two</td>
<td>IT, Tax</td>
</tr>
<tr>
<td>Three</td>
<td>Audit</td>
</tr>
</tbody>
</table>
Upvotes: 0
Reputation: 11975
You can pass "(^|, )" + val + "(,|$)"
to the search to solve this.
Note: Need to check if val is empty then show all rows.
column.search(val ? "(^|, )" + val + "(,|$)" : "", true, false).draw();
Upvotes: 2