diff --git a/.vscode/settings.json b/.vscode/settings.json
index 39e44f17346..90abaf1f399 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,7 +1,8 @@
{
"editor.formatOnSave": false,
"[javascript]": {
- "editor.formatOnSave": true
+ "editor.formatOnSave": true,
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.formatOnSave": true
diff --git a/assets/bulk-add.js b/assets/bulk-add.js
deleted file mode 100644
index 0821122f3b8..00000000000
--- a/assets/bulk-add.js
+++ /dev/null
@@ -1,41 +0,0 @@
-class BulkAdd extends HTMLElement {
- constructor() {
- super();
- this.queue = []
- this.requestStarted = false;
- this.ids = []
- }
-
- startQueue(id, quantity) {
- this.queue.push({id, quantity})
- const interval = setInterval(() => {
- if (this.queue.length > 0) {
- if (!this.requestStarted) {
- this.sendRequest(this.queue)
- }
- } else {
- clearInterval(interval)
- }
- }, 250)
- }
-
-
- sendRequest(queue) {
- this.requestStarted = true;
- const items = {}
- const ids = []
- queue.forEach((queueItem) => {
- items[parseInt(queueItem.id)] = queueItem.quantity;
- ids.push(queueItem.id)
- });
- this.queue = this.queue.filter(queueElement => !queue.includes(queueElement));
- const quickOrderList = this.closest('quick-order-list');
- quickOrderList.updateMultipleQty(items, ids)
- }
-}
-
-if (!customElements.get('bulk-add')) {
- customElements.define('bulk-add', BulkAdd)
-};
-
-
diff --git a/assets/global.js b/assets/global.js
index 3ccdd967de9..29ee2cfe353 100644
--- a/assets/global.js
+++ b/assets/global.js
@@ -1360,3 +1360,82 @@ class AccountIcon extends HTMLElement {
}
customElements.define('account-icon', AccountIcon);
+
+class BulkAdd extends HTMLElement {
+ constructor() {
+ super();
+ this.queue = [];
+ this.requestStarted = false;
+ this.ids = [];
+ }
+
+ startQueue(id, quantity) {
+ this.queue.push({ id, quantity });
+ const interval = setInterval(() => {
+ if (this.queue.length > 0) {
+ if (!this.requestStarted) {
+ this.sendRequest(this.queue);
+ }
+ } else {
+ clearInterval(interval);
+ }
+ }, 250);
+ }
+
+ sendRequest(queue) {
+ this.requestStarted = true;
+ const items = {};
+ queue.forEach((queueItem) => {
+ items[parseInt(queueItem.id)] = queueItem.quantity;
+ });
+ this.queue = this.queue.filter((queueElement) => !queue.includes(queueElement));
+ const quickBulkElement = this.closest('quick-order-list') || this.closest('quick-add-bulk');
+ quickBulkElement.updateMultipleQty(items);
+ }
+
+ resetQuantityInput(id) {
+ const input = this.querySelector(`#Quantity-${id}`);
+ input.value = input.getAttribute('value');
+ this.isEnterPressed = false;
+ }
+
+ setValidity(event, index, message) {
+ event.target.setCustomValidity(message);
+ event.target.reportValidity();
+ this.resetQuantityInput(index);
+ event.target.select();
+ }
+
+ validateQuantity(event) {
+ const inputValue = parseInt(event.target.value);
+ const index = event.target.dataset.index;
+
+ if (inputValue < event.target.dataset.min) {
+ this.setValidity(event, index, window.quickOrderListStrings.min_error.replace('[min]', event.target.dataset.min));
+ } else if (inputValue > parseInt(event.target.max)) {
+ this.setValidity(event, index, window.quickOrderListStrings.max_error.replace('[max]', event.target.max));
+ } else if (inputValue % parseInt(event.target.step) != 0) {
+ this.setValidity(event, index, window.quickOrderListStrings.step_error.replace('[step]', event.target.step));
+ } else {
+ event.target.setCustomValidity('');
+ event.target.reportValidity();
+ this.startQueue(index, inputValue);
+ }
+ }
+
+ getSectionsUrl() {
+ if (window.pageNumber) {
+ return `${window.location.pathname}?page=${window.pageNumber}`;
+ } else {
+ return `${window.location.pathname}`;
+ }
+ }
+
+ getSectionInnerHTML(html, selector) {
+ return new DOMParser().parseFromString(html, 'text/html').querySelector(selector).innerHTML;
+ }
+}
+
+if (!customElements.get('bulk-add')) {
+ customElements.define('bulk-add', BulkAdd);
+}
diff --git a/assets/quick-add-bulk.js b/assets/quick-add-bulk.js
index 935d6f6a61d..1208ffe7241 100644
--- a/assets/quick-add-bulk.js
+++ b/assets/quick-add-bulk.js
@@ -1,16 +1,16 @@
if (!customElements.get('quick-add-bulk')) {
customElements.define(
'quick-add-bulk',
- class QuickAddBulk extends HTMLElement {
+ class QuickAddBulk extends BulkAdd {
constructor() {
super();
this.quantity = this.querySelector('quantity-input');
const debouncedOnChange = debounce((event) => {
- if (parseInt(event.target.dataset.cartQuantity) === 0) {
- this.addToCart(event);
+ if (parseInt(event.target.value) === 0) {
+ this.startQueue(event.target.dataset.index, parseInt(event.target.value));
} else {
- this.updateCart(event);
+ this.validateQuantity(event);
}
}, ON_CHANGE_DEBOUNCE_TIMER);
@@ -65,12 +65,6 @@ if (!customElements.get('quick-add-bulk')) {
});
}
- resetQuantityInput(id) {
- const input = document.getElementById(id);
- input.value = input.getAttribute('value');
- this.isEnterPressed = false;
- }
-
cleanErrorMessageOnType(event) {
event.target.addEventListener(
'keypress',
@@ -102,81 +96,37 @@ if (!customElements.get('quick-add-bulk')) {
});
}
- updateCart(event) {
- this.lastActiveInputId = event.target.getAttribute('data-index');
- this.quantity.classList.add('quantity__input-disabled');
+ updateMultipleQty(items) {
this.selectProgressBar().classList.remove('hidden');
+
+ const ids = Object.keys(items);
const body = JSON.stringify({
- quantity: event.target.value,
- id: event.target.getAttribute('data-index'),
+ updates: items,
sections: this.getSectionsToRender().map((section) => section.section),
sections_url: this.getSectionsUrl(),
});
- fetch(`${routes.cart_change_url}`, { ...fetchConfig('javascript'), ...{ body } })
+ fetch(`${routes.cart_update_url}`, { ...fetchConfig(), ...{ body } })
.then((response) => {
return response.text();
})
.then((state) => {
const parsedState = JSON.parse(state);
- this.quantity.classList.remove('quantity__input-disabled');
- if (parsedState.description || parsedState.errors) {
- event.target.setCustomValidity(parsedState.description);
- event.target.reportValidity();
- this.resetQuantityInput(event.target.id);
- this.selectProgressBar().classList.add('hidden');
- event.target.select();
- this.cleanErrorMessageOnType(event);
- return;
- }
-
- this.renderSections(parsedState);
-
+ this.renderSections(parsedState, ids);
publish(PUB_SUB_EVENTS.cartUpdate, { source: 'quick-add', cartData: parsedState });
})
- .catch((error) => {
- console.log(error, 'error');
- });
- }
-
- addToCart(event) {
- this.quantity.classList.add('quantity__input-disabled');
- this.selectProgressBar().classList.remove('hidden');
- this.lastActiveInputId = event.target.getAttribute('data-index');
- const body = JSON.stringify({
- items: [
- {
- quantity: parseInt(event.target.value),
- id: parseInt(this.dataset.id),
- },
- ],
- sections: this.getSectionsToRender().map((section) => section.section),
- });
-
- fetch(`${routes.cart_add_url}`, { ...fetchConfig('javascript'), ...{ body } })
- .then((response) => {
- return response.text();
- })
- .then((state) => {
- const parsedState = JSON.parse(state);
- this.quantity.classList.remove('quantity__input-disabled');
- if (parsedState.description || parsedState.errors) {
- event.target.setCustomValidity(parsedState.description);
- event.target.reportValidity();
- this.resetQuantityInput(event.target.id);
- this.selectProgressBar().classList.add('hidden');
- event.target.select();
- this.cleanErrorMessageOnType(event);
- // Error handling
- return;
- }
-
- this.renderSections(parsedState);
-
- publish(PUB_SUB_EVENTS.cartUpdate, { source: 'quick-add', cartData: parsedState });
+ .catch(() => {
+ // Commented out for now and will be fixed when BE issue is done https://github.com/Shopify/shopify/issues/440605
+ // e.target.setCustomValidity(error);
+ // e.target.reportValidity();
+ // this.resetQuantityInput(ids[index]);
+ // this.selectProgressBar().classList.add('hidden');
+ // e.target.select();
+ // this.cleanErrorMessageOnType(e);
})
- .catch((error) => {
- console.error(error);
+ .finally(() => {
+ this.selectProgressBar().classList.add('hidden');
+ this.requestStarted = false;
});
}
@@ -200,19 +150,9 @@ if (!customElements.get('quick-add-bulk')) {
];
}
- getSectionsUrl() {
- if (window.pageNumber) {
- return `${window.location.pathname}?page=${window.pageNumber}`;
- } else {
- return `${window.location.pathname}`;
- }
- }
-
- getSectionInnerHTML(html, selector) {
- return new DOMParser().parseFromString(html, 'text/html').querySelector(selector).innerHTML;
- }
-
- renderSections(parsedState) {
+ renderSections(parsedState, ids) {
+ const intersection = this.queue.filter((element) => ids.includes(element.id));
+ if (intersection.length !== 0) return;
this.getSectionsToRender().forEach((section) => {
const sectionElement = document.getElementById(section.id);
if (
diff --git a/assets/quick-add.css b/assets/quick-add.css
index b9d889ad5a9..2fb9b2a9f49 100644
--- a/assets/quick-add.css
+++ b/assets/quick-add.css
@@ -355,6 +355,7 @@ quick-add-bulk .progress-bar-container {
overflow: hidden;
border-radius: var(--inputs-radius-outset);
border: var(--inputs-border-width) solid transparent;
+ z-index: -1;
}
quick-add-bulk quantity-input {
diff --git a/assets/quick-order-list.js b/assets/quick-order-list.js
index 45c51cac6e2..433fb6972e8 100644
--- a/assets/quick-order-list.js
+++ b/assets/quick-order-list.js
@@ -137,15 +137,11 @@ if (!customElements.get('quick-order-list')) {
onChange(event) {
const inputValue = parseInt(event.target.value);
- const cartQuantity = parseInt(event.target.dataset.cartQuantity);
- const index = event.target.dataset.index;
-
- const quantity = inputValue - cartQuantity;
this.cleanErrorMessageOnType(event);
if (inputValue == 0) {
- this.startQueue(index, inputValue);
+ this.startQueue(event.target.dataset.index, inputValue);
} else {
- this.validateQuantity(event, index, inputValue, cartQuantity, quantity);
+ this.validateQuantity(event);
}
}
@@ -156,35 +152,6 @@ if (!customElements.get('quick-order-list')) {
});
}
- validateQuantity(event, index, inputValue, cartQuantity, quantity) {
- if (inputValue < event.target.dataset.min) {
- this.setValidity(
- event,
- index,
- window.quickOrderListStrings.min_error.replace('[min]', event.target.dataset.min)
- );
- } else if (inputValue > parseInt(event.target.max)) {
- this.setValidity(event, index, window.quickOrderListStrings.max_error.replace('[max]', event.target.max));
- } else if (inputValue % parseInt(event.target.step) != 0) {
- this.setValidity(event, index, window.quickOrderListStrings.step_error.replace('[step]', event.target.step));
- } else {
- event.target.setCustomValidity('');
- event.target.reportValidity();
- if (cartQuantity > 0) {
- this.startQueue(index, inputValue);
- } else {
- this.startQueue(index, quantity);
- }
- }
- }
-
- setValidity(event, index, message) {
- event.target.setCustomValidity(message);
- event.target.reportValidity();
- this.resetQuantityInput(index);
- event.target.select();
- }
-
validateInput(target) {
if (target.max) {
return (
@@ -261,47 +228,47 @@ if (!customElements.get('quick-order-list')) {
}
renderSections(parsedState, ids) {
- if (ids) {
- this.ids.push(ids)
- }
- const intersection = this.queue.filter(element => ids.includes(element.id));
- if (intersection.length === 0) {
- this.getSectionsToRender().forEach((section) => {
- const sectionElement = document.getElementById(section.id);
- if (
- sectionElement &&
- sectionElement.parentElement &&
- sectionElement.parentElement.classList.contains('drawer')
- ) {
- parsedState.items.length > 0
- ? sectionElement.parentElement.classList.remove('is-empty')
- : sectionElement.parentElement.classList.add('is-empty');
- setTimeout(() => {
- document.querySelector('#CartDrawer-Overlay').addEventListener('click', this.cart.close.bind(this.cart));
- });
- }
- const elementToReplace =
- sectionElement && sectionElement.querySelector(section.selector)
- ? sectionElement.querySelector(section.selector)
- : sectionElement;
- if (elementToReplace) {
- if (section.selector === `#${this.quickOrderListId} .js-contents` && this.ids.length > 0) {
- this.ids.flat().forEach((i) => {
- elementToReplace.querySelector(`#Variant-${i}`).innerHTML =
- this.getSectionInnerHTML(parsedState.sections[section.section], `#Variant-${i}`);
- });
- } else {
- elementToReplace.innerHTML = this.getSectionInnerHTML(
- parsedState.sections[section.section],
- section.selector
- );
- }
- }
+ this.ids.push(ids);
+ const intersection = this.queue.filter((element) => ids.includes(element.id));
+ if (intersection.length !== 0) return;
+
+ this.getSectionsToRender().forEach((section) => {
+ const sectionElement = document.getElementById(section.id);
+ if (
+ sectionElement &&
+ sectionElement.parentElement &&
+ sectionElement.parentElement.classList.contains('drawer')
+ ) {
+ parsedState.items.length > 0
+ ? sectionElement.parentElement.classList.remove('is-empty')
+ : sectionElement.parentElement.classList.add('is-empty');
+ setTimeout(() => {
+ document.querySelector('#CartDrawer-Overlay').addEventListener('click', this.cart.close.bind(this.cart));
});
- this.defineInputsAndQuickOrderTable();
- this.addMultipleDebounce();
- this.ids = []
- }
+ }
+ const elementToReplace =
+ sectionElement && sectionElement.querySelector(section.selector)
+ ? sectionElement.querySelector(section.selector)
+ : sectionElement;
+ if (elementToReplace) {
+ if (section.selector === `#${this.quickOrderListId} .js-contents` && this.ids.length > 0) {
+ this.ids.flat().forEach((i) => {
+ elementToReplace.querySelector(`#Variant-${i}`).innerHTML = this.getSectionInnerHTML(
+ parsedState.sections[section.section],
+ `#Variant-${i}`
+ );
+ });
+ } else {
+ elementToReplace.innerHTML = this.getSectionInnerHTML(
+ parsedState.sections[section.section],
+ section.selector
+ );
+ }
+ }
+ });
+ this.defineInputsAndQuickOrderTable();
+ this.addMultipleDebounce();
+ this.ids = [];
}
getTableHead() {
@@ -394,9 +361,11 @@ if (!customElements.get('quick-order-list')) {
}
}
- updateMultipleQty(items, ids) {
+ updateMultipleQty(items) {
this.querySelector('.variant-remove-total .loading__spinner')?.classList.remove('hidden');
+ const ids = Object.keys(items);
+
const body = JSON.stringify({
updates: items,
sections: this.getSectionsToRender().map((section) => section.section),
@@ -413,7 +382,8 @@ if (!customElements.get('quick-order-list')) {
.then((state) => {
const parsedState = JSON.parse(state);
this.renderSections(parsedState, ids);
- }).catch(() => {
+ })
+ .catch(() => {
this.setErrorMessage(window.cartStrings.error);
})
.finally(() => {
@@ -422,19 +392,6 @@ if (!customElements.get('quick-order-list')) {
});
}
- getSectionsUrl() {
- if (window.pageNumber) {
- return `${window.location.pathname}?page=${window.pageNumber}`;
- } else {
- return `${window.location.pathname}`;
- }
- }
-
- resetQuantityInput(id, quantityElement) {
- const input = quantityElement ?? document.getElementById(`Quantity-${id}`);
- input.value = input.getAttribute('value');
- }
-
setErrorMessage(message = null) {
this.errorMessageTemplate =
this.errorMessageTemplate ??
@@ -513,10 +470,6 @@ if (!customElements.get('quick-order-list')) {
}, 1000);
}
- getSectionInnerHTML(html, selector) {
- return new DOMParser().parseFromString(html, 'text/html').querySelector(selector).innerHTML;
- }
-
toggleLoading(id, enable) {
const quickOrderListItems = this.querySelectorAll(`#Variant-${id} .loading__spinner`);
const quickOrderListItem = this.querySelector(`#Variant-${id}`);
diff --git a/layout/theme.liquid b/layout/theme.liquid
index 963bb22944c..b4bd68d9adc 100644
--- a/layout/theme.liquid
+++ b/layout/theme.liquid
@@ -28,7 +28,6 @@
{% render 'meta-tags' %}
-
diff --git a/snippets/card-product.liquid b/snippets/card-product.liquid
index a12e91e9136..080d897d125 100644
--- a/snippets/card-product.liquid
+++ b/snippets/card-product.liquid
@@ -389,7 +389,7 @@
data-min="{{ card_product.selected_or_first_available_variant.quantity_rule.min }}"
id="quick-add-bulk-{{ card_product.selected_or_first_available_variant.id }}-{{ section.id }}"
class="quick-add-bulk"
- data-id="{{ card_product.selected_or_first_available_variant.id }}"
+ data-index="{{ card_product.selected_or_first_available_variant.id }}"
>
{% render 'quantity-input', variant: card_product.selected_or_first_available_variant, min: 0 %}
@@ -416,7 +416,10 @@
{%- render 'loading-spinner' -%}
-
+