Parent filtering

Hey @Support-Luis,

I’m working on a website where I have this events list.
Since I want to separate each month, I’ve created 12 “month groups” each containing the same events collection list.

On page load, I’m using this script:

document.addEventListener("DOMContentLoaded", function () {
  const monthMap = {
    january: "01", february: "02", march: "03", april: "04", may: "05", june: "06",
    july: "07", august: "08", september: "09", october: "10", november: "11", december: "12",
  };

  const currentMonth = new Date().getMonth() + 1;
  const paddedCurrentMonth = currentMonth.toString().padStart(2, "0");

  document.querySelectorAll(".events_date-group").forEach((group) => {
    const groupMonthName = group.getAttribute("date-group")?.toLowerCase();
    const numericMonth = monthMap[groupMonthName];
    if (!numericMonth) return;

    // Remove past month groups
    if (parseInt(numericMonth) < parseInt(paddedCurrentMonth)) {
      group.remove();
      return;
    }

    // Set month name in empty state blocks
    group.querySelectorAll('.events_empty [data-el="month"]').forEach((span) => {
      span.textContent = groupMonthName.charAt(0).toUpperCase() + groupMonthName.slice(1);
    });

    // Remove events that do not belong to this group’s month
    group.querySelectorAll('.events_item[role="listitem"]').forEach((event) => {
      const eventMonthEl = event.querySelector('[data-el="event-month"]');
      if (!eventMonthEl) return;
      const eventMonth = eventMonthEl.textContent.trim();
      if (eventMonth !== numericMonth) event.remove();
    });

    // Remove the group if it's now empty
    const remaining = group.querySelectorAll('.events_item[role="listitem"]');
    if (remaining.length === 0) {
      group.remove();
    }
  });

  // Adjust attendance badges
  document.querySelectorAll('.events_item[role="listitem"]').forEach((event) => {
    const typeEl = event.querySelector('[fs-cmsfilter-field="type"]');
    const inPerson = event.querySelector('[data-el="in-person"]');
    const online = event.querySelector('[data-el="online"]');
    const type = typeEl?.textContent.trim().toLowerCase();

    if (type === "webinar") {
      inPerson?.remove();
    } else {
      online?.remove();
    }
  });
});

To map the events to the correct groups. I then hide any empty group.

Following the same logic, and taping into the Attributes API, I used this script:

window.fsAttributes = window.fsAttributes || [];

window.fsAttributes.push([
  'cmsfilter',
  (filterInstances) => {
    const allLists = filterInstances
      .flatMap(instance => instance.lists)
      .filter(Boolean);

    // === Listen for filter tag clicks
    const filterSpans = document.querySelectorAll(
      'span[fs-cmsfilter-field="type"], span[fs-cmsfilter-field="attendance"], span[fs-cmsfilter-field="location"]'
    );

    filterSpans.forEach((span) => {
      span.addEventListener('click', () => {
        const label = span.textContent?.trim();
        if (label) console.log(`🎯 Filter clicked: ${label}`);
      });
    });

    // === Watch Finsweet lifecycle events
    document.addEventListener('fs-cmsfilter-update', () => {
      setTimeout(updateMonthGroupVisibility, 50);
    });

    document.addEventListener('fs-cmsfilter-reset', () => {
      setTimeout(updateMonthGroupVisibility, 50);
    });
  }
]);

to hide/show empty month groups any time I filter. This has not been successful and would like your input on this to see if I’ve got something wrong.

Thanks in advance for your help!

Hey @joseph.bongrand! The issue seems to come from the event listeners attached to the document — I’m afraid we don’t dispatch the events you’re listening to, so the function to hide the empty months isn’t being triggered.

Instead, we can listen to the renderitems event. This is fired every time items are rendered on the page — whether filters are set or removed:

// All previous code stays the same, just add this instead of the event listeners
// === Watch Finsweet lifecycle events
const [filterInstance] = filterInstances;

filterInstance.listInstance.on('renderitems', (renderedItems) => {
  setTimeout(updateMonthGroupVisibility, 50);
});

If you’d like an alternative approach, you can try reverse nesting the events within the corresponding months, as shown in this guide:

1 Like

Hey @Support-Luis, that worked perfectly! Thanks a lot!

1 Like