Introduction
Jquery datatable provides individual column filtering but not on group of columns. Moreover, we can only select one item from each column. This article actually demonstrates how we can leverage the column level filtering to create a custom filter that just works like Excel filter, i.e., user can type to filter items and those items will be slected on the main grid.
Background
This article uses Jquery Datatable
for the grid and filter API. Please have a look at the actual documentation here.
Using the Code
This code uses the basic initialization of Jquery Datatable with a static
Json dataset
. However, the dataset
can be pulled via a webservice easily and integrated.
Once the table is initailized, it calls configFilter
function with the desired column numbers passed as an input array. This function actually loops through the data of each column passed, and creates a filter dialog with individual data listed under one column.
Example: If the input array passed as [1,2], then it will create two filter popups/dialogs with the data of column 2 and column 3 (array is zero index based).
The actual source code is listed below:
function configFilter($this, colArray) {
setTimeout(function () {
var tableName = $this[0].id;
var columns = $this.api().columns();
$.each(colArray, function (i, arg) {
$('#' + tableName + ' th:eq(' + arg + ')').append
('<img src="http://www.icone-png.com/png/39/38556.png"
class="filterIcon" onclick="showFilter(event,\'' +
tableName + '_' + arg + '\')" />');
});
var template = '<div class="modalFilter">' +
'<div class="modal-content">' +
'{0}</div>' +
'<div class="modal-footer">' +
'<a href="#!"
onclick="clearFilter(this, {1}, \'{2}\');"
class=" btn left waves-effect waves-light">Clear</a>' +
'<a href="#!"
onclick="performFilter(this, {1}, \'{2}\');"
class=" btn right waves-effect waves-light">Ok</a>' +
'</div>' +
'</div>';
$.each(colArray, function (index, value) {
columns.every(function (i) {
if (value === i) {
var column = this, content = '<input type="text"
class="filterSearchText"
onkeyup="filterValues(this)" /> <br/>';
var columnName = $(this.header()).text().replace(/\s+/g, "_");
var distinctArray = [];
column.data().each(function (d, j) {
if (distinctArray.indexOf(d) == -1) {
var id = tableName + "_" + columnName + "_" + j;
content += '<div><input type="checkbox" value="' +
d + '" id="' + id + '"/>
<label for="' + id + '"> ' +
d + '</label></div>';
distinctArray.push(d);
}
});
var newTemplate = $(template.replace('{0}', content).replace
('{1}', value).replace('{1}', value).replace('{2}', tableName).replace
('{2}', tableName));
$('body').append(newTemplate);
modalFilterArray[tableName + "_" + value] = newTemplate;
content = '';
}
});
});
}, 50);
The filter actually looks like this:
Once the filters are initialized based upon the desired columns, the filter popups can be clicking the filter icons of the column header. User can now type in the textbox or click on the checkbox and press 'OK'. The filter will now be applied on the grid and matching rows will be selected. The 'Clear' button. The actual source code can be found out in the zipped folder.
function performFilter(node, i, tableId) {
var rootNode = $(node).parent().parent();
var searchString = '', counter = 0;
rootNode.find('input:checkbox').each(function (index, checkbox) {
if (checkbox.checked) {
searchString += (counter == 0) ? checkbox.value : '|' + checkbox.value;
counter++;
}
});
$('#' + tableId).DataTable().column(i).search(
searchString,
true, false
).draw();
rootNode.hide();
$('#mask').hide();
}
Conclusion
Currently, this does filtering upon group of columns with the records filtered from selected columns. We can easily extend it to support cascading filter (the column filters only contain the data filtered by other active filters if any).