100 lines
3.9 KiB
JavaScript
100 lines
3.9 KiB
JavaScript
if (!customElements.get('product-info')) {
|
|
customElements.define(
|
|
'product-info',
|
|
class ProductInfo extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
this.input = this.querySelector('.quantity__input');
|
|
this.currentVariant = this.querySelector('.product-variant-id');
|
|
this.submitButton = this.querySelector('[type="submit"]');
|
|
}
|
|
|
|
cartUpdateUnsubscriber = undefined;
|
|
variantChangeUnsubscriber = undefined;
|
|
|
|
connectedCallback() {
|
|
if (!this.input) return;
|
|
this.quantityForm = this.querySelector('.product-form__quantity');
|
|
if (!this.quantityForm) return;
|
|
this.setQuantityBoundries();
|
|
if (!this.dataset.originalSection) {
|
|
this.cartUpdateUnsubscriber = subscribe(PUB_SUB_EVENTS.cartUpdate, this.fetchQuantityRules.bind(this));
|
|
}
|
|
this.variantChangeUnsubscriber = subscribe(PUB_SUB_EVENTS.variantChange, (event) => {
|
|
const sectionId = this.dataset.originalSection ? this.dataset.originalSection : this.dataset.section;
|
|
if (event.data.sectionId !== sectionId) return;
|
|
this.updateQuantityRules(event.data.sectionId, event.data.html);
|
|
this.setQuantityBoundries();
|
|
});
|
|
}
|
|
|
|
disconnectedCallback() {
|
|
if (this.cartUpdateUnsubscriber) {
|
|
this.cartUpdateUnsubscriber();
|
|
}
|
|
if (this.variantChangeUnsubscriber) {
|
|
this.variantChangeUnsubscriber();
|
|
}
|
|
}
|
|
|
|
setQuantityBoundries() {
|
|
const data = {
|
|
cartQuantity: this.input.dataset.cartQuantity ? parseInt(this.input.dataset.cartQuantity) : 0,
|
|
min: this.input.dataset.min ? parseInt(this.input.dataset.min) : 1,
|
|
max: this.input.dataset.max ? parseInt(this.input.dataset.max) : null,
|
|
step: this.input.step ? parseInt(this.input.step) : 1,
|
|
};
|
|
|
|
let min = data.min;
|
|
const max = data.max === null ? data.max : data.max - data.cartQuantity;
|
|
if (max !== null) min = Math.min(min, max);
|
|
if (data.cartQuantity >= data.min) min = Math.min(min, data.step);
|
|
|
|
this.input.min = min;
|
|
this.input.max = max;
|
|
this.input.value = min;
|
|
publish(PUB_SUB_EVENTS.quantityUpdate, undefined);
|
|
}
|
|
|
|
fetchQuantityRules() {
|
|
if (!this.currentVariant || !this.currentVariant.value) return;
|
|
this.querySelector('.quantity__rules-cart .loading__spinner').classList.remove('hidden');
|
|
fetch(`${this.dataset.url}?variant=${this.currentVariant.value}§ion_id=${this.dataset.section}`)
|
|
.then((response) => {
|
|
return response.text();
|
|
})
|
|
.then((responseText) => {
|
|
const html = new DOMParser().parseFromString(responseText, 'text/html');
|
|
this.updateQuantityRules(this.dataset.section, html);
|
|
this.setQuantityBoundries();
|
|
})
|
|
.catch((e) => {
|
|
console.error(e);
|
|
})
|
|
.finally(() => {
|
|
this.querySelector('.quantity__rules-cart .loading__spinner').classList.add('hidden');
|
|
});
|
|
}
|
|
|
|
updateQuantityRules(sectionId, html) {
|
|
const quantityFormUpdated = html.getElementById(`Quantity-Form-${sectionId}`);
|
|
const selectors = ['.quantity__input', '.quantity__rules', '.quantity__label'];
|
|
for (let selector of selectors) {
|
|
const current = this.quantityForm.querySelector(selector);
|
|
const updated = quantityFormUpdated.querySelector(selector);
|
|
if (!current || !updated) continue;
|
|
if (selector === '.quantity__input') {
|
|
const attributes = ['data-cart-quantity', 'data-min', 'data-max', 'step'];
|
|
for (let attribute of attributes) {
|
|
const valueUpdated = updated.getAttribute(attribute);
|
|
if (valueUpdated !== null) current.setAttribute(attribute, valueUpdated);
|
|
}
|
|
} else {
|
|
current.innerHTML = updated.innerHTML;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
);
|
|
}
|