首页 > 解决方案 > 如何按类别限制过滤结果?

问题描述

如下图所示,我有一个复选框过滤器,可根据类别过滤项目。除了我试图找出一种方法来限制过滤结果以显示仅与检查的类别匹配的项目之外,这可以实现我想要的功能

例如,如果选中“A”和“B”,则仅显示具有这些类别的项目,并排除任何不完全匹配的项目。目前它显示检查的每个类别

// CHECKBOX FILTER
var $filterCheckboxes = $('input[type="checkbox"]');
var filterFunc = function() {
  
  var selectedFilters = {};

  $filterCheckboxes.filter(':checked').each(function() {

    if (!selectedFilters.hasOwnProperty(this.name)) {
      selectedFilters[this.name] = [];
    }

    selectedFilters[this.name].push(this.value);
  });

  // create a collection containing all of the filterable elements
  var $filteredResults = $('.box');

  // loop over the selected filter name -> (array) values pairs
  $.each(selectedFilters, function(name, filterValues) {

    // filter each .animal element
    $filteredResults = $filteredResults.filter(function() {

      var matched = false,
        currentFilterValues = $(this).data('category').split(' ');

      // loop over each category value in the current input tag 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 input tag element is returned
      return matched;

    });
  });

  $('.box').hide().filter($filteredResults).show();
}

$filterCheckboxes.on('change', filterFunc);



let label = document.getElementsByTagName('label');
let cboxes = document.querySelectorAll("input");
cboxes.forEach(check => check.addEventListener("change", grayout.bind(null,check)))

function grayout(box) {

   if(!Array.from(cboxes).some(checkbox => checkbox.checked)) return cboxes.forEach(checkbox => checkbox.parentElement.style.color = "#000");
   cboxes.forEach(checkbox => {
      if(checkbox.checked) return checkbox.parentElement.style.color = "#000";
      checkbox.parentElement.style.color = "#808080";
   });
}


  $('.uncheck').click(function() {
    $('input[type="checkbox"]:checked').prop('checked',false);
    $('.project-tag').show();
    
    cboxes.forEach(checkbox => {
      checkbox.parentElement.style.color = "#000";
   });
  });
input {
  display:inline-block;
}
label {
  display:block;
}
section {
  display:flex;
  flex-direction: row;
  flex-wrap:wrap;
}
.box {
  background:#000;
  width:100px;
  height:80px;
  margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div>
  <label><input type="checkbox" value="a" id="a"/>A</label>
  <label><input type="checkbox" value="b" id=""/>B</label>
  <label><input type="checkbox" value="c" id=""/>C</label>
  <label><input type="checkbox" value="d" id=""/>D</label>
  <label><input type="checkbox" value="e" id=""/>E</label>
  <label><input type="checkbox" value="f" id=""/>F</label>
</div>
<button type="button" class="uncheck btn">Clear All</button>
<br><br>
<section>
  <div class="box" data-category="a"></div>
  <div class="box" data-category="b"></div>
  <div class="box" data-category="c b"></div>
  <div class="box" data-category="d"></div>
  <div class="box" data-category="e"></div>
  <div class="box" data-category="f a"></div>
  <div class="box" data-category="a"></div>
  <div class="box" data-category="b"></div>
  <div class="box" data-category="c d"></div>
</section>

标签: jquery

解决方案


好吧,你应该做几件事:

  1. 把你selectedFilters变成一个Set
var selectedFilters = new Set();
  1. 然后填充集合
  $filterCheckboxes.filter(':checked').each(function() {
    selectedFilters.add(this.value)
  });
  1. 然后用于Array.prototype.every计算您的匹配条件
var matched = [...selectedFilters].every(i => currentFilterValues.includes(i))

// CHECKBOX FILTER
var $filterCheckboxes = $('input[type="checkbox"]');

var filterFunc = function() {
var selectedFilters = new Set();

  $filterCheckboxes.filter(':checked').each(function() {
    selectedFilters.add(this.value)
  });

  // create a collection containing all of the filterable elements
  var $filteredResults = $('.box').filter(function() {
    var currentFilterValues = $(this).data('category').split(' ');
    var matched = [...selectedFilters].every(i => currentFilterValues.includes(i))
    // if matched is true the current input tag element is returned
    return matched;
  });

  $('.box').hide().filter($filteredResults).show();
}

$filterCheckboxes.on('change', filterFunc);



let label = document.getElementsByTagName('label');
let cboxes = document.querySelectorAll("input");
cboxes.forEach(check => check.addEventListener("change", grayout.bind(null, check)))

function grayout(box) {

  if (!Array.from(cboxes).some(checkbox => checkbox.checked)) return cboxes.forEach(checkbox => checkbox.parentElement.style.color = "#000");
  cboxes.forEach(checkbox => {
    if (checkbox.checked) return checkbox.parentElement.style.color = "#000";
    checkbox.parentElement.style.color = "#808080";
  });
}


$('.uncheck').click(function() {
  $('input[type="checkbox"]:checked').prop('checked', false);
  $('.project-tag').show();

  cboxes.forEach(checkbox => {
    checkbox.parentElement.style.color = "#000";
  });
});
input {
  display: inline-block;
}

label {
  display: block;
}

section {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.box {
  background: #000;
  width: 100px;
  height: 80px;
  margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div>
  <label><input type="checkbox" value="a" id="a"/>A</label>
  <label><input type="checkbox" value="b" id=""/>B</label>
  <label><input type="checkbox" value="c" id=""/>C</label>
  <label><input type="checkbox" value="d" id=""/>D</label>
  <label><input type="checkbox" value="e" id=""/>E</label>
  <label><input type="checkbox" value="f" id=""/>F</label>
</div>
<button type="button" class="uncheck btn">Clear All</button>
<br><br>
<section>
  <div class="box" data-category="a"></div>
  <div class="box" data-category="b"></div>
  <div class="box" data-category="c b"></div>
  <div class="box" data-category="d"></div>
  <div class="box" data-category="e"></div>
  <div class="box" data-category="f a"></div>
  <div class="box" data-category="a"></div>
  <div class="box" data-category="b"></div>
  <div class="box" data-category="c d"></div>
</section>


推荐阅读