Files
add-to-basket/main.js
2025-08-14 13:01:01 +02:00

92 lines
3.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @product {object} product information
* @size product size, get form product.sizes.[0]
* @return html markup
**/
function idmAddToBasket(product, size) {
const can = product?.type === 'product' && product?.sizes?.length === 1 && size;
if (!can) return '';
const sellBy = size?.unitSellby || 1;
const precision = size?.unitPrecision || 0;
const max = (typeof size?.amount === 'number' && size.amount > 0) ? size.amount : '';
return `
<div class='idm-products-banner__add-to-basket'>
<form class='idm-products-banner__add-to-basket-form' action='/basketchange.php' method='post'>
<input type='hidden' name='mode' value='1'>
<input type='hidden' name='product' value='${escapeHtml(product.id)}'>
<input type='hidden' name='size' value='${escapeHtml(size.id)}'>
<div class='idm-products-banner__qty'
data-sell-by='${escapeHtml(String(sellBy))}'
data-precision='${escapeHtml(String(precision))}'
data-max='${escapeHtml(String(max))}'>
<button type='button' class='idm-products-banner__qty-decrease'></button>
<input type='number'
name='number'
class='idm-products-banner__qty-input'
value='${escapeHtml(String(sellBy))}'
step='${escapeHtml(String(sellBy))}'
min='${escapeHtml(String(sellBy))}'
max='${escapeHtml(String(max))}'>
<button type='button' class='idm-products-banner__qty-increase'>+</button>
</div>
<button type='submit' class='btn --solid --medium idm-products-banner__add-to-basket-button'>
<span>${<iai:variable vid='Do koszyka' />}</span>
</button>
</form>
</div>`;
}
// +/- i walidacja inputów ilości
document.addEventListener('click', (e) => {
const wrapper = e.target.closest('.idm-products-banner__qty');
if (!wrapper) return;
const input = wrapper.querySelector('.idm-products-banner__qty-input');
const step = parseFloat(wrapper.dataset.sellBy || '1');
const precision = parseInt(wrapper.dataset.precision || '0');
const max = parseFloat(wrapper.dataset.max || '999999');
let current = parseFloat(input.value) || 0;
if (e.target.classList.contains('idm-products-banner__qty-increase')) {
current += step;
if (current > max) current = max;
} else if (e.target.classList.contains('idm-products-banner__qty-decrease')) {
current -= step;
if (current < step) current = step;
}
input.value = current.toFixed(precision);
});
document.addEventListener('blur', (e) => {
if (!e.target.classList.contains('idm-products-banner__qty-input')) return;
const input = e.target;
const wrapper = input.closest('.idm-products-banner__qty');
const step = parseFloat(wrapper.dataset.sellBy || '1');
const precision = parseInt(wrapper.dataset.precision || '0');
const max = parseFloat(wrapper.dataset.max || '999999');
let val = parseFloat(input.value);
if (isNaN(val) || val < step) {
val = step;
} else if (val > max) {
val = max;
} else {
val = Math.round(val / step) * step;
}
input.value = val.toFixed(precision);
}, true);
// helper
const escapeHtml = (v = '') => String(v)
.replace(/&/g, '&amp;').replace(/</g, '&lt;')
.replace(/>/g, '&gt;').replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');