Add button feature

This commit is contained in:
2025-08-14 13:01:01 +02:00
commit bd567d0788
7 changed files with 196 additions and 0 deletions

92
main.js Normal file
View File

@@ -0,0 +1,92 @@
/**
* @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;');