322 lines
9.6 KiB
JavaScript
322 lines
9.6 KiB
JavaScript
class CartRemoveButton extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
|
|
this.addEventListener("click", (event) => {
|
|
event.preventDefault();
|
|
const cartItems =
|
|
this.closest("cart-items") || this.closest("cart-drawer-items");
|
|
cartItems.updateQuantity(this.dataset.index, 0);
|
|
});
|
|
}
|
|
}
|
|
|
|
customElements.define("cart-remove-button", CartRemoveButton);
|
|
|
|
class CartItems extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
this.lineItemStatusElement =
|
|
document.getElementById("shopping-cart-line-item-status") ||
|
|
document.getElementById("CartDrawer-LineItemStatus");
|
|
|
|
const debouncedOnChange = debounce((event) => {
|
|
this.onChange(event);
|
|
}, ON_CHANGE_DEBOUNCE_TIMER);
|
|
|
|
this.addEventListener("change", debouncedOnChange.bind(this));
|
|
}
|
|
|
|
cartUpdateUnsubscriber = undefined;
|
|
|
|
connectedCallback() {
|
|
this.cartUpdateUnsubscriber = subscribe(
|
|
PUB_SUB_EVENTS.cartUpdate,
|
|
(event) => {
|
|
if (event.source === "cart-items") {
|
|
return;
|
|
}
|
|
this.onCartUpdate();
|
|
}
|
|
);
|
|
}
|
|
|
|
disconnectedCallback() {
|
|
if (this.cartUpdateUnsubscriber) {
|
|
this.cartUpdateUnsubscriber();
|
|
}
|
|
}
|
|
|
|
onChange(event) {
|
|
this.updateQuantity(
|
|
event.target.dataset.index,
|
|
event.target.value,
|
|
document.activeElement.getAttribute("name"),
|
|
event.target.dataset.quantityVariantId
|
|
);
|
|
}
|
|
|
|
onCartUpdate() {
|
|
if (this.tagName === "CART-DRAWER-ITEMS") {
|
|
fetch(`${routes.cart_url}?section_id=cart-drawer`)
|
|
.then((response) => response.text())
|
|
.then((responseText) => {
|
|
const html = new DOMParser().parseFromString(
|
|
responseText,
|
|
"text/html"
|
|
);
|
|
const selectors = ["cart-drawer-items", ".cart-drawer__footer"];
|
|
for (const selector of selectors) {
|
|
const targetElement = document.querySelector(selector);
|
|
const sourceElement = html.querySelector(selector);
|
|
if (targetElement && sourceElement) {
|
|
targetElement.replaceWith(sourceElement);
|
|
}
|
|
}
|
|
})
|
|
.catch((e) => {
|
|
console.error(e);
|
|
});
|
|
} else {
|
|
fetch(`${routes.cart_url}?section_id=main-cart-items`)
|
|
.then((response) => response.text())
|
|
.then((responseText) => {
|
|
const html = new DOMParser().parseFromString(
|
|
responseText,
|
|
"text/html"
|
|
);
|
|
const sourceQty = html.querySelector("cart-items");
|
|
this.innerHTML = sourceQty.innerHTML;
|
|
})
|
|
.catch((e) => {
|
|
console.error(e);
|
|
});
|
|
}
|
|
}
|
|
|
|
getSectionsToRender() {
|
|
return [
|
|
{
|
|
id: "main-cart-items",
|
|
section: document.getElementById("main-cart-items").dataset.id,
|
|
selector: ".js-contents",
|
|
},
|
|
{
|
|
id: "cart-icon-bubble",
|
|
section: "cart-icon-bubble",
|
|
selector: ".shopify-section",
|
|
},
|
|
{
|
|
id: "cart-live-region-text",
|
|
section: "cart-live-region-text",
|
|
selector: ".shopify-section",
|
|
},
|
|
{
|
|
id: "main-cart-footer",
|
|
section: document.getElementById("main-cart-footer").dataset.id,
|
|
selector: ".js-contents",
|
|
},
|
|
];
|
|
}
|
|
|
|
updateQuantity(line, quantity, name, variantId) {
|
|
this.enableLoading(line);
|
|
|
|
const body = JSON.stringify({
|
|
line,
|
|
quantity,
|
|
sections: this.getSectionsToRender().map((section) => section.section),
|
|
sections_url: window.location.pathname,
|
|
});
|
|
|
|
fetch(`${routes.cart_change_url}`, { ...fetchConfig(), ...{ body } })
|
|
.then((response) => {
|
|
return response.text();
|
|
})
|
|
.then((state) => {
|
|
const parsedState = JSON.parse(state);
|
|
const quantityElement =
|
|
document.getElementById(`Quantity-${line}`) ||
|
|
document.getElementById(`Drawer-quantity-${line}`);
|
|
const items = document.querySelectorAll(".cart-item");
|
|
|
|
if (parsedState.errors) {
|
|
quantityElement.value = quantityElement.getAttribute("value");
|
|
this.updateLiveRegions(line, parsedState.errors);
|
|
return;
|
|
}
|
|
|
|
this.classList.toggle("is-empty", parsedState.item_count === 0);
|
|
const cartDrawerWrapper = document.querySelector("cart-drawer");
|
|
const cartFooter = document.getElementById("main-cart-footer");
|
|
|
|
if (cartFooter)
|
|
cartFooter.classList.toggle("is-empty", parsedState.item_count === 0);
|
|
if (cartDrawerWrapper)
|
|
cartDrawerWrapper.classList.toggle(
|
|
"is-empty",
|
|
parsedState.item_count === 0
|
|
);
|
|
|
|
this.getSectionsToRender().forEach((section) => {
|
|
const elementToReplace =
|
|
document
|
|
.getElementById(section.id)
|
|
.querySelector(section.selector) ||
|
|
document.getElementById(section.id);
|
|
elementToReplace.innerHTML = this.getSectionInnerHTML(
|
|
parsedState.sections[section.section],
|
|
section.selector
|
|
);
|
|
});
|
|
const updatedValue = parsedState.items[line - 1]
|
|
? parsedState.items[line - 1].quantity
|
|
: undefined;
|
|
let message = "";
|
|
if (
|
|
items.length === parsedState.items.length &&
|
|
updatedValue !== parseInt(quantityElement.value)
|
|
) {
|
|
if (typeof updatedValue === "undefined") {
|
|
message = window.cartStrings.error;
|
|
} else {
|
|
message = window.cartStrings.quantityError.replace(
|
|
"[quantity]",
|
|
updatedValue
|
|
);
|
|
}
|
|
}
|
|
this.updateLiveRegions(line, message);
|
|
|
|
const lineItem =
|
|
document.getElementById(`CartItem-${line}`) ||
|
|
document.getElementById(`CartDrawer-Item-${line}`);
|
|
if (lineItem && lineItem.querySelector(`[name="${name}"]`)) {
|
|
cartDrawerWrapper
|
|
? trapFocus(
|
|
cartDrawerWrapper,
|
|
lineItem.querySelector(`[name="${name}"]`)
|
|
)
|
|
: lineItem.querySelector(`[name="${name}"]`).focus();
|
|
} else if (parsedState.item_count === 0 && cartDrawerWrapper) {
|
|
trapFocus(
|
|
cartDrawerWrapper.querySelector(".drawer__inner-empty"),
|
|
cartDrawerWrapper.querySelector("a")
|
|
);
|
|
} else if (document.querySelector(".cart-item") && cartDrawerWrapper) {
|
|
trapFocus(
|
|
cartDrawerWrapper,
|
|
document.querySelector(".cart-item__name")
|
|
);
|
|
}
|
|
|
|
publish(PUB_SUB_EVENTS.cartUpdate, {
|
|
source: "cart-items",
|
|
cartData: parsedState,
|
|
variantId: variantId,
|
|
});
|
|
})
|
|
.catch(() => {
|
|
this.querySelectorAll(".loading__spinner").forEach((overlay) =>
|
|
overlay.classList.add("hidden")
|
|
);
|
|
const errors =
|
|
document.getElementById("cart-errors") ||
|
|
document.getElementById("CartDrawer-CartErrors");
|
|
errors.textContent = window.cartStrings.error;
|
|
})
|
|
.finally(() => {
|
|
this.disableLoading(line);
|
|
});
|
|
}
|
|
|
|
updateLiveRegions(line, message) {
|
|
const lineItemError =
|
|
document.getElementById(`Line-item-error-${line}`) ||
|
|
document.getElementById(`CartDrawer-LineItemError-${line}`);
|
|
if (lineItemError)
|
|
lineItemError.querySelector(".cart-item__error-text").innerHTML = message;
|
|
|
|
this.lineItemStatusElement.setAttribute("aria-hidden", true);
|
|
|
|
const cartStatus =
|
|
document.getElementById("cart-live-region-text") ||
|
|
document.getElementById("CartDrawer-LiveRegionText");
|
|
cartStatus.setAttribute("aria-hidden", false);
|
|
|
|
setTimeout(() => {
|
|
cartStatus.setAttribute("aria-hidden", true);
|
|
}, 1000);
|
|
}
|
|
|
|
getSectionInnerHTML(html, selector) {
|
|
return new DOMParser()
|
|
.parseFromString(html, "text/html")
|
|
.querySelector(selector).innerHTML;
|
|
}
|
|
|
|
enableLoading(line) {
|
|
const mainCartItems =
|
|
document.getElementById("main-cart-items") ||
|
|
document.getElementById("CartDrawer-CartItems");
|
|
mainCartItems.classList.add("cart__items--disabled");
|
|
|
|
const cartItemElements = this.querySelectorAll(
|
|
`#CartItem-${line} .loading__spinner`
|
|
);
|
|
const cartDrawerItemElements = this.querySelectorAll(
|
|
`#CartDrawer-Item-${line} .loading__spinner`
|
|
);
|
|
|
|
[...cartItemElements, ...cartDrawerItemElements].forEach((overlay) =>
|
|
overlay.classList.remove("hidden")
|
|
);
|
|
|
|
document.activeElement.blur();
|
|
this.lineItemStatusElement.setAttribute("aria-hidden", false);
|
|
}
|
|
|
|
disableLoading(line) {
|
|
const mainCartItems =
|
|
document.getElementById("main-cart-items") ||
|
|
document.getElementById("CartDrawer-CartItems");
|
|
mainCartItems.classList.remove("cart__items--disabled");
|
|
|
|
const cartItemElements = this.querySelectorAll(
|
|
`#CartItem-${line} .loading__spinner`
|
|
);
|
|
const cartDrawerItemElements = this.querySelectorAll(
|
|
`#CartDrawer-Item-${line} .loading__spinner`
|
|
);
|
|
|
|
cartItemElements.forEach((overlay) => overlay.classList.add("hidden"));
|
|
cartDrawerItemElements.forEach((overlay) =>
|
|
overlay.classList.add("hidden")
|
|
);
|
|
}
|
|
}
|
|
|
|
customElements.define("cart-items", CartItems);
|
|
|
|
if (!customElements.get("cart-note")) {
|
|
customElements.define(
|
|
"cart-note",
|
|
class CartNote extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
|
|
this.addEventListener(
|
|
"input",
|
|
debounce((event) => {
|
|
const body = JSON.stringify({ note: event.target.value });
|
|
fetch(`${routes.cart_update_url}`, {
|
|
...fetchConfig(),
|
|
...{ body },
|
|
});
|
|
}, ON_CHANGE_DEBOUNCE_TIMER)
|
|
);
|
|
}
|
|
}
|
|
);
|
|
}
|