Untitled
unknown
javascript
2 years ago
10 kB
6
Indexable
import '../lib/facet-remove'; class FacetFiltersForm extends HTMLElement { constructor() { super(); this._loading = false; this._activeFilter = false; this.selectors = { filterBtn: '[data-filter-btn]', filterRemove: '[data-filter-remove]', filterOptionsContainer: '[data-filter-options-container]', mobileFilterBtn: '[data-mobile-filter-trigger]', mobileApplyFiltersBtn: '[data-mobile-apply-filters]', mobileCloseFiltersBtn: '[data-mobile-filter-close]', mobileFilters: '[data-mobile-filters]' }; this.onActiveFilterClick = this.onActiveFilterClick.bind(this); const facetForm = this.querySelector('form'); facetForm.addEventListener('input', this.onSubmitHandler.bind(this)); this.addEventListener('click', this.onFilterBtnClick.bind(this)); if (this.id === 'MobileFacets') { document .querySelector(this.selectors.mobileFilterBtn) .addEventListener('click', this.onMobileFilterPanelClick.bind(this)); document .querySelector(this.selectors.mobileFilters) .addEventListener('click', this.onMobileApplyFiltersClick.bind(this)); document .querySelector(this.selectors.mobileFilters) .addEventListener('click', this.onMobileFiltersCloseClick.bind(this)); } } static setListeners() { const onHistoryChange = (event) => { const searchParams = event.state ? event.state.searchParams : FacetFiltersForm.searchParamsInitial; if (searchParams === FacetFiltersForm.searchParamsPrev) return; FacetFiltersForm.renderPage(searchParams, null, false); }; window.addEventListener('popstate', onHistoryChange); } onActiveFilterClick(event) { event.preventDefault(); const url = event.currentTarget.href.indexOf('?') === -1 ? '' : event.currentTarget.href.slice( event.currentTarget.href.indexOf('?') + 1 ); FacetFiltersForm.renderPage(url); } onMobileFilterPanelClick(e) { e.preventDefault(); document .querySelector(this.selectors.mobileFilters) .classList.add('active'); document.querySelector('[data-sticky-filters]').classList.add('active'); } onMobileFiltersCloseClick(e) { if (e.target.closest(this.selectors.mobileCloseFiltersBtn) === null) return; document .querySelector(this.selectors.mobileFilters) .classList.remove('active'); document.querySelector('[data-sticky-filters]').classList.remove('active'); } onMobileApplyFiltersClick(e) { if (e.target.closest(this.selectors.mobileApplyFiltersBtn) === null) return; document .querySelector(this.selectors.mobileFilters) .classList.remove('active'); document.querySelector('[data-sticky-filters]').classList.remove('active'); } createSearchParams(form) { const formData = new FormData(form); return new URLSearchParams(formData).toString(); } onSubmitHandler(event) { event.preventDefault(); this.loading = true; const sortFilterForms = document.querySelectorAll('facets-form form'); const forms = []; const isMobile = event.target.closest('form').id === 'FacetsFormMobile'; sortFilterForms.forEach((form) => { if (!isMobile) { if ( form.id === 'FacetSortForm' || form.id === 'FacetsFormDesktop' || form.id === 'FacetSortDrawerForm' ) { forms.push(this.createSearchParams(form)); } } else if (form.id === 'FacetsFormMobile') { forms.push(this.createSearchParams(form)); } }); this.onSubmitForm(forms.join('&'), event); } onSubmitForm(searchParams, event) { FacetFiltersForm.renderPage(searchParams, event); } onFilterBtnClick(e) { if (e.target.closest(this.selectors.filterBtn) === null) return; const btn = e.target.closest(this.selectors.filterBtn); this.activeFilter = btn.getAttribute('data-filter-btn'); } static renderFilters(html, event) { const parsedHTML = new DOMParser().parseFromString(html, 'text/html'); const facetDetailsElements = parsedHTML.querySelectorAll( '#FacetsFormDesktop [data-filter-options], #FacetsFormMobile [data-filter-options]' ); const matchesIndex = (element) => { const jsFilter = event ? event.target.closest('[data-filter-slug]') : undefined; return jsFilter ? element.dataset.index === jsFilter.dataset.index : false; }; const facetsToRender = Array.from(facetDetailsElements).filter( (element) => !matchesIndex(element) ); facetsToRender.forEach((element) => { document .querySelectorAll( `[data-filter-options="${element.dataset.facetSlug}"]` ) .forEach((filter) => { filter.innerHTML = element.innerHTML; }); }); FacetFiltersForm.renderActiveFacets(parsedHTML); } static renderActiveFacets(html) { const activeFacetElementSelectors = ['[data-active-filters]']; activeFacetElementSelectors.forEach((selector) => { const activeFacetsElement = html.querySelector(selector); if (!activeFacetsElement) return; document.querySelector(selector).innerHTML = activeFacetsElement.innerHTML; }); } static renderProductGridContainer(html) { document.querySelector('[data-product-grid-container]').innerHTML = new DOMParser() .parseFromString(html, 'text/html') .querySelector('[data-product-grid-container]').innerHTML; document.querySelector('#DesktopFacets').loading = false; document.querySelector('#MobileFacets').loading = false; // if (window.shopifyWishlist) { // window.shopifyWishlist.initButtons( // document.querySelector('[data-product-grid-container]') // ); // } } static renderSectionFromCache(filterDataUrl, event) { const { html } = FacetFiltersForm.filterData.find(filterDataUrl); FacetFiltersForm.renderFilters(html, event); FacetFiltersForm.renderProductGridContainer(html); } static renderSectionFromFetch(url, event) { console.log('renderSectionFromFetch url => ', url); fetch(url) .then((response) => response.text()) .then((responseText) => { const html = responseText; FacetFiltersForm.filterData = [ ...FacetFiltersForm.filterData, { html, url } ]; FacetFiltersForm.renderFilters(html, event); FacetFiltersForm.renderProductGridContainer(html); }); } static renderPage(searchParams, event, updateURLHash = true) { FacetFiltersForm.searchParamsPrev = searchParams; const sections = FacetFiltersForm.getSections(); sections.forEach((section) => { const url = `${window.location.pathname}?section_id=${section.section}&${searchParams}`; const filterDataUrl = (element) => element.url === url; if (FacetFiltersForm.filterData.some(filterDataUrl)) { FacetFiltersForm.renderSectionFromCache(filterDataUrl, event); } else { FacetFiltersForm.renderSectionFromFetch(url, event); } }); if (updateURLHash) FacetFiltersForm.updateURLHash(searchParams); } static updateURLHash(searchParams) { window.history.pushState( { searchParams }, '', `${window.location.pathname}${searchParams && '?'.concat(searchParams)}` ); } static getSections() { return [ { section: document.getElementById('product-grid').dataset.id } ]; } get activeFilter() { return this._activeFilter; } set activeFilter(handle) { if (handle) { if (this.activeFilter && this.activeFilter === handle) { /** * Clicked on self */ if (this.id === 'DesktopFacets') { this.querySelector( `[data-filter-btn="${this.activeFilter}"]` ).classList.remove('active'); this.classList.remove('active'); this.querySelector( `[data-filter-options="${this.activeFilter}"]` ).classList.remove('active'); } document .querySelector('[data-sticky-filters]') .classList.remove('active'); this._activeFilter = false; } else if (this.activeFilter) { /** * Click on another filter while another is already open */ if (this.id === 'DesktopFacets') { this.querySelector( `[data-filter-btn="${this.activeFilter}"]` ).classList.remove('active'); this.querySelector(`[data-filter-btn="${handle}"]`).classList.add( 'active' ); this.querySelector( `[data-filter-options="${this.activeFilter}"]` ).classList.remove('active'); this.querySelector(`[data-filter-options="${handle}"]`).classList.add( 'active' ); } this._activeFilter = handle; } else { /** * No facet open yet */ if (this.id === 'DesktopFacets') { this.querySelector(`[data-filter-btn="${handle}"]`).classList.add( 'active' ); this.classList.add('active'); this.querySelector(`[data-filter-options="${handle}"]`).classList.add( 'active' ); } document.querySelector('[data-sticky-filters]').classList.add('active'); this._activeFilter = handle; } } else { /** * Close all */ if (this.id === 'DesktopFacets') { this.querySelector( `[data-filter-btn="${this.activeFilter}"]` ).classList.remove('active'); this.classList.remove('active'); this.querySelector( `[data-filter-options="${this.activeFilter}"]` ).classList.remove('active'); } document .querySelector('[data-sticky-filters]') .classList.remove('active'); this._activeFilter = false; } } get loading() { return this._loading; } set loading(val) { this._loading = val; this.classList.toggle('loading', val); } } FacetFiltersForm.filterData = []; FacetFiltersForm.searchParamsInitial = window.location.search.slice(1); FacetFiltersForm.searchParamsPrev = window.location.search.slice(1); customElements.define('facets-form', FacetFiltersForm); FacetFiltersForm.setListeners();
Editor is loading...