Reputation: 8970
Preface:
I am working on a function to allow a user to choose data points to filter a table by. Each table row has 3 attributes associated with it, Title
, Department
, and Location
.
There are three multi-select filter options on the page that allow the user to narrow their search down by selecting 1 or more filter options by each of the fields.
As those options are selected, it triggers a function to adjust the table and only show the rows with data that matches their filter.
The Problem:
Since my function contains a loop that checks each of the filter options independently, its hiding/showing rows in order which is causing problems. For example if it was supposed to show the first row in the table because the filter told it to, the next filter says to only show rows that matches its filter, ignoring the ones before it.
What I have Tried:
I attempted to build the function in a way where it hides all the rows to start and then if the attribute of the table row was contained in our filter, it shows the row. This works for the first filter but as it iterates over the rows and hits the other filters, it hides them when it shouldn't be.
Ideal Solution:
Looking for a way to clean up this function where it applies the filter logic all at once and not in order by the function call. If I choose Austin
as my location, it will show rows that have the attribute location=austin
. If I then select a department
in the filters, it needs to apply both the location and department filter to the table.
Code Sample:
// Filters our user groups based on selections
function filterUserGroups(){
// Define our vars
var locationsFilter = $('[name=in_ugLocationsFilter]').val(),
departmentsFilter = $('[name=in_ugDepartmentsFilter]').val(),
titlesFilter = $('[name=in_ugTitlesFilter]').val(),
tempLocation = '',
tempDepartment = '',
tempTitle = '';
// Loop over our rows and show the data that matches our filters
$('[name=userGroupsRows] tr').hide();
$('[name=userGroupsRows] tr').each(function(){
// Get the current vars of each row
tempLocation = $(this).data('location');
tempDepartment = $(this).data('department');
tempTitle = $(this).data('title');
// Do we have any filter options selected?
if(locationsFilter || departmentsFilter || titlesFilter){
// If the location is in our filter, show row
if(jQuery.inArray(tempLocation, locationsFilter) != -1) {
$(this).show();
}
// If the departmentis in our filter, show row
if(jQuery.inArray(tempDepartment, departmentsFilter) != -1) {
$(this).show();
}
// If the title is in our filter, show row
if(jQuery.inArray(tempTitle, titlesFilter) != -1) {
$(this).show();
}
}
})
}
Fiddle: https://jsfiddle.net/p4xvgLo1/1/
Upvotes: 3
Views: 1247
Reputation: 10746
Because you hide everything I would also add a check so that if all the filters are empty everything is shown (locationsFilter==null && departmentsFilter==null && titlesFilter==null)
and then I'd change data-department="Global Financial Services 2"
to not have a space so it's the same as the filter name: data-department="Global Financial Services2"
.
if (locationsFilter || departmentsFilter || titlesFilter) {
// If the location is in our filter, show row
if (jQuery.inArray(tempLocation, locationsFilter) != -1 || (locationsFilter==null&&departmentsFilter==null&&titlesFilter==null)) {
$(this).show();
}
// If the location is in our filter, show row
if (jQuery.inArray(tempDepartment, departmentsFilter) != -1|| (locationsFilter==null&&departmentsFilter==null&&titlesFilter==null)) {
$(this).show();
}
// If the location is in our filter, show row
if (jQuery.inArray(tempTitle, titlesFilter) != -1|| (locationsFilter==null&&departmentsFilter==null&&titlesFilter==null)) {
$(this).show();
}
Edited fiddle: https://jsfiddle.net/3c3vjfhz/1/
Upvotes: 0
Reputation: 548
EDITED: Try with this:
var show = false;
if (locationsFilter) {
if (jQuery.inArray(tempLocation, locationsFilter) != -1) {
show = true;
}
}
if (!show && departmentsFilter) {
if (jQuery.inArray(tempDepartment, departmentsFilter) != -1) {
show = true;
}
}
if (!show && titlesFilter) {
if (jQuery.inArray(tempTitle, titlesFilter) != -1) {
show = true;
}
}
if (show) $(this).show();
See the edited fiddle: https://jsfiddle.net/p4xvgLo1/7/
Upvotes: 1