92 lines
3.3 KiB
JavaScript
92 lines
3.3 KiB
JavaScript
/**
|
||
* @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, '&').replace(/</g, '<')
|
||
.replace(/>/g, '>').replace(/"/g, '"')
|
||
.replace(/'/g, '''); |