Show only filters with results

Hi,
is there a way to use dynamic visibility to show a filter (checkbox) only if that filter has results? (given other active filters)

Hey @gianluca! Yes! We can hide or style filters with some extra JS, if you want, you can share a live link and I’ll help you out with the code :muscle:

https://bevande-cuni.webflow.io/catalogo-birre?Dark%20Lagers="true"

as an example, if i open this page pre-filtered for dark lagers i would like to hide other beer stiles (of course) but also “Fermentazione → Alta” because all the dark lagers have low fermentation.

thank you as always for your time

Hey @gianluca! Sorry for the delay, this code should achieve what you are looking for.

You can replace the CMS Filter callback you have under the CMS Nest one for this


window.fsAttributes.push([
    'cmsfilter',
    (filterInstances) => {
      const searchInput = document.querySelector('#global-field-textsearch');
      searchInput.dispatchEvent(new Event('input', { bubbles: true }));
      setTimeout(function () {
        filterInstances.forEach((filterInstance) => {
          function hideEmptyFilters() {
            const filtersData = filterInstance.filtersData;
            let resultsArray = [];

            filtersData.forEach(function (element) {
              const elements = element.elements;
              elements.forEach(function (element) {
                let filterValue = element.value;
                let resultsNumber = element.resultsCount;
                resultsArray.push({ filterName: filterValue, filterResults: resultsNumber });
              });
            });

            resultsArray.forEach(function (filter) {
              let elements = Array.from(document.querySelectorAll('[fs-cmsfilter-field]')).filter(
                function (element) {
                  return element.textContent.trim() === filter.filterName;
                }
              );

              elements.forEach(function (element) {
                let parentElement = element.parentElement;

                if (parentElement.tagName.toLowerCase() !== 'div') {
                  if (filter.filterResults === 0) {
                    parentElement.style.display = 'none';
                  } else {
                    parentElement.style.display = 'block';
                  }
                }
              });
            });
          }

          hideEmptyFilters();
          filterInstance.listInstance.on('renderitems', (renderedItems) => {
            hideEmptyFilters();
          });
        });
      }, 1000);
    },
  ]);

Please test it out and let me know how it goes!

1 Like

it’s working but it seems to slow down the filter, also there are multiple flickering like everything it’s refreshing multiple times, any tips?

well, to be fair only the wine page is this slow… the item count is similar to the spirits page, really cant say what’s the reason so maybe it’s not the script…

https://bevande-cuni.webflow.io/catalogo-vini
https://bevande-cuni.webflow.io/catalogo-spirits

I do not see any of these issues on my end :thinking:

Hi Luiss,

sorry for not giving fast feedback on the various task but we were sprinting to go live!

Now the site is live and we are about to share the results on the slack community, thank you so so so much for your help!

I’m replying here because we are experimenting an issue with the “hide filter snippet”

It is working on all the filters exception made for the “cantine”. here we have more than 100 record, at first i put 2 separate collection with limit 100, 1 and limit 100, 101 and it was working, now that the unused filters disappear the first limit returns element from the second collection and it shows as duplicate.

I added the cms-load (render-all) to the first collection and removed the second, removed the limit and tried to filter but at that point some element are not hidden (i suppose there’s a delay, even with render-all mode )

is there a way to fix that?

Any other way to accomplish this?

Thank you for your time

Hey @gianluca! We can try wrapping the CMS filter code within the CMS Load callback. So the code runs after all items are loaded.

Can you test this?

<script>
  window.fsAttributes = window.fsAttributes || [];
  window.fsAttributes.push([
    'cmsnest',
    (listInstances) => {
      console.log('cmsnest Successfully loaded!');
      window.fsAttributes.cmsfilter.init();
    },
  ]);

  window.fsAttributes.push([
    'cmsload',
    (listInstances) => {
      console.log('cmsload Successfully loaded!');
      window.fsAttributes.push([
        'cmsfilter',
        (filterInstances) => {
          const searchInput = document.querySelector('#global-field-textsearch');
          searchInput.dispatchEvent(new Event('input', { bubbles: true }));
          setTimeout(function () {
            filterInstances.forEach((filterInstance) => {
              function hideEmptyFilters() {
                const filtersData = filterInstance.filtersData;
                let resultsArray = [];

                filtersData.forEach(function (element) {
                  const elements = element.elements;
                  elements.forEach(function (element) {
                    let filterValue = element.value;
                    let resultsNumber = element.resultsCount;
                    resultsArray.push({
                      filterName: filterValue,
                      filterResults: resultsNumber,
                    });
                  });
                });

                resultsArray.forEach(function (filter) {
                  let elements = Array.from(
                    document.querySelectorAll('[fs-cmsfilter-field]')
                  ).filter(function (element) {
                    return element.textContent.trim() === filter.filterName;
                  });

                  elements.forEach(function (element) {
                    let parentElement = element.parentElement;

                    if (parentElement.tagName.toLowerCase() !== 'div') {
                      if (filter.filterResults === 0) {
                        parentElement.style.display = 'none';
                      } else {
                        parentElement.style.display = 'block';
                      }
                    }
                  });
                });
              }

              hideEmptyFilters();
              filterInstance.listInstance.on('renderitems', (renderedItems) => {
                hideEmptyFilters();
              });
            });
          }, 1000);
        },
      ]);
    },
  ]);
</script>

Hi Luiss!

i tried you new snippet but it’s not changing the behavior

https://bevande-cuni.webflow.io/catalogo-vini

here’s the implementation, am i doing it wrong? thanks

hi Luis,

i had to make some changes to the page so i duplicated it as a restricted page: https://www.bevandecuni.it/catalogo-vini-test-luis

the password is: luis