I have a webpage with some divs displayed. There are some filters used on a webshop to filter specific items. Now I want to display the message "no results" if all divs have display:none
.
How could I do that?
I tried some stuff like:
if ($('filters')(':visible').length == 0) {
document.textContent('No results');
}
but that doesn't work.
const buttons = document.querySelectorAll('.btn');
const composers = document.querySelectorAll('.filterDiv');
buttons.forEach((btn) =>
btn.addEventListener('click', (e) => {
e.target.classList.toggle('active');
filterSelection();
}),
);
function filterSelection() {
const filters = [...document.querySelectorAll('.btn.active')].map(
(el) => el.dataset.filter,
);
composers.forEach(
(c) =>
(c.style.display =
filters.length === 0 || c.matches(`.${filters.join('.')}`) ?
'block' :
'none'),
);
}
<div id="filters">
<div id="myBtnContainer">
<p>Period</p>
<button data-filter="Barok" >Barok</button>
<button data-filter="Classic" >Classic</button>
<button data-filter="Renaissance" >Renaissance</button>
<button data-filter="Romantic" >Romantic</button>
</div>
<div id="myBtnContainer">
<p>Composer</p>
<button data-filter="DiLasso" >De Lassus</button>
<button data-filter="Bach" >Bach</button>
<button data-filter="Vivaldi" >Vivaldi</button>
<button data-filter="Schubert" >Schubert</button>
<button data-filter="Tchaikovsky" >Tchaikovsky</button>
</div>
</div>
<div id="myUL">
<div >Di Lasso -Lagrime de San Pietro</div>
<div >Sweelinck - Fantasie</div>
<div >Haydn - The Seasons</div>
<div >Wagner - Parsifal</div>
<div >Mozart - Requiem</div>
<div >Bach - Magnificat</div>
<div >Beethoven - Symphony 5</div>
<div >Händel - Hallelujah</div>
<div >Vivaldi - The Four Seasons</div>
<div >Obrecht - Factor Orbis</div>
<div >Schubert - Erlkönig</div>
<div >Tchaikovsky - Swan Lake</div>
<div >Vivaldi - Rosmira</div>
<div >Beethoven - Moonlight Sonata</div>
</div>
CodePudding user response:
You can use a class to control your hidden elements by .filterDiv.hidden
(if elements are hidden, they will have a class hidden
).
This approach needs to have styles with CSS
.hidden {
display: none;
}
const buttons = document.querySelectorAll('.btn');
const composers = document.querySelectorAll('.filterDiv');
buttons.forEach((btn) =>
btn.addEventListener('click', (e) => {
e.target.classList.toggle('active');
filterSelection();
}),
);
function filterSelection() {
const filters = [...document.querySelectorAll('.btn.active')].map(
(el) => el.dataset.filter,
);
composers.forEach((c) => {
if (filters.length === 0 || c.matches(`.${filters.join('.')}`)) {
c.classList.remove("hidden")
} else {
c.classList.add("hidden")
}
});
const hiddenComposers = document.querySelectorAll('.filterDiv.hidden');
const noResultElement = document.getElementById("noResult");
if (composers.length === hiddenComposers.length) {
noResultElement.classList.remove("hidden");
} else {
noResultElement.classList.add("hidden");
}
}
.hidden {
display: none;
}
<div id="filters">
<div id="myBtnContainer">
<p>Period</p>
<button data-filter="Barok" >Barok</button>
<button data-filter="Classic" >Classic</button>
<button data-filter="Renaissance" >Renaissance</button>
<button data-filter="Romantic" >Romantic</button>
</div>
<div id="myBtnContainer">
<p>Composer</p>
<button data-filter="DiLasso" >De Lassus</button>
<button data-filter="Bach" >Bach</button>
<button data-filter="Vivaldi" >Vivaldi</button>
<button data-filter="Schubert" >Schubert</button>
<button data-filter="Tchaikovsky" >Tchaikovsky</button>
</div>
</div>
<div id="myUL">
<div >Di Lasso -Lagrime de San Pietro</div>
<div >Sweelinck - Fantasie</div>
<div >Haydn - The Seasons</div>
<div >Wagner - Parsifal</div>
<div >Mozart - Requiem</div>
<div >Bach - Magnificat</div>
<div >Beethoven - Symphony 5</div>
<div >Händel - Hallelujah</div>
<div >Vivaldi - The Four Seasons</div>
<div >Obrecht - Factor Orbis</div>
<div >Schubert - Erlkönig</div>
<div >Tchaikovsky - Swan Lake</div>
<div >Vivaldi - Rosmira</div>
<div >Beethoven - Moonlight Sonata</div>
</div>
<div id="noResult" >No result</div>
CodePudding user response:
All you need to do is to listen to a mutation of the document. then just do normal counting logic for those which are set to displaynone
const buttons = document.querySelectorAll('.btn');
const composers = document.querySelectorAll('.filterDiv');
buttons.forEach((btn) =>
btn.addEventListener('click', (e) => {
e.target.classList.toggle('active');
filterSelection();
}),
);
function filterSelection() {
const filters = [...document.querySelectorAll('.btn.active')].map(
(el) => el.dataset.filter,
);
composers.forEach(
(c) =>
(c.style.display =
filters.length === 0 || c.matches(`.${filters.join('.')}`)
? 'block'
: 'none'),
);
}
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var observer = new MutationObserver(function(mutations, observer) {
// fired when a mutation occurs
let filtersCount = [...$('.filterDiv')].length;
let filtersNoneCount = [...$('.filterDiv')].filter((f,i) => {return f.style.display === "none"}).length;
if(filtersCount === filtersNoneCount){
$(document.body).html('No results');
}
});
observer.observe(document, {
subtree: true,
attributes: true
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="filters">
<div id="myBtnContainer">
<p>Period</p>
<button data-filter="Barok" >Barok</button>
<button data-filter="Classic" >Classic</button>
<button data-filter="Renaissance" >Renaissance</button>
<button data-filter="Romantic" >Romantic</button>
</div>
<div id="myBtnContainer">
<p>Composer</p>
<button data-filter="DiLasso" >De Lassus</button>
<button data-filter="Bach" >Bach</button>
<button data-filter="Vivaldi" >Vivaldi</button>
<button data-filter="Schubert" >Schubert</button>
<button data-filter="Tchaikovsky" >Tchaikovsky</button>
</div>
</div>
<div id="myUL">
<div >Di Lasso -Lagrime de San Pietro</div>
<div >Sweelinck - Fantasie</div>
<div >Haydn - The Seasons</div>
<div >Wagner - Parsifal</div>
<div >Mozart - Requiem</div>
<div >Bach - Magnificat</div>
<div >Beethoven - Symphony 5</div>
<div >Händel - Hallelujah</div>
<div >Vivaldi - The Four Seasons</div>
<div >Obrecht - Factor Orbis</div>
<div >Schubert - Erlkönig</div>
<div >Tchaikovsky - Swan Lake</div>
<div >Vivaldi - Rosmira</div>
<div >Beethoven - Moonlight Sonata</div>
</div>