Untitled
unknown
javascript
2 years ago
10 kB
10
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...