Home > Mobile >  How can I show the message "no results" when all divs are hidden?
How can I show the message "no results" when all divs are hidden?

Time:11-04

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>

more docs

  • Related