jquery - 如何按类别限制过滤结果?
问题描述
如下图所示,我有一个复选框过滤器,可根据类别过滤项目。除了我试图找出一种方法来限制过滤结果以显示仅与检查的类别匹配的项目之外,这可以实现我想要的功能
例如,如果选中“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>
解决方案
好吧,你应该做几件事:
- 把你
selectedFilters
变成一个Set
var selectedFilters = new Set();
- 然后填充集合
$filterCheckboxes.filter(':checked').each(function() {
selectedFilters.add(this.value)
});
- 然后用于
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>
推荐阅读
- reactjs - importing image with es6 import or require during runtime
- ios - 当用户快速滚动表格视图时如何隐藏和取消隐藏导航栏?
- react-native - Realm in React Native - TypeError while not using JS Debugging
- php - Remove XML Node from a file loaded using PHP filesystem
- apache-spark - spark Listner OnApplicationEnd event stops only Driver, executors are not getting cleaned up
- r - How to transform a Document Term Matrix in R?
- arrays - 如何使用线段树在未排序数组的范围内查找两个最小数字和一个最大数字?
- java - Apache Flink:如何处理多字段记录?
- swift - 如何在 UICollectionViewCell 中使用图像数组 swift 4 制作翻转动画
- c# - 如何在 EF Core 中调用 ThenInclude 两次?