Falls Church
VA
DC
Washington
DC
Washington
DC
Washington
DC
Washington
DC
Washington
`;
}
// Update URL without reloading page
updateUrlWithFilters(selectedIndustries, selectedTypeTags, currentPage);
} else {
// No filters, restore original WordPress pagination
isFiltered = false;
projectsGrid.innerHTML = originalProjectsGridHTML;
// Clear URL parameters
window.history.replaceState({}, '', window.location.pathname);
}
// Hide loading and fade in
loadingIndicator.style.display = 'none';
projectsGrid.style.opacity = '1';
// Close dropdowns after applying filters
closeAllDropdowns();
}, 300);
}
// Get paginated projects
function getPaginatedProjects(projects, page) {
const startIndex = (page - 1) * PROJECTS_PER_PAGE;
const endIndex = startIndex + PROJECTS_PER_PAGE;
const paginatedProjects = projects.slice(startIndex, endIndex);
return {
projects: paginatedProjects,
totalPages: Math.ceil(projects.length / PROJECTS_PER_PAGE),
currentPage: page
};
}
// Create pagination HTML
function createPagination(totalProjects, currentPage) {
const totalPages = Math.ceil(totalProjects / PROJECTS_PER_PAGE);
let paginationHTML = '';
if (totalPages <= 1) return '';
// Previous button
if (currentPage > 1) {
paginationHTML += `
←`;
}
// Page numbers
for (let i = 1; i <= totalPages; i++) {
if (i === currentPage) {
paginationHTML += `
${i}`;
} else {
paginationHTML += `
${i}`;
}
}
// Next button
if (currentPage < totalPages) {
paginationHTML += `
→`;
}
return paginationHTML;
}
// Add event listeners to pagination links
function addPaginationEventListeners(filteredProjects) {
const pageLinks = document.querySelectorAll('.projects-pagination .page-numbers');
pageLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
if (this.classList.contains('current')) return;
const page = parseInt(this.dataset.page);
if (page) {
goToPage(page, filteredProjects);
}
});
});
}
// Go to specific page
function goToPage(page, filteredProjects) {
currentPage = page;
// Get paginated projects
const paginatedProjects = getPaginatedProjects(filteredProjects, currentPage);
// Show loading
projectsGrid.style.opacity = '0.5';
setTimeout(() => {
// Clear current content
projectsGrid.innerHTML = '';
// Add filtered projects with fade in
paginatedProjects.projects.forEach((card, index) => {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = card.html;
const cardElement = tempDiv.firstElementChild;
cardElement.style.opacity = '0';
cardElement.style.transition = 'opacity 0.3s ease';
projectsGrid.appendChild(cardElement);
setTimeout(() => {
cardElement.style.opacity = '1';
}, index * 50); // Staggered animation
});
// Add pagination
if (filteredProjects.length > PROJECTS_PER_PAGE) {
const paginationHTML = createPagination(filteredProjects.length, currentPage);
const paginationDiv = document.createElement('div');
paginationDiv.className = 'projects-pagination';
paginationDiv.innerHTML = paginationHTML;
projectsGrid.appendChild(paginationDiv);
// Add event listeners to pagination links
addPaginationEventListeners(filteredProjects);
}
// Update URL
const selectedIndustries = getSelectedIndustries();
const selectedTypeTags = getSelectedTypeTags();
updateUrlWithFilters(selectedIndustries, selectedTypeTags, currentPage);
// Scroll to top of grid smoothly
projectsGrid.scrollIntoView({ behavior: 'smooth', block: 'start' });
// Fade in
projectsGrid.style.opacity = '1';
}, 300);
}
// Update URL with current filters and page
function updateUrlWithFilters(industries, typeTags, page = 1) {
const params = new URLSearchParams();
industries.forEach(industry => {
params.append('industries[]', industry);
});
typeTags.forEach(typeTag => {
params.append('type_tags[]', typeTag);
});
// Only add page parameter if it's not page 1
if (page > 1) {
params.set('pg', page);
}
const queryString = params.toString();
const newUrl = queryString
? `${window.location.pathname}?${queryString}`
: window.location.pathname;
// Update URL without reloading
window.history.replaceState({}, '', newUrl);
}
// Clear all filters - RESTORED ORIGINAL PAGINATION
function clearAllFilters() {
// Uncheck all industry checkboxes
document.querySelectorAll('.industry-filter:checked').forEach(cb => {
cb.checked = false;
});
// Uncheck all type tag checkboxes
document.querySelectorAll('.type-tag-filter:checked').forEach(cb => {
cb.checked = false;
});
// Hide type tag filter column
typeTagFilterColumn.style.display = 'none';
// Hide clear filter button
clearFilterColumn.style.display = 'none';
// Update UI
updateUI();
// Show loading
loadingIndicator.style.display = 'block';
projectsGrid.style.opacity = '0.5';
setTimeout(() => {
// Restore original WordPress pagination
projectsGrid.innerHTML = originalProjectsGridHTML;
// Hide loading and fade in
loadingIndicator.style.display = 'none';
projectsGrid.style.opacity = '1';
// Clear URL parameters
window.history.replaceState({}, '', window.location.pathname);
// Close dropdowns
closeAllDropdowns();
}, 300);
}
// Handle industry checkbox selection with max limit
if (industryCheckboxes) {
industryCheckboxes.addEventListener('change', function(e) {
if (e.target.classList.contains('industry-filter')) {
const selectedIndustries = getSelectedIndustries();
// If max reached and trying to select another, uncheck the last one
if (selectedIndustries.length > MAX_INDUSTRY_SELECTIONS) {
e.target.checked = false;
alert(`You can select a maximum of ${MAX_INDUSTRY_SELECTIONS} industries.`);
return;
}
updateUI();
applyFilters();
}
});
}
// Handle type tag checkbox selection with max limit
if (typeTagCheckboxes) {
typeTagCheckboxes.addEventListener('change', function(e) {
if (e.target.classList.contains('type-tag-filter')) {
const selectedTypeTags = getSelectedTypeTags();
// If max reached and trying to select another, uncheck the last one
if (selectedTypeTags.length > MAX_TYPE_TAG_SELECTIONS) {
e.target.checked = false;
alert(`You can select a maximum of ${MAX_TYPE_TAG_SELECTIONS} project types.`);
return;
}
updateUI();
applyFilters();
}
});
}
// Dropdown toggle events
industryDropdownToggle.addEventListener('click', function(e) {
e.stopPropagation();
industryDropdownOpen = !industryDropdownOpen;
toggleDropdown(industryDropdownToggle, industryDropdownContent, industryDropdownOpen);
// Close type tag dropdown if open
if (typeTagDropdownOpen) {
toggleDropdown(typeTagDropdownToggle, typeTagDropdownContent, false);
typeTagDropdownOpen = false;
}
});
typeTagDropdownToggle.addEventListener('click', function(e) {
e.stopPropagation();
// Only allow opening if industries are selected
const selectedIndustries = getSelectedIndustries();
if (selectedIndustries.length === 0) {
alert('Please select industries first to filter project types.');
return;
}
typeTagDropdownOpen = !typeTagDropdownOpen;
toggleDropdown(typeTagDropdownToggle, typeTagDropdownContent, typeTagDropdownOpen);
// Close industry dropdown if open
if (industryDropdownOpen) {
toggleDropdown(industryDropdownToggle, industryDropdownContent, false);
industryDropdownOpen = false;
}
});
// Close dropdowns when clicking outside
document.addEventListener('click', function(e) {
if (!e.target.closest('.filter-dropdown-content') && !e.target.closest('.filter-dropdown-toggle')) {
closeAllDropdowns();
}
});
// Event Listeners
clearFiltersBtn.addEventListener('click', clearAllFilters);
// Initialize from URL parameters on page load
function initializeFromUrl() {
const urlParams = new URLSearchParams(window.location.search);
// Set industry checkboxes
const industries = urlParams.getAll('industries[]');
industries.forEach(industrySlug => {
const checkbox = document.querySelector(`.industry-filter[value="${industrySlug}"]`);
if (checkbox) {
checkbox.checked = true;
}
});
// Set type tag checkboxes
const typeTags = urlParams.getAll('type_tags[]');
typeTags.forEach(typeTagSlug => {
const checkbox = document.querySelector(`.type-tag-filter[value="${typeTagSlug}"]`);
if (checkbox) {
checkbox.checked = true;
}
});
// Set current page from URL
const pageFromUrl = urlParams.get('pg');
if (pageFromUrl) {
currentPage = parseInt(pageFromUrl);
}
// Update UI
updateUI();
// Apply filters if we have any selections
if (industries.length > 0 || typeTags.length > 0) {
applyFilters();
}
}
// Initialize all project data and from URL on page load
initializeAllProjectData();
initializeFromUrl();
});