Jquery filtering with multiple Checkboxes

前端 未结 2 925
小蘑菇
小蘑菇 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

    0 讨论(0)
  • 2021-02-03 17:01

    Here is a fork of the jsfiddle from billyonecan. Differences are...

    • An unchecked box means that property is excluded from results
    • All checkboxes are checked by default (all results shown)
    • At least one checkbox for each filter group must be checked
    • If a filter group does not submit a filter, all results are hidden
    • If a new filter group is added it will be automatically handled

      ( ( a||b||c ) && ( x||y||z ) && ( 1||2||3 )... )

    . jsFiddle

    var $filterCheckboxes = $('input[type="checkbox"]');
    
      // Read All Available Filter Groups
      var allFilters = [];
      $filterCheckboxes.each(function() {
      	if ($.inArray(this.name,allFilters) == -1){
        	allFilters.push(this.name);
        }  
      });
    //  console.log(allFilters); 
    
    
    
    
    
    
    $filterCheckboxes.on('change', function() {
    
      // create a collection containing all of the filterable elements
      var $filteredResults = $('.item');
    
    	var $filterCategoryApplied = 0;
      
      $.each(allFilters, function(arIndex, filterName) {
      // console.log(filterName); 
    	var $filterCheckboxCategory = $('input[name='+filterName+']').filter(':checked');
    	
      console.log(filterName + ' length = ' + $filterCheckboxCategory.length);
       
       if ( $filterCheckboxCategory.length === 0 ) {
    //    alert('none checked for ' + filterName);
        $filteredResults = [];
       }
      });
    
    
    
    
    console.log('start checking');
    
    
    
    	// Read Selectetd Filters
      var selectedFilters = {};
      $filterCheckboxes.filter(':checked').each(function() {
        if (!selectedFilters.hasOwnProperty(this.name)) {
          selectedFilters[this.name] = [];
        }
        selectedFilters[this.name].push(this.value);
      });
      
      
    
      
    
    
    
      // loop over the selected filter name -> (array) values pairs
      $.each(selectedFilters, function(name, filterValues) {
    
    //console.log(selectedFilters['fl-colour'].length); 
    //console.log(name); 
    //console.log(filterValues); 
    //console.log(filterValues.length); 
    
    
    
        // 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;
    
        });
      });
    
      $('.item').hide().filter($filteredResults).show();
    
    });
    body {
      font-family: 'Arial';
      color: #646464;
    }
    
    
    .items-wrap {
      float: left;
      width: 20%;
      margin: 0 3% 0 0;
      padding: 0;
      position: relative;
    }
    
    .items {
      float: left;
      width: 60%;
    }
    
    .items div.item {
      float: left;
      width: 45%;
      height: 28px;
      line-height: 38px;
      padding: 0 1%;
      background: #eee;
      margin: 0 0 1px;
      position: relative;
      font-size: 0.7em;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <pre id=result> </pre>
    
    <div class="items-wrap">
    
      <h3 style="font-size:13px; font-weight:normal;">Filter Items</h3>
      <p style="font-size:12px;"><strong>By colour:</strong></p>
      
      <form id='filters'>
        <label style="font-size:12px;">
          <input type="checkbox" name="fl-colour" value="red" id="red" checked /> Red</label>
        <br>
        <label style="font-size:12px;">
          <input type="checkbox" name="fl-colour" value="yellow" id="yellow" checked /> Yellow</label>
        <br>
        <label style="font-size:12px;">
          <input type="checkbox" name="fl-colour" value="green" id="green" checked /> Green</label>
    
        <p style="font-size:12px;"><strong>By size:</strong></p>
        <label style="font-size:12px;">
          <input type="checkbox" name="fl-size" value="small" id="small" checked /> Small</label>
        <br>
        <label style="font-size:12px;">
          <input type="checkbox" name="fl-size" value="medium" id="medium" checked /> Medium</label>
        <br>
        <label style="font-size:12px;">
          <input type="checkbox" name="fl-size" value="large" id="large" checked /> Large</label>
      
        <p style="font-size:12px;"><strong>By Shape:</strong></p>
        <label style="font-size:12px;">
          <input type="checkbox" name="fl-shape" value="square" id="square" checked /> Square</label>
        <br>
        <label style="font-size:12px;">
          <input type="checkbox" name="fl-shape" value="circle" id="circle" checked /> Circle</label>
        <br>
        <label style="font-size:12px;">
          <input type="checkbox" name="fl-shape" value="triangle" id="triangle" checked /> Triangle</label>
      </form>
    
    </div>
    
    
    
    <div class="items">
      <div class="item" data-id="rss" data-category="red small square">red small square</div>
      <div class="item" data-id="yss" data-category="yellow small square">yellow small square</div>
      <div class="item" data-id="gss" data-category="green small square">green small square</div>
      
      <div class="item" data-id="rms" data-category="red medium square">red medium square</div>
      <div class="item" data-id="yms" data-category="yellow medium square">yellow medium square</div>
      <div class="item" data-id="gms" data-category="green medium square">green medium square</div>
      
      <div class="item" data-id="rls" data-category="red large square">red large square</div>
      <div class="item" data-id="yls" data-category="yellow large square">yellow large square</div>
      <div class="item" data-id="gls" data-category="green large square">green large square</div>
    
    
    
    
    
    
    
      <div class="item" data-id="rsc" data-category="red small circle">red small circle</div>
      <div class="item" data-id="ysc" data-category="yellow small circle">yellow small circle</div>
      <div class="item" data-id="gsc" data-category="green small circle">green small circle</div>
      
      <div class="item" data-id="rmc" data-category="red medium circle">red medium circle</div>
      <div class="item" data-id="ymc" data-category="yellow medium circle">yellow medium circle</div>
      <div class="item" data-id="gmc" data-category="green medium circle">green medium circle</div>
      
      <div class="item" data-id="rlc" data-category="red large circle">red large circle</div>
      <div class="item" data-id="ylc" data-category="yellow large circle">yellow large circle</div>
      <div class="item" data-id="glc" data-category="green large circle">green large circle</div>
      
      
      
      
      
      <div class="item" data-id="rst" data-category="red small triangle">red small triangle</div>
      <div class="item" data-id="yst" data-category="yellow small triangle">yellow small triangle</div>
      <div class="item" data-id="gst" data-category="green small triangle">green small triangle</div>
      
      <div class="item" data-id="rmt" data-category="red medium triangle">red medium triangle</div>
      <div class="item" data-id="ymt" data-category="yellow medium triangle">yellow medium triangle</div>
      <div class="item" data-id="gmt" data-category="green medium triangle">green medium triangle</div>
      
      <div class="item" data-id="rlt" data-category="red large triangle">red large triangle</div>
      <div class="item" data-id="ylt" data-category="yellow large triangle">yellow large triangle</div>
      <div class="item" data-id="glt" data-category="green large triangle">green large triangle</div>  
      
    
    
    
    </div>

    0 讨论(0)
提交回复
热议问题