Problem:
I have a scenario where I want to apply multiple range filters on a jquery data table. Like, first filter is for filtering between certain range of days for which I have dropdown containing certain days values and another one will search between certain selected dates from the date picker. I’m using $.fn.dataTable.ext.search.push(function(settings, data, dataIndex))
to push the range of values for searching in table. These both filters are working fine together until I clear any one of it. I am using $.fn.dataTable.ext.search.pop()
to pop the applied filters but it is all the search results and not just the specific one.
How can i solve this issue?
Here is my code:
- For filtering between days range:
var filterTableByRange = (searchUptoDays, columnIndex) => {
if(searchUptoDays) {
$.fn.dataTable.ext.search.push(function( settings, data, dataIndex ) {
var min = 0;
var max = parseInt(searchUptoDays);
var totalTransDays = parseInt(data[columnIndex]) || 0; // use data for the age column
if ( ( isNaN( min ) && isNaN( max ) ) ||
( isNaN( min ) && totalTransDays <= max ) ||
( min <= totalTransDays && isNaN( max ) ) ||
( min <= totalTransDays && totalTransDays <= max ) )
{
return true;
}
return false;
});
homePageDataTable.draw();
} else {
var dateFrom = $('#' + portlet_namespace + 'dateFrom').val();
var dateTo = $('#' + portlet_namespace + 'dateTo').val();
if(dateFrom && dateTo) {
filterTablesWithinDates();
}
$.fn.dataTable.ext.search.pop();
homePageDataTable.draw();
}
};
- For filtering between Dates:
var filterTablesWithinDates = () => {
var dateFrom = $('#' + portlet_namespace + 'dateFrom').val();
var dateTo = $('#' + portlet_namespace + 'dateTo').val();
if(dateFrom === '' || dateTo === '') {
$.fn.dataTable.ext.search.pop();
var filterByDays = $('#' + portlet_namespace + 'filter_by_days').val();
if(filterByDays) {
filterTableByRange(filterByDays, 10);
}
homePageDataTable.draw();
return;
}
var min = new Date(dateFrom);
var max = new Date(dateTo);
if(min > max) {
alert('Date From must be smaller than Date To.');
return;
}
$.fn.dataTable.ext.search.push(function( settings, data, dataIndex ) {
let date = new Date(data[3]); // use data for the age column
if (min <= date && date <= max) {
return true;
}
return false;
});
homePageDataTable.draw();
};
Solution:
In order to manage multiple filters, you need to keep track of which filters are currently active and pop only the specific filter that needs to be removed. Here is an example code for doing this:
// Define an array to store the filter functions
var filterFunctions = [];
var filterTableByRange = (searchUptoDays, columnIndex) => {
// Remove any existing filter functions for this filter
filterFunctions = filterFunctions.filter(fn => fn !== filterByRange);
if (searchUptoDays) {
filterFunctions.push(filterByRange(searchUptoDays, columnIndex));
}
applyFilters();
};
// Function to create the filter function for days range
var filterByRange = (searchUptoDays, columnIndex) => {
return function(settings, data, dataIndex) {
var min = 0;
var max = parseInt(searchUptoDays);
var totalTransDays = parseInt(data[columnIndex]) || 0;
if ((isNaN(min) && isNaN(max)) ||
(isNaN(min) && totalTransDays <= max) ||
(min <= totalTransDays && isNaN(max)) ||
(min <= totalTransDays && totalTransDays <= max)) {
return true;
}
return false;
};
};
var filterTablesWithinDates = () => {
// Remove any existing filter functions for this filter
filterFunctions = filterFunctions.filter(fn => fn !== filterWithinDates);
var dateFrom = $('#' + portlet_namespace + 'dateFrom').val();
var dateTo = $('#' + portlet_namespace + 'dateTo').val();
if (dateFrom && dateTo) {
filterFunctions.push(filterWithinDates(dateFrom, dateTo));
}
applyFilters();
};
var filterWithinDates = (dateFrom, dateTo) => {
return function(settings, data, dataIndex) {
let date = new Date(data[3]);
if (min <= date && date <= max) {
return true;
}
return false;
};
};
var applyFilters = () => {
// Remove any previously added search functions
$.fn.dataTable.ext.search.pop();
// Push all active filter functions into the DataTable
filterFunctions.forEach(fn => {
$.fn.dataTable.ext.search.push(fn);
});
// Draw the table
homePageDataTable.draw();
};