From e5370ac3466df6dbf598d60e3b6c8c3724aab033 Mon Sep 17 00:00:00 2001 From: Aaron Stephanus Date: Wed, 27 Dec 2023 17:13:24 -0600 Subject: [PATCH] Adds persistent calendar filtering across page views in session storage Signed-off-by: Aaron Stephanus --- _layouts/calendar.html | 82 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/_layouts/calendar.html b/_layouts/calendar.html index d90062f208..5f0ddf23b4 100644 --- a/_layouts/calendar.html +++ b/_layouts/calendar.html @@ -675,7 +675,89 @@

Connect with the community

}); } } + + const filterStateStorageName = 'events--calendar--filters'; + function readFilterState() { + const filterStateJson = window.sessionStorage.getItem(filterStateStorageName); + if (filterStateJson) { + const parsedFilterState = JSON.parse(filterStateJson); + return parsedFilterState; + } + return null; + } + + function writeFilterState() { + const defaultFilterState = { + categories: [], + showInPersonEvents: true, + }; + const filteredCategoriesSelector = '.events--calendar.events--calendar__filtered'; + const selectedCategoriesAttributeName = 'data-filtercategory'; + const filteredCategories = ( + document.querySelector( + filteredCategoriesSelector + )?.getAttribute?.( + selectedCategoriesAttributeName + ) ?? '' + ).split(',').filter(category => category !== ''); + const onlineOnlySelector = '.events--calendar.events--calendar__filtered.events--calendar__online-only'; + const onlineOnly = !!document.querySelector(onlineOnlySelector); + const filterState = { + ...defaultFilterState, + categories: [...filteredCategories], + showInPersonEvents: !onlineOnly, + }; + const filterStateJson = JSON.stringify(filterState, null, 2); + window.sessionStorage.setItem(filterStateStorageName, filterStateJson); + } + + function initializeFilterStateDOM(filterState) { + if (!filterState) { + return; + } + const { + categories = [], + showInPersonEvents = true + } = filterState; + const calendarSelector = '.events--calendar'; + const eventsCalendarElement = document.querySelector(calendarSelector); + const selectedCategoriesAttributeName = 'data-filtercategory'; + const selectedCategoryCount = categories?.length ?? 0; + if (!showInPersonEvents) { + const inPersonToggleSelector = '.events--calendar--filters--in-person-toggle'; + const onlineOnlyClass = 'events--calendar--filters--in-person-toggle__toggled-off'; + const onlineOnlyCalendarClass = 'events--calendar__online-only'; + eventsCalendarElement?.classList?.add?.(onlineOnlyCalendarClass); + document.querySelector(inPersonToggleSelector)?.classList?.add?.(onlineOnlyClass); + } + + if (selectedCategoryCount > 0) { + const categoryList = categories.join(','); + const calendarFilteredClassName = 'events--calendar__filtered'; + eventsCalendarElement?.setAttribute?.(selectedCategoriesAttributeName, categoryList); + eventsCalendarElement?.classList?.add?.(calendarFilteredClassName); + + const categorySelectElementId = 'category-filter-selectorFilter-by-Category'; + const categorySelectElement = document.getElementById(categorySelectElementId); + const labelSelector = `label[for="${categorySelectElementId}"]`; + const labelText = `Filter by Category (${selectedCategoryCount})`; + const labelElement = document.querySelector(labelSelector); + + categories.forEach(category => { + categorySelectElement?.querySelector?.(`option[value="${category}"]`)?.setAttribute?.('selected', ''); + addFilterChip(category); + }); + if (labelElement) { + labelElement.textContent = labelText; + } + } + } + setEventsPageLinksToThisMonthCalendar(); localizeEventDates(); + initializeFilterStateDOM(readFilterState()); + window.addEventListener('beforeunload', () => { + writeFilterState(); + }); });