I created a community page for my latest
@Webflow project powered by
@Mapbox and the Webflow CMS coded and animated from the ground up.
You can search by member name and filter by country. I didn't use Finsweet Attributes or Jetboost. Coded it all from scratch with GPT. The country flags are being fetched from the REST Countries API and the script automatically calculates and displays how many members there are from each country.
Here is the full script.
<script src="
code.jquery.com/jquery-3.6.0…"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const memberItems = document.querySelectorAll(".members_collection-item");
const dropdownList = document.querySelector("[filters-dropdown]");
const templateFilterElement = document.querySelector(".members_filter");
const searchInput = document.querySelector("form .members_search");
// Check if the dropdown list element, template filter element, and search input are found
if (!dropdownList) {
console.error("Dropdown list with attribute 'filters-dropdown' not found.");
return;
}
if (!templateFilterElement) {
console.error("Template filter element with class 'members_filter' not found.");
return;
}
if (!searchInput) {
console.error("Search input with class 'members_search' not found.");
return;
} else {
console.log("Search input found:", searchInput);
}
let countryCounts = {};
// Collect all unique countries and count members
memberItems.forEach(item => {
const countryElement = item.querySelector("[country]");
if (countryElement) {
const country = countryElement.getAttribute("country").toLowerCase();
if (countryCounts[country]) {
countryCounts[country] ;
} else {
countryCounts[country] = 1;
}
}
});
console.log("Country counts:", countryCounts);
// Clear existing members_filter elements
dropdownList.innerHTML = '';
// Generate members_filter elements for each country
Object.keys(countryCounts).forEach(country => {
// Clone the template filter element
let filterElement = templateFilterElement.cloneNode(true);
filterElement.style.display = ''; // Ensure the cloned element is visible
let textBlock = filterElement.querySelector("[country-filter]");
let flagImage = filterElement.querySelector(".members_filter-flag");
let totalMembers = filterElement.querySelector("[total-members]");
if (textBlock) {
textBlock.textContent = country.charAt(0).toUpperCase() country.slice(1);
}
if (totalMembers) {
totalMembers.textContent = countryCounts[country];
}
// Fetch the country flag from Rest Countries API
fetch(`
restcountries.com/v3.1/name/${country}?fullText=true`)
.then(response => response.json())
.then(data => {
if (data && data[0] && data[0].flags && data[0].flags.svg) {
flagImage.src = data[0].flags.svg;
} else {
console.error(`Flag not found for country: ${country}`);
}
})
.catch(error => {
console.error(`Error fetching flag for country: ${country}`, error);
});
dropdownList.appendChild(filterElement);
// Add click event listener to each filter
filterElement.addEventListener("click", function() {
// Toggle the filter
filterElement.classList.toggle("active");
// Apply filters
applyFilters();
});
});
// Add search functionality
searchInput.addEventListener("input", function() {
// Reset country filters
document.querySelectorAll(".members_filter").forEach(filter => filter.classList.remove("active"));
// Apply filters
applyFilters();
});
function applyFilters() {
const searchText = searchInput.value.toLowerCase();
console.log("Search text:", searchText);
const activeFilters = document.querySelectorAll(".members_filter.active");
let activeCountries = Array.from(activeFilters).map(filter => filter.querySelector("[country-filter]").textContent.toLowerCase());
console.log("Active countries:", activeCountries);
memberItems.forEach(member => {
const memberNameElement = member.querySelector("[member-name]");
const memberCountryElement = member.querySelector("[country]");
const memberName = memberNameElement ? memberNameElement.textContent.toLowerCase() : '';
const memberCountry = memberCountryElement ? memberCountryElement.getAttribute("country").toLowerCase() : '';
console.log("Member name:", memberName, "Member country:", memberCountry);
// Show member if it matches the search text and the active country filters
if (memberName.includes(searchText) && (activeCountries.length === 0 || activeCountries.includes(memberCountry))) {
member.style.display = "";
} else {
member.style.display = "none";
}
});
}
});
</script>