Jquery filtering with multiple Checkboxes

前端 未结 2 926
小蘑菇
小蘑菇 2021-02-03 16:08

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

2条回答
  •  离开以前
    2021-02-03 16:45

    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();
    

    Here's an example fiddle

提交回复
热议问题