Hey everyone @Diony_Betrisey, @user14644, @Camilla_Dalgaard
Here is the revised code (custom Tag filter) from our devs, that should be added to the Custom JS section on the Settings tab of your widget’s settings:
//Change filter name here
const DEFAULT_FILTER_LABEL = "TAGS";
const DEFAULT_FILTER_VALUE = "all";
const waitForElement = (selector, root = document) => new Promise(res => {
let i = 0;
const check = () => {
const component = root.querySelector(selector);
if (component) {
res(component);
} else if (i !== 50) {
setTimeout(check, 100);
i++;
}
};
check();
});
waitForElement(".eapp-events-calendar-events-calendar-component").then((widget) => {
const select = document.createElement('select');
select.id = "es-custom-filter";
select.classList.add('eapp-events-calendar-controls-item');
select.classList.add('eapp-events-calendar-filter');
select.classList.add('eapp-events-calendar-filter-current');
// Add default option to the filter
const defaultOption = document.createElement('option');
defaultOption.value = DEFAULT_FILTER_VALUE;
defaultOption.text = DEFAULT_FILTER_LABEL;
select.appendChild(defaultOption);
// Get all tags on the page
const tags = [...widget.querySelectorAll('.eapp-events-calendar-tags-item')];
// Add tags to the filter list
const addedTags = [];
const addTags = (tag) => {
const trimmedTag = tag.innerText?.trim();
if (!trimmedTag || addedTags.includes(trimmedTag)) {
return;
}
const option = document.createElement('option');
option.value = trimmedTag;
option.text = trimmedTag;
select.appendChild(option);
addedTags.push(trimmedTag);
};
tags.forEach(addTags);
// Place the filter after the other ones
let filterContainer = widget.querySelector('.eapp-events-calendar-controls-component');
if (!filterContainer) {
let header = widget.querySelector(".eapp-events-calendar-events-calendar-header");
if (!header) {
header = document.createElement("div");
header.classList.add("eapp-events-calendar-events-calendar-header");
widget.prepend(header);
}
filterContainer = document.createElement("div");
filterContainer.classList.add("eapp-events-calendar-controls-component");
header.append(filterContainer);
}
filterContainer.appendChild(select);
const filterEvents = (event) => {
const selectedTag = select.value.toLowerCase();
// Look if event has selected tag
const eventTags = [...event.querySelectorAll(".eapp-events-calendar-tags-item")];
const match = eventTags.some((tag) => tag.textContent?.toLowerCase() === selectedTag);
// Show/Hide the events
if (match || selectedTag === DEFAULT_FILTER_VALUE) {
event.style.display = 'flex';
return;
}
event.style.display = 'none';
};
// Add event listener when filter selected
const eventsContainer = widget.querySelector(".eapp-events-calendar-list-events, .eapp-events-calendar-grid-component");
const callback = (mutationList) => mutationList.forEach(({ type, addedNodes }) => {
if (type !== 'childList' || !addedNodes.length) {
return;
}
addedNodes.forEach(filterEvents);
});
const observer = new MutationObserver(callback);
const refilter = () => {
observer.disconnect();
const selectedTag = select.value.toLowerCase();
// Met à jour le texte du filtre sélectionné
if (selectedTag !== DEFAULT_FILTER_VALUE) {
select.options[0].text = "All"; // Change the first option when a filter is selected
} else {
select.options[0].text = DEFAULT_FILTER_LABEL;
}
// Get all events on the page
let events = [...widget.querySelectorAll("[class*='eapp-events-calendar-'][class$='-item-component']")];
const isGrid = events?.[0].classList.contains("eapp-events-calendar-grid-item-component");
if (isGrid) {
events = events.map(event => event.parentNode);
}
events.forEach(filterEvents);
observer.observe(eventsContainer, { childList: true });
};
select.addEventListener('change', refilter);
document.addEventListener("click", (event) => {
if (event.target.closest(".eapp-events-calendar-filter-item")) {
refilter();
}
});
});
Note: We’ve managed to make it work in combination with other filters, but it’s usable for List and Grid layouts only.
In this video, you can see the feature in action:
Feel free to test it out
@Diony_Betrisey Once again, thanks a million for such a valuable input, that’s highly appreciated!