@salla.sa/twilight-components
Version:
Salla Web Component
215 lines (210 loc) • 9.72 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
;
var index = require('./index-WgjOGof0.js');
var interfaces = require('./interfaces-DZDQwN6-.js');
var Helper = require('./Helper-RxjfQWAX.js');
require('./anime.es-BqW8JHZi.js');
const sallaFiltersCss = ":host{display:block}.s-rating-stars-small{line-height:12px}.s-filters-radio{background-image:none !important}";
const SallaFilters = class {
constructor(hostRef) {
index.registerInstance(this, hostRef);
this.changed = index.createEvent(this, "changed");
this.isReady = false; //to avoid triggering the changed event
this.filtersData = {};
salla.event.on('filters::hidden', () => this.host.style.display = 'none');
salla.lang.onLoaded(() => {
this.apply = salla.lang.get('pages.checkout.apply');
this.reset = salla.lang.get('pages.categories.filters_reset');
});
salla.event.on('filters::fetched', ({ filters }) => {
this.host.style.display = '';
let freshFilterData = {};
this.filters = filters
.map((filter) => {
filter.label = {
category_id: salla.lang.get('common.titles.categories'),
brand_id: salla.lang.get('common.titles.brands'),
rating: salla.lang.get('pages.categories.filter_rating'),
price: salla.lang.get('pages.categories.filter_price'),
}[filter.key] || filter.label;
// filter.type = FilterOptionTypes.VALUES;
if (filter.key == 'rating') {
filter.type = interfaces.FilterOptionTypes.VALUES;
//@ts-ignore
let { max, min } = filter.values;
//@ts-ignore
filter.values = [5, 4, 3, 2, 1].filter(stars => stars >= min || stars <= max);
}
if (this.filtersData.variants && filter.type == interfaces.FilterOptionTypes.VARIANTS) {
freshFilterData.variants = this.filtersData.variants;
}
if (this.filtersData[filter.key] && filter.type !== interfaces.FilterOptionTypes.VARIANTS) {
freshFilterData[filter.key] = this.filtersData[filter.key];
}
let searchParams = new URLSearchParams(window.location.search);
let hasFilters = false;
for (let key of searchParams.keys()) {
if (key.includes('filters')) {
hasFilters = true;
break; // No need to continue checking once a match is found
}
}
if (salla.config.get('page.slug') == "product.index" && Object.keys(freshFilterData).length == 0 && !hasFilters) {
// Append the current category to the url if there are no pre-selected filters
let currentUrl = window.location.href;
let filterValue = salla.config.get('page.id');
let separator = currentUrl.indexOf('?') !== -1 ? '&' : '?';
let newUrl = currentUrl + separator + 'filters[category_id]=' + filterValue;
freshFilterData.category_id = filterValue;
window.history.pushState({ path: newUrl }, '', newUrl);
}
return filter;
});
this.filtersData = freshFilterData;
this.host.childNodes.forEach(async (widget) => widget.setWidgetHeight && await widget.setWidgetHeight());
});
}
async componentWillLoad() {
try {
const searchParams = new URLSearchParams(window.location.search);
this.filtersData = await Helper.Helper.extractFiltersFromUrl(searchParams);
}
catch (e) {
console.warn('failed to get filters from URL', e.message);
}
}
/**
* Method to get filter data.
*/
async getFilters() {
return this.filtersData;
}
/**
* Apply filter action.
*/
async applyFilters() {
if (!this.isReady) {
return;
}
let hasFilters = Object.keys(this.filtersData).length > 0;
setTimeout(() => {
var _a;
if (hasFilters) {
let url = new URL(window.location.href);
for (const [key] of url.searchParams.entries()) {
if (key.startsWith("filters")) {
url.searchParams.delete(key);
}
}
let encodedFilterValues = this.encodeFilters(this.filtersData);
let sanitizedFilterValues = url.search.split("&").filter(item => !item.includes('filters')).join("&");
if (sanitizedFilterValues) {
url.search = url.search.split("&filters")[0] + "&" + encodedFilterValues;
}
else {
url.search = `?${encodedFilterValues}`;
}
window.history.pushState({}, '', url.href);
}
else {
let url = new URL(window.location.href);
(_a = url.searchParams) === null || _a === void 0 ? void 0 : _a.delete('filters');
window.history.pushState({}, '', url.toString());
}
salla.event.emit('salla-filters::changed', this.filtersData);
this.changed.emit(this.filtersData);
}, 300);
}
encodeFilters(filters, parentKey = 'filters') {
const encodedFilters = [];
for (const key in filters) {
if (Object.prototype.hasOwnProperty.call(filters, key)) {
const value = filters[key];
const fullKey = parentKey ? `${parentKey}[${key}]` : key;
if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
encodedFilters.push(`${fullKey}[${i}]=${value[i]}`);
}
}
else if (typeof value === 'object' && value !== null) {
encodedFilters.push(this.encodeFilters(value, fullKey));
}
else {
// const encodedKey = encodeURIComponent(fullKey);
// const encodedValue = encodeURIComponent(value);
let result = `${fullKey}=${value}`;
encodedFilters.push(result);
}
}
}
return encodedFilters.join('&');
}
;
/**
* Reset selected filters.
*/
async resetFilters() {
this.removeFiltersQueryParams();
this.filtersData = {};
this.host.childNodes.forEach((widget) => widget.reset && widget.reset());
salla.event.emit('salla-filters::reset');
return this.applyFilters();
}
removeFiltersQueryParams() {
const searchParams = new URLSearchParams(window.location.search);
const newUrl = Array.from(searchParams.keys())
.filter(key => !key.startsWith('filters['))
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(searchParams.get(key))}`)
.join('&');
const finalUrl = newUrl ? `${window.location.pathname}?${newUrl}` : window.location.pathname;
window.history.pushState({}, '', finalUrl);
}
/**
* @param {{target:HTMLInputElement}} event
* @param option
* @param value
* @private
*/
handleOptionChange(event, option, value) {
if (option.type === interfaces.FilterOptionTypes.RANGE) {
this.filtersData[option.key] = value;
}
let isChecked = event.target.checked;
if (option.type === interfaces.FilterOptionTypes.VARIANTS) {
this.filtersData.variants = this.filtersData.variants || {};
isChecked && (this.filtersData.variants[option.key] = value);
isChecked || (delete this.filtersData.variants[option.key]);
}
else if (event.target.type == "radio") {
isChecked && (this.filtersData[option.key] = value);
isChecked || (delete this.filtersData[option.key]);
}
//it's checkbox
// add if condition to avoid error when the filter is not existed in the filtersData
else if (event.target.type == "checkbox") {
this.filtersData[option.key] = this.filtersData[option.key] || [];
if (isChecked) {
this.filtersData[option.key].push(value);
}
this.filtersData[option.key] = this.filtersData[option.key].filter(val => val != value);
}
this.applyFilters();
}
render() {
var _a, _b;
return index.h(index.Host, { key: '80fda46c33daf06c6a22d567d13375351db4e3cb' }, (_a = this.filters) === null || _a === void 0 ? void 0 :
_a.map(option => index.h("salla-filters-widget", { option: option, filtersData: this.filtersData, onChanged: ({ detail: { event, option, value } }) => {
this.handleOptionChange(event, option, value);
} })), ((_b = this.filters) === null || _b === void 0 ? void 0 : _b.length) ? index.h("div", { class: "s-filters-footer" }, index.h("salla-button", { color: 'gray', fill: 'outline', onClick: () => this.resetFilters() }, this.reset)) : '');
}
componentDidLoad() {
this.isReady = true;
}
get host() { return index.getElement(this); }
};
SallaFilters.style = sallaFiltersCss;
exports.salla_filters = SallaFilters;
//# sourceMappingURL=salla-filters.entry.cjs.js.map
//# sourceMappingURL=salla-filters.cjs.entry.js.map