I need make a filter by checkboxes, which will specify two or more options in one category. My filter filters one option in each category.
function change() {
let results = Array.from(document.querySelectorAll('.result > div'));
// Hide all results
results.forEach(function(result) {
result.style.display = 'none';
});
// Filter results to only those that meet ALL requirements:
Array.from(document.querySelectorAll('.filter input[rel]:checked'), function(input) {
const attrib = input.getAttribute('rel');
results = results.filter(function(result) {
return result.classList.contains(attrib);
});
});
// Show those filtered results:
results.forEach(function(result) {
result.style.display = 'block';
});
}
change();
<div class="filter">
<h1>Select models</h1>
<div class="checkbox">
<label><input type="checkbox" rel="apple" onchange="change()"/>Apple</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="samsung" onchange="change()"/>Samsung</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="xiaomi" onchange="change()"/>Xiaomi</label>
</div>
<h1>Select processors</h1>
<div class="checkbox">
<label><input type="checkbox" rel="a9" onchange="change()"/>A9</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="a8" onchange="change()"/>A8</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="snapdragon" onchange="change()"/>Snapdragon</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="exynos" onchange="change()"/>Exynos</label>
</div>
</div>
<div class="result">
<div class="apple a9">
<h1>iPhone 7</h1>
</div>
<div class="apple a8">
<h1>iPhone 6</h1>
</div>
<div class="samsung exynos">
<h1>Samsung s7</h1>
</div>
<div class="xiaomi snapdragon">
<h1>Xiaomi Redmi note 4x</h1>
</div>
</div>
I need make a filter by checkboxes, which will specify two or more options in one category. My filter filters one option in each category.
function change() {
let results = Array.from(document.querySelectorAll('.result > div'));
// Hide all results
results.forEach(function(result) {
result.style.display = 'none';
});
// Filter results to only those that meet ALL requirements:
Array.from(document.querySelectorAll('.filter input[rel]:checked'), function(input) {
const attrib = input.getAttribute('rel');
results = results.filter(function(result) {
return result.classList.contains(attrib);
});
});
// Show those filtered results:
results.forEach(function(result) {
result.style.display = 'block';
});
}
change();
<div class="filter">
<h1>Select models</h1>
<div class="checkbox">
<label><input type="checkbox" rel="apple" onchange="change()"/>Apple</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="samsung" onchange="change()"/>Samsung</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="xiaomi" onchange="change()"/>Xiaomi</label>
</div>
<h1>Select processors</h1>
<div class="checkbox">
<label><input type="checkbox" rel="a9" onchange="change()"/>A9</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="a8" onchange="change()"/>A8</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="snapdragon" onchange="change()"/>Snapdragon</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="exynos" onchange="change()"/>Exynos</label>
</div>
</div>
<div class="result">
<div class="apple a9">
<h1>iPhone 7</h1>
</div>
<div class="apple a8">
<h1>iPhone 6</h1>
</div>
<div class="samsung exynos">
<h1>Samsung s7</h1>
</div>
<div class="xiaomi snapdragon">
<h1>Xiaomi Redmi note 4x</h1>
</div>
</div>
So in result I cannot choose Apple and Samsung simultaneously. I can choose only one options in each group. It is like a radiobutton. But I need checkbox with multiply options
Share Improve this question edited Jan 18, 2018 at 7:06 Shyngys Rakhad asked Jan 18, 2018 at 6:54 Shyngys RakhadShyngys Rakhad 1962 gold badges4 silver badges16 bronze badges 5- Do you want to bine those filters (e.g: apple AND snapdragon) or just multiply them? (e.g: apple OR snapdragon) – flx Commented Jan 18, 2018 at 6:58
- @zeropublix I need to make a opportunity to choose more options in each group. For example, If I choose Samsung and Apple, as a result, nothing is shown, but need to be shown apple and samsung simultaneously. Could I explain my issue? – Shyngys Rakhad Commented Jan 18, 2018 at 7:01
- @Mr.Chingis what if you choose apple samsung and snapdragon?? Should the result be all the 4 phones or none(since samsung and apple does not have snapdragon)? – sanatsathyan Commented Jan 18, 2018 at 7:08
- @sanatsathyan none. Because choosen products have no snapdragons processor. If I choose apple samsung xiaomi and snapdragon, result should be only one phone xiaomi. Because from choosen phones, at least one phone has snapdragon, so result should be xiaomi – Shyngys Rakhad Commented Jan 18, 2018 at 7:12
- @Mr.Chingis did any of the Answers solve your question? then mark them as that please or a little "thanks" is appreciated as we took the effort to help you. – flx Commented Jan 18, 2018 at 10:30
2 Answers
Reset to default 5As I understand you (by reading the ments) You want to have the the following behaviour:
- The model or processor checkboxes are "OR" correlation inside their filter-group.
- But the phone has to be of any checked model and must have any of the checked processors.
This code should solve your issue/question:
function change() {
var modelCbs = document.querySelectorAll(".models input[type='checkbox']");
var processorCbs = document.querySelectorAll(".processors input[type='checkbox']");
var filters = {
models: getClassOfCheckedCheckboxes(modelCbs),
processors: getClassOfCheckedCheckboxes(processorCbs)
};
filterResults(filters);
}
function getClassOfCheckedCheckboxes(checkboxes) {
var classes = [];
if (checkboxes && checkboxes.length > 0) {
for (var i = 0; i < checkboxes.length; i++) {
var cb = checkboxes[i];
if (cb.checked) {
classes.push(cb.getAttribute("rel"));
}
}
}
return classes;
}
function filterResults(filters) {
var rElems = document.querySelectorAll(".result div");
var hiddenElems = [];
if (!rElems || rElems.length <= 0) {
return;
}
for (var i = 0; i < rElems.length; i++) {
var el = rElems[i];
if (filters.models.length > 0) {
var isHidden = true;
for (var j = 0; j < filters.models.length; j++) {
var filter = filters.models[j];
if (el.classList.contains(filter)) {
isHidden = false;
break;
}
}
if (isHidden) {
hiddenElems.push(el);
}
}
if (filters.processors.length > 0) {
var isHidden = true;
for (var j = 0; j < filters.processors.length; j++) {
var filter = filters.processors[j];
if (el.classList.contains(filter)) {
isHidden = false;
break;
}
}
if (isHidden) {
hiddenElems.push(el);
}
}
}
for (var i = 0; i < rElems.length; i++) {
rElems[i].style.display = "block";
}
if (hiddenElems.length <= 0) {
return;
}
for (var i = 0; i < hiddenElems.length; i++) {
hiddenElems[i].style.display = "none";
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div class="filter">
<h1>Select models</h1>
<div class="models">
<div class="checkbox">
<label><input type="checkbox" rel="apple" onchange="change();"/>Apple</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="samsung" onchange="change();"/>Samsung</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="xiaomi" onchange="change();"/>Xiaomi</label>
</div>
</div>
<h1>Select processors</h1>
<div class="processors">
<div class="checkbox">
<label><input type="checkbox" rel="a9" onchange="change();"/>A9</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="a8" onchange="change();"/>A8</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="snapdragon" onchange="change();"/>Snapdragon</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="exynos" onchange="change();"/>Exynos</label>
</div>
</div>
</div>
<div class="result">
<div class="apple a9">
<h1>iPhone 7</h1>
</div>
<div class="apple a8">
<h1>iPhone 6</h1>
</div>
<div class="samsung exynos">
<h1>Samsung s7</h1>
</div>
<div class="xiaomi snapdragon">
<h1>Xiaomi Redmi note 4x</h1>
</div>
</div>
</body>
try this,or you can see the demo ahead:https://jsfiddle/xianshenglu/gzs3fr7n/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content="height=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no" name="viewport">
<title>Document</title>
<style>
</style>
<!-- <script type="text/javascript" src="http://livejs./live.js"></script> -->
<!-- <script src="http://apps.bdimg./libs/jquery/2.1.4/jquery.min.js"></script> -->
<!-- <script src="test2.js"></script> -->
<script>
function change() {
let results = Array.from(document.querySelectorAll('.result > div')),
modelsChecked = document.querySelectorAll('.filter input.models:checked'),
processorsChecked = document.querySelectorAll('.filter input.processors:checked');
// Hide all results
results.forEach(function(result) {
result.style.display = 'none';
});
// Filter results to only those that meet ALL requirements:
filterModelsOrProcessors(modelsChecked);
if (processorsChecked.length != 0) {
filterModelsOrProcessors(processorsChecked);
}
function filterModelsOrProcessors(modelsOrProcessorsChecked) {
results = Array.from(modelsOrProcessorsChecked).reduce(function(sum, input) {
const attrib = input.getAttribute('rel');
return sum.concat(results.filter(function(result) {
return result.classList.contains(attrib);
}));
}, []);
}
// Show those filtered results:
results.forEach(function(result) {
result.style.display = 'block';
});
}
change();
</script>
</head>
<body>
<div class="filter">
<h1>Select models</h1>
<div class="checkbox">
<label>
<input type="checkbox" rel="apple" class="models" onchange="change()" />Apple</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" rel="samsung" class="models" onchange="change()" />Samsung</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" rel="xiaomi" class="models" onchange="change()" />Xiaomi</label>
</div>
<h1>Select processors</h1>
<div class="checkbox">
<label>
<input type="checkbox" rel="a9" class="processors" onchange="change()" />A9</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" rel="a8" class="processors" onchange="change()" />A8</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" rel="snapdragon" class="processors" onchange="change()" />Snapdragon</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" rel="exynos" class="processors" onchange="change()" />Exynos</label>
</div>
</div>
<div class="result">
<div class="apple a9">
<h1>iPhone 7</h1>
</div>
<div class="apple a8">
<h1>iPhone 6</h1>
</div>
<div class="samsung exynos">
<h1>Samsung s7</h1>
</div>
<div class="xiaomi snapdragon">
<h1>Xiaomi Redmi note 4x</h1>
</div>
</div>
</body>
</html>