Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 2 additions & 41 deletions src/js/components/useQuantityInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,50 +322,17 @@ const sendUpdateCartRequest = async (updateUrl: string, quantity: number) => {
return response;
};

export const populateMinQuantityInput = (selector = quantityInputMap.default) => {
const qtyInputNodeList = document.querySelectorAll<HTMLElement>(selector);

const products = window.prestashop?.cart?.products;

if (!Array.isArray(products) || products.length === 0) {
return;
}

qtyInputNodeList.forEach((qtyInputWrapper: HTMLElement) => {
const form = qtyInputWrapper.closest('form');
const idProductInput = form?.querySelector<HTMLInputElement>(quantityInputMap.idProductInput);
const qtyInput = qtyInputWrapper.querySelector<HTMLInputElement>('input');

if (!idProductInput || !qtyInput) return;

const idProduct = parseInt(idProductInput.value, 10);
const minAttr = qtyInput.getAttribute('min');

if (!minAttr) return;

const min = parseInt(minAttr, 10);
const productInCart = products.find((p: { id: number }) => p.id === idProduct);

const minimalQuantity = productInCart && productInCart.quantity_wanted >= min ? 1 : min;

qtyInput.setAttribute('min', minimalQuantity.toString());
qtyInput.setAttribute('value', minimalQuantity.toString());
});
};

document.addEventListener('DOMContentLoaded', () => {
const {prestashop, Theme: {events}} = window;

populateMinQuantityInput();

// Delegated keydown: store focus only on Enter key press
document.addEventListener('keydown', (e: KeyboardEvent) => {
const target = e.target as HTMLElement | null;

if (!target) return;

// If Enter key pressed and element is inside productQuantity wrapper, store focus
if (e.key === ENTER_KEY && target.closest(cartSelectorMap.productQuantity)) {
if ((e.key === ENTER_KEY || e.key === ' ' || e.code === 'Space') && target.closest(cartSelectorMap.productQuantity)) {
// Set state.lastUpdateAction to track the last update action
state.set('lastUpdateAction', availableLastUpdateAction.UPDATE_PRODUCT_QUANTITY);
a11y.storeFocus();
Expand All @@ -381,7 +348,7 @@ document.addEventListener('DOMContentLoaded', () => {
// nearest button inside the product quantity wrapper
const btn = target.closest(`${cartSelectorMap.productQuantity} button`) as HTMLElement | null;

if (btn && (e.key === ENTER_KEY || e.key === ' ')) {
if (btn && (e.key === ENTER_KEY || e.key === ' ' || e.code === 'Space')) {
// Set state.lastUpdateAction to track the last update action
state.set('lastUpdateAction', availableLastUpdateAction.UPDATE_PRODUCT_QUANTITY);
a11y.storeFocus();
Expand All @@ -390,16 +357,10 @@ document.addEventListener('DOMContentLoaded', () => {

prestashop.on(events.updatedCart, () => {
useQuantityInput(cartSelectorMap.productQuantity);
populateMinQuantityInput();
});

prestashop.on(events.updateProduct, () => {
populateMinQuantityInput();
});

prestashop.on(events.quickviewOpened, () => {
useQuantityInput(quantityInputMap.modal);
populateMinQuantityInput(quantityInputMap.modal);
});
});

Expand Down
3 changes: 1 addition & 2 deletions src/js/modules/facetedsearch/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* file that was distributed with this source code.
*/

import useQuantityInput, {populateMinQuantityInput} from '@js/components/useQuantityInput';
import useQuantityInput from '@js/components/useQuantityInput';

export const parseSearchUrl = (event: Event): string => {
const target = (event.target as HTMLElement).closest<HTMLElement>('[data-search-url]');
Expand Down Expand Up @@ -123,7 +123,6 @@ export default function initFacetedSearch(): void {
prestashop.on(events.updateProductList, (data: Record<string, unknown>) => {
updateProductListDOM(data);
useQuantityInput();
populateMinQuantityInput();
});

// Listen for color label space key press
Expand Down
2 changes: 1 addition & 1 deletion src/js/modules/ps_searchbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const initSearchbar = () => {

// Add keyboard support for clear button
searchClear?.addEventListener('keydown', (e: KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') {
if (e.key === 'Enter' || e.key === ' ' || e.code === 'Space') {
e.preventDefault();
clearSearch();
}
Expand Down
39 changes: 1 addition & 38 deletions src/js/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,6 @@ export default () => {
prestashop.on(events.updatedProduct, initProductSlide);
prestashop.on(events.quickviewOpened, initProductSlide);

prestashop.on(events.updateCart, (event: UpdateCartEvent) => {
const quantityInput = document.querySelector(
SelectorsMap.qtyInput.quantityWanted,
) as HTMLInputElement;

if (quantityInput) {
const minQuantity = getMinValue(quantityInput);
const quantityInCart = Number(event.resp.quantity) || 0;

if (quantityInCart >= minQuantity) {
quantityInput.setAttribute('min', '1');
quantityInput.setAttribute('value', '1');
}
}
});

function detectQuantityChange() {
const quantityInput = document.querySelector(
SelectorsMap.qtyInput.quantityWanted,
Expand Down Expand Up @@ -78,28 +62,11 @@ export default () => {

const debouncedTriggerEmit = debounce(triggerEmit, 500);

quantityInput.addEventListener('input', (event: Event) => {
const input = event.target as HTMLInputElement;
const minQuantity = getMinValue(input);
const sanitizedValue = sanitizeInputToNumber(input.value);
const clampedValue = clampToMin(sanitizedValue, minQuantity);

if (input.value !== clampedValue.toString()) {
input.value = clampedValue.toString();
}

quantityInput.addEventListener('input', () => {
debouncedTriggerEmit();
});

quantityInput.addEventListener('blur', () => {
const minQuantity = getMinValue(quantityInput);
const sanitizedValue = sanitizeInputToNumber(quantityInput.value);
const clampedValue = clampToMin(sanitizedValue, minQuantity);

if (quantityInput.value !== clampedValue.toString()) {
quantityInput.value = clampedValue.toString();
}

triggerEmit();
});

Expand All @@ -111,10 +78,6 @@ export default () => {

const getMinValue = (input: HTMLInputElement): number => Number(input.getAttribute('min')) || 1;

const sanitizeInputToNumber = (value: string): number => Number(value.replace(/[^\d]/g, '')) || 0;

const clampToMin = (value: number, min: number): number => Math.max(value, min);

// Call the function to start listening for quantity changes
detectQuantityChange();
};
2 changes: 1 addition & 1 deletion templates/catalog/_partials/miniatures/product.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
{include file='components/qty-input.tpl'
attributes=[
"id" => "quantity_wanted_{$product.id_product}",
"value" => "{$product.quantity_required}",
"value" => "{$product.quantity_wanted}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will never work anyway, it will always resolve to quantity_required.

Before PrestaShop/PrestaShop#40570, it wasn't even reliable, that's why I just used quantity_required.

"min" => "{$product.quantity_required}"
]
}
Expand Down