I have Datatables filtering records with checkboxes. The problem is that if a column has 2 values within it, then the checkbox filter does not find the row.
For example, there are 3 checkboxes for 'Call', 'Meeting' and 'Email'. If a row in the table has values of 'Call' AND 'Email', if you then want to filter by 'Email', this row doesn't display. It can't see it because it doesn't just say 'Email'. It says 'Call Email'
$(document).ready(function() {
$.fn.dataTable.ext.search.push(
function(settings, searchData, index, rowData, counter) {
var positions = $('input:checkbox[name="pos"]:checked').map(function() {
return this.value;
}).get();
if (positions.length === 0) {
return true;
}
if (positions.indexOf(searchData[1]) !== -1) {
return true;
}
return false;
}
);
$.fn.dataTable.ext.search.push(
function(settings, searchData, index, rowData, counter) {
var offices = $('input:checkbox[name="ofc"]:checked').map(function() {
return this.value;
}).get();
if (offices.length === 0) {
return true;
}
if (offices.indexOf(searchData[2]) !== -1) {
return true;
}
return false;
}
);
var table = $('#example').DataTable();
$('input:checkbox').on('change', function() {
table.draw();
});
});
body {
font: 90%/1.45em "Helvetica Neue", HelveticaNeue, Verdana, Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
color: #333;
background-color: #fff;
}
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
<div >
<hr>
<div id="position">
<input type="checkbox" name="pos" value="Call">Call
<input type="checkbox" name="pos" value="Meeting">Meeting
<input type="checkbox" name="pos" value="Email">Email
</div>
<hr>
<div id="ofice">
<input type="checkbox" name="ofc" value="GBP">GBP
<input type="checkbox" name="ofc" value="EUR">EUR
<input type="checkbox" name="ofc" value="USD">USD
</div>
<hr>
<table id="example" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Currency</th>
<th>Age</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Name</th>
<th>Type</th>
<th>Currency</th>
<th>Age</th>
</tr>
</tfoot>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>Call</td>
<td>GBP</td>
<td>61</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Meeting</td>
<td>USD</td>
<td>63</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Call</td>
<td>GBP</td>
<td>66</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Meeting</td>
<td>GBP</td>
<td>22</td>
</tr>
<tr>
<td>Jenna Elliott</td>
<td>Call</td>
<td>USD GBP</td>
<td>33</td>
</tr>
<tr>
<td>Brielle Williamson</td>
<td>Call Email</td>
<td>GBP USD</td>
<td>61</td>
</tr>
<tr>
<td>Herrod Chandler</td>
<td>Meeting</td>
<td>EUR</td>
<td>59</td>
</tr>
<tr>
<td>Rhona Davidson</td>
<td>Email</td>
<td>GBP</td>
<td>55</td>
</tr>
<tr>
<td>Colleen Hurst</td>
<td>Email Meeting</td>
<td>EUR</td>
<td>39</td>
</tr>
</tbody>
</table>
</div>
http://live.datatables.net/qeqezali/1/edit
CodePudding user response:
You Need to make separation of that string for individual checking.
Please check below JS Code for Example:
$(document).ready( function () {
$.fn.dataTable.ext.search.push(
function( settings, searchData, index, rowData, counter ) {
var positions = $('input:checkbox[name="pos"]:checked').map(function() {
return this.value;
}).get();
if (positions.length === 0) {
return true;
}
var searchDataStr = searchData[1].split(" ");
var row_status = false;
$(searchDataStr).each(function(kk, vv){
if (positions.indexOf(vv) !== -1) {
row_status = true;
}
})
if(row_status == true){
return true;
}
return false;
}
);
$.fn.dataTable.ext.search.push(
function( settings, searchData, index, rowData, counter ) {
var offices = $('input:checkbox[name="ofc"]:checked').map(function() {
return this.value;
}).get();
if (offices.length === 0) {
return true;
}
if (offices.indexOf(searchData[2]) !== -1) {
return true;
}
return false;
}
);
var table = $('#example').DataTable();
$('input:checkbox').on('change', function () {
table.draw();
});
} );
CodePudding user response:
The issue in your code is because you're looking for an absolute match of 'X' in a string which can contain 'X Y Z'. As such you need to alter your logic.
One way to do this would be to create an array from the values in the Datatable cell and then compare this to the array of checked radio buttons. If there are matches, display that row.
In addition, the two calls to $.fn.dataTable.ext.search
can be combined to make the logic slightly more succinct.
Finally, note that jQuery 1.11.3 is rather outdated. I updated the example to use the latest version of jQuery - 3.6.0 at the time of writing.
jQuery($ => {
$.fn.dataTable.ext.search.push((_, searchData) => {
let positions = $('input:checkbox[name="pos"]:checked').map((i, el) => el.value).get();
let offices = $('input:checkbox[name="ofc"]:checked').map((i, el) => el.value).get();
const posMatches = positions.filter(p => searchData[1].split(' ').includes(p));
const ofcMatches = offices.filter(o => searchData[2].split(' ').includes(o));
return posMatches.length > 0 || ofcMatches.length > 0 || (positions.length == 0 && offices.length == 0);
});
var table = $('#example').DataTable();
$('input:checkbox').on('change', function() {
table.draw();
});
});
body {
font: 90%/1.45em "Helvetica Neue", HelveticaNeue, Verdana, Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
color: #333;
background-color: #fff;
}
<script src="http://code.jquery.com/jquery-3.6.0.min.js"></script>
<link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
<div >
<hr>
<div id="position">
<input type="checkbox" name="pos" value="Call">Call
<input type="checkbox" name="pos" value="Meeting">Meeting
<input type="checkbox" name="pos" value="Email">Email
</div>
<hr>
<div id="ofice">
<input type="checkbox" name="ofc" value="GBP">GBP
<input type="checkbox" name="ofc" value="EUR">EUR
<input type="checkbox" name="ofc" value="USD">USD
</div>
<hr>
<table id="example" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Currency</th>
<th>Age</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Name</th>
<th>Type</th>
<th>Currency</th>
<th>Age</th>
</tr>
</tfoot>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>Call</td>
<td>GBP</td>
<td>61</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Meeting</td>
<td>USD</td>
<td>63</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Call</td>
<td>GBP</td>
<td>66</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Meeting</td>
<td>GBP</td>
<td>22</td>
</tr>
<tr>
<td>Jenna Elliott</td>
<td>Call</td>
<td>USD GBP</td>
<td>33</td>
</tr>
<tr>
<td>Brielle Williamson</td>
<td>Call Email</td>
<td>GBP USD</td>
<td>61</td>
</tr>
<tr>
<td>Herrod Chandler</td>
<td>Meeting</td>
<td>EUR</td>
<td>59</td>
</tr>
<tr>
<td>Rhona Davidson</td>
<td>Email</td>
<td>GBP</td>
<td>55</td>
</tr>
<tr>
<td>Colleen Hurst</td>
<td>Email Meeting</td>
<td>EUR</td>
<td>39</td>
</tr>
</tbody>
</table>
</div>