document.querySelectorAll('[data-control]').forEach(item => {
item.addEventListener('click', event => {
event.preventDefault();
handleFilterItems(item);
});
});
function handleFilterItems(filterItem) {
if (filterItem.getAttribute('data-control') === '' || filterItem.getAttribute('data-control') === '.all') {
document.querySelectorAll('[data-control]').forEach(item => {
item.classList.remove('_active');
});
} else {
document.querySelector('[data-control=".all"]').classList.remove('_active');
}
if (filterItem.classList.contains('_active')) {
filterItem.classList.remove('_active');
// check if no other filter item is active
if (!document.querySelectorAll('[data-control]._active').length) {
document.querySelector('[data-control=".all"]').classList.add('_active');
}
} else {
filterItem.classList.add('_active');
}
handleFilterTeaser();
}
function handleFilterTeaser() {
document.querySelectorAll('.all').forEach(item => {
item.classList.add('_hidden');
});
if (document.querySelectorAll('[data-control]._active').length === 0) {
document.querySelectorAll('.all').forEach(item => {
item.classList.remove('_hidden');
});
} else {
document.querySelectorAll('[data-control]._active').forEach(item => {
let filterTag = item.getAttribute('data-control');
document.querySelectorAll(filterTag).forEach(tag => {
tag.classList.remove('_hidden');
});
});
}
}
ul,
li {
list-style: none;
display: inline-block;
}
button {
padding: 10px;
}
button:hover {
color: green;
}
button._active {
color: tomato;
}
.list>div {
background: grey;
margin-bottom: 10px;
color: #fff;
padding: 10px;
}
._hidden {
display: none;
}
.show-choice {
width: max-content;
border: 1px solid red;
padding: 10px;
margin: 0 0 20px;
}
._hidden {
display: none;
}
.show-choice {
width: max-content;
border: 1px solid red;
padding: 10px;
margin: 0 0 20px
}
<div>
<ul>
<li>
<button data-control=".all">all</button>
</li>
<li>
<button data-control=".a">a</button>
</li>
<li>
<button data-control=".b">b</button>
</li>
<li>
<button data-control=".c">c</button>
</li>
</ul>
<div >
<div id="choice">
<span>a 1, b 2, a b 3, b 4, a 5, c 6</span>
</div>
</div>
</div>
<div >
<div >a 1</div>
<div >b 2</div>
<div >a b 3</div>
<div >b 4</div>
<div >a 5</div>
<div >c 6</div>
</div>
When the page loads, all elements are shown (the <div id="choice">
field also shows all the options) When we select the display of certain data in the "choise" field, only the selected one should be displayed; if the selection is canceled, everything returns to its original state.
https://codepen.io/slagrach/pen/YzjQMOw
CodePudding user response:
The way to achieve this with minimal changes is to modify the function handleFilterTeaser()
to collect the text values of all selected elements, and then join them into a string and assign them to the element with id choise
.
function handleFilterTeaser() {
let values = [];
document.querySelectorAll('.all').forEach(item => {
item.classList.add('_hidden');
});
if (document.querySelectorAll('[data-control]._active').length === 0) {
document.querySelectorAll('.all').forEach(item => {
item.classList.remove('_hidden');
values.push(item.innerHTML);
});
} else {
document.querySelectorAll('[data-control]._active').forEach(item => {
let filterTag = item.getAttribute('data-control');
document.querySelectorAll(filterTag).forEach(tag => {
tag.classList.remove('_hidden');
values.push(tag.innerHTML);
});
});
}
document.querySelector('#choise').innerHTML = values.join(', ');
}
https://codepen.io/Urnix/pen/GRBEVGj
Update: The above implementation allows duplicate items in #choise
element. I would recommend rewriting the code like this:
document.querySelectorAll('[data-control]').forEach((button, index) => {
button.addEventListener('click', event => {
event.preventDefault();
handleFilterItems(index);
});
});
function handleFilterItems(buttonIndex) {
// Array of filters
const filters = [...document.querySelectorAll('[data-control]')];
// Array of names of active filters
let activeFilterNames = filters
.filter(function (button) {
return button.classList.contains('_active');
})
.map(function (button) {
return button.innerHTML;
});
// Toggle clicked
const clickedFilterName = filters[buttonIndex].innerHTML;
if (activeFilterNames.includes(clickedFilterName)) {
activeFilterNames = activeFilterNames.filter(f => f !== clickedFilterName);
} else {
activeFilterNames.push(clickedFilterName);
}
if (clickedFilterName === 'all') {
// Turn off the rest filters if `All` clicked
activeFilterNames = ['all'];
} else {
// Turn off `all` if haven any other
const activeFilterNamesWithoutItemNamedAll = activeFilterNames.filter(f => f !== 'all');
activeFilterNames = activeFilterNamesWithoutItemNamedAll.length ? activeFilterNamesWithoutItemNamedAll : ['all'];
}
// Add or remove `_active` class for each button
filters.forEach(function (f, i) {
if (activeFilterNames.includes(f.innerHTML)) {
document.querySelectorAll('[data-control]')[i].classList.add('_active');
} else {
document.querySelectorAll('[data-control]')[i].classList.remove('_active');
}
});
handleFilterTeaser(activeFilterNames);
}
function handleFilterTeaser(filters) {
const values = [];
document.querySelectorAll('.all').forEach(tag => {
// Add or remove `_hidden` class for each item
if (
[...tag.classList].find(function (clazz) {
return filters.includes(clazz);
})
) {
tag.classList.remove('_hidden');
// Collect visible items for display in `#choise` element
values.push(tag.innerHTML);
} else {
tag.classList.add('_hidden');
}
});
document.querySelector('#choise').innerHTML = values.join(', ');
}