For a current project I am creating a simple product catalogue which should be able to be filtered by Jquery with several sets of checkboxes.
In one single set when tw
Your current approach isn't very dynamic, selectors and arrays are being hardcoded, so each time you add new filter options you'll have to add code to handle it.
Instead, just bind a change handler to all filter checkboxes, you can collect up their values, and group them by their respective names, eg:
var $filterCheckboxes = $( '.filter-checkboxes' );
$filterCheckboxes.on( 'change', function() {
var selectedFilters = {};
$filterCheckboxes.filter( ':checked' ).each( function() {
if ( ! selectedFilters.hasOwnProperty( this.name ) ) {
selectedFilters[ this.name ] = [];
}
selectedFilters[ this.name ].push( this.value );
} );
} );
This will create an object containing input-name -> value array
pairs, eg:
selectedFilters = {
'fl-colour': [ 'red', 'green' ],
'fl-size': [ 'tiny' ]
};
You can then loop over each selectedFilters
, and filter your .flower
elements. If a .flower
element matches a value in each named set, we return true so that the element is included in the $filteredResults
collection:
// create a collection containing all of the filterable elements
var $filteredResults = $( '.flower' );
// loop over the selected filter name -> (array) values pairs
$.each( selectedFilters, function( name, filterValues ) {
// filter each .flower element
$filteredResults = $filteredResults.filter( function() {
var matched = false,
currentFilterValues = $( this ).data( 'category' ).split( ' ' );
// loop over each category value in the current .flower's data-category
$.each( currentFilterValues, function( _, currentFilterValue ) {
// if the current category exists in the selected filters array
// set matched to true, and stop looping. as we're ORing in each
// set of filters, we only need to match once
if ( $.inArray( currentFilterValue, filterValues) != -1 ) {
matched = true;
return false;
}
} );
// if matched is true the current .flower element is returned
return matched;
} );
} );
Then simply hide all the .flower
elements, and show the $filteredResults
, eg:
$( '.flower' ).hide().filter( $filteredResults ).show();