On this site, the user needs to select activities and locations. I’m using CMS Filter to filter the activities available by Location and Type.
Here’s my problem.
I want to reset my second (Activity) filter to nothing selected when my main filter (Location) is changes. The Activity option should be reset every time you change to a new Location.
So any method to reset the filter and clear the dropdown would solve my problem.
Things I’ve tried.
I tried removing the query param from the URL but this doesn’t appear to change the filter when my javascript changes the URL.
I’ve tried triggering a click on the dropdown item and then closing it with js but this doesn’t seem to work on mobile.
Webflow discussion on closing dropdowns
You can see this working here on desktop, but it won’t work on mobile:
Working on desktop
Steps to recreate my problem:
- Select a Location
- Select an activity
- Select a different Location (Activity should be reset / cleared)
- Doesn’t work on mobile
Read Only Link:
Hey @jon.burdon! I see what you are trying to do, and I think there may be a simpler approach.
If you read the CMS Filter API documentation you’ll see we have this method
/**
* Resets the active filters.
* @param filterKey If passed, only this filter key will be resetted.
* @param value If passed, only that specific value and the elements that hold it will be cleared.
*/
resetFilters(filterKeys?: string[], value?: string): Promise<void>;
So you should be able to do
filterInstance.resetFilters(['IDENTIFIER']);
Where IDENTIFIER
is the filter you wish to clear.
Could you try incorporating this into your code? I don’t want to risk breaking anything important that you have already achieved aside from the resetting of the dropdowns.
Thanks. I added the following code and linked it to a button which you can see on the page. This seems to make no difference when clicked.
document.getElementById('reset-button').addEventListener('click', function() {
console.log("Reset Filter 2");
filterInstance.resetFilters(['activity']);
});
If you inspect the console you’ll find the next error
VM14:9 Uncaught ReferenceError: filterInstance is not defined
at HTMLAnchorElement.<anonymous> (VM14:9:5)
This is because filterInstance
is not yet defined. I have slightly modified the code to wrap it in the CMS Filter callback function.
Can you test this again with the new code?
<script>
window.fsAttributes = window.fsAttributes || [];
window.fsAttributes.push([
'cmsfilter',
(filterInstances) => {
console.log('cmsfilter Successfully loaded!');
const [filterInstance] = filterInstances;
const { listInstance } = filterInstance;
document.getElementById('reset-button').addEventListener('click', function () {
console.log('Reset Filter 2');
filterInstance.resetFilters(['activity']);
});
// var filtermonitor = "Filtering is available";
var filtermonitor = false;
console.log(filtermonitor);
function createEventListeners() {
console.log('Creating Event Listeners');
/**/
/* Add Event Listener to dropdowns * SHOULD be only when CMSfiltering has changed the dom */
document.querySelectorAll('[activity-dropdown-item="true"]').forEach((item) => {
item.addEventListener('click', function () {
document.getElementById('filter-results-dropdown').classList.remove('hide');
});
});
document.querySelectorAll('[data-location-item="true"]').forEach((item) => {
item.addEventListener('click', function () {
/* Reset Secondary Filter every time the first dropdown is used */
console.log('Reset Dropdown 2');
document.querySelectorAll('[activity-dropdown-item="true"]').forEach((item) => {
if (item.textContent.trim() === 'Select Activity') {
/* Click the blank 'Select Activity' item*/
//item.click();
item.click();
console.log(item);
/* Close the dropdown */
//document.getElementById("secondary-filter-toggle").click();
/* Hide the filter results */
//document.getElementById('filter-results-dropdown').classList.add('hide');
const dropdownToggle = document.querySelector('#secondary-filter-toggle');
//if (dropdownToggle.classList.contains('w--open')) {
if (dropdownToggle) {
dropdownToggle.dispatchEvent(new Event('mousedown'));
setTimeout(() => {
//dropdownToggle.dispatchEvent(new Event('mousedown'));
dropdownToggle.dispatchEvent(new Event('mouseup'));
}, 10); // A short delay ensures that events are distinguished
}
}
});
});
});
/* Hide Filters id Secondary Filter selects 'Select Activity'. If it contains 'Golf' then transform it to a dropdown */
document.querySelectorAll('[activity-dropdown-item="true"]').forEach((item) => {
item.addEventListener('click', function () {
console.log('Secondary filter clicked');
console.log(item.textContent);
if (item.textContent.trim() === 'Select Activity') {
console.log('Select Selected');
document.getElementById('filter-results-dropdown').classList.add('hide');
}
if (item.textContent.trim() === 'Golf') {
console.log('Golf Selected');
/*Change the results appearance into a Dropdown*/
transformGolf();
} else {
resetGolf();
}
});
});
}
function transformGolf() {
document.getElementById('go-button').classList.add('is-inactive');
document.getElementById('filter-results-dropdown').classList.remove('is-normalview');
document.getElementById('filter-results-toggle').classList.remove('is-normalview');
document.getElementById('filter-results-list').classList.remove('is-normalview');
document.getElementById('filter-results-dropdown').classList.remove('hide');
document.getElementById('go-button').classList.remove('hide');
}
function resetGolf() {
document.getElementById('go-button').classList.add('hide');
document.getElementById('filter-results-dropdown').classList.add('is-normalview');
document.getElementById('filter-results-toggle').classList.add('is-normalview');
document.getElementById('filter-results-list').classList.add('is-normalview');
}
function handleDropdownUpdateClick() {
const secondaryfilter = document.getElementById('activity-selector');
secondaryfilter.classList.remove('is-inactive');
/*Unhide all Activity dropdowns*/
const ele_var = document.querySelectorAll('[activity-dropdown-item="true"]');
ele_var.forEach((element) => {
element.classList.remove('hide');
});
// Step 1: Get the text from the element with data-target-heading="true"
let targetHeadingElement = document.querySelector('[data-target-heading="true"]');
if (targetHeadingElement) {
let currentLocation = targetHeadingElement.innerText;
// Step 2: Make an alert with the value stored in currentLocation
/*
alert(currentLocation);
*/
// Step 3: Find an element with activity-checker="true" and check if activity-checker-name matches currentLocation. Hide elements that match.
let activityChecker = Array.from(
document.querySelectorAll('[activity-checker="true"]')
).find((element) => element.getAttribute('activity-checker-name') === currentLocation);
if (activityChecker) {
// Step 4: Inside the activity-checker element, find the element with the class 'w-dyn-items'
let dynItems = activityChecker.querySelector('.w-dyn-items');
if (dynItems) {
// Get all child elements and log the value of their activity-checker-item attribute
let items = dynItems.querySelectorAll('[activity-checker-item]');
items.forEach((item) => {
let locationSelect = document.getElementById('location-selector');
let elements = locationSelect.querySelectorAll('[activity-dropdown-item]');
// console.log(locationSelect);
// Iterate through each element
elements.forEach((element) => {
if (element.textContent.trim() === item.getAttribute('activity-checker-item')) {
// Add the class 'hide' to the element
element.classList.add('hide');
}
});
});
}
}
}
}
// Attach the click event listener to the element with ID dropdown-update
/*
document.getElementById("dropdown-update").addEventListener("click", handleDropdownUpdateClick);
*/
/* Update Dropdown when Activity Filter is activated */
// The `renderitems` event runs whenever the list renders items after switching pages.
listInstance.on('renderitems', (renderedItems) => {
document.querySelectorAll('[activity-selected="true"]').forEach((item) => {
item.addEventListener('click', function () {
// Find the sibling element with the attribute activity-inner-link-destination="true"
const sibling = item.parentElement.querySelector(
'[activity-inner-link-destination="true"]'
);
// Check if the sibling exists and contains an <a> element
if (sibling) {
const linkElement = sibling.querySelector('a');
if (linkElement) {
// Get the href value from the <a> element
const hrefValue = linkElement.getAttribute('href');
// Update the href of the button with ID go-button
const goButton = document.getElementById('go-button');
if (goButton) {
goButton.setAttribute('href', hrefValue);
goButton.classList.remove('is-inactive');
}
}
}
});
});
// Run these the first time filtering happens
// Log that filtering has happened
console.log('Filtering is');
console.log(filtermonitor);
if (filtermonitor) {
console.log("I'm not repeating myself");
} else {
createEventListeners();
}
filtermonitor = true;
console.log(filtermonitor);
//if filteringhappened {console.log("Filtering has happened")};
handleDropdownUpdateClick();
});
},
]);
</script>
That works!! So now the blue button creates the desired action.
So now I just need it to happen when I select any item in Dropdown 1.
I’d like to find a simple and elegant way to do this - my code is already messy and rushed.
I thought I had added an event listener to any click on [activity-dropdown-item=“true”] and then reset filter 2 on line 59 of my code but it’s not happening.
Is there a simple way using the API to trigger the reset of filter 2 every time filter 1 happens?
hey @jon.burdon! How about this? Instead of adding an event listener to all options, we listen to any selection change for the first dropdown and then we trigger the filter reset.
const locationDropdown = document.getElementById('location-select');
locationDropdown.addEventListener('change', () => {
console.log('location changed');
filterInstance.resetFilters(['activity']);
});
Maybe this can also help us remove some redundant code from the solution you created.
Let me know if there is anything else we are missing!
Brilliant. It’s working. I need to work on a couple of other amendments. Thanks for your support.
Great to hear @jon.burdon! Let me know if there is anything else I can help you with