Add button feature
This commit is contained in:
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
12
.idea/add-to-basket.iml
generated
Normal file
12
.idea/add-to-basket.iml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Max Scheme" />
|
||||
</state>
|
||||
</component>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/add-to-basket.iml" filepath="$PROJECT_DIR$/.idea/add-to-basket.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
18
README.md
Normal file
18
README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Add To Basket Button #
|
||||
|
||||
Use the function to generate the markup. Then just insert the button somewhere in your item element.
|
||||
|
||||
### How to use ###
|
||||
|
||||
1. Copy the code, and use **idmAddToBasket** function to generate the markup
|
||||
2. Don't forget to put it somewhere after
|
||||
|
||||
```
|
||||
const afterWhatPaste = document.getElementById('item-container');
|
||||
const idmAddToBasketElement = idmAddToBasket(product, size);
|
||||
afterWhatPaste.insertAdjacentHTML('afterend', idmAddToBasketElement);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Created by • **[IdoMods](https://idomods.pl/)** • 2025
|
||||
92
main.js
Normal file
92
main.js
Normal 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, '&').replace(/</g, '<')
|
||||
.replace(/>/g, '>').replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
53
style.less
Normal file
53
style.less
Normal file
@@ -0,0 +1,53 @@
|
||||
.idm-products-banner__qty {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.idm-products-banner__qty-input {
|
||||
height: 4rem;
|
||||
text-align: center;
|
||||
border: 1px solid #ccc;
|
||||
width: 60%;
|
||||
max-width: unset;
|
||||
min-width: unset;
|
||||
}
|
||||
|
||||
.idm-products-banner__qty button {
|
||||
background: #000;
|
||||
height: 4rem;
|
||||
width: 4rem;
|
||||
color: #fff;
|
||||
border-radius: 0.5rem;
|
||||
min-width: 4rem;
|
||||
}
|
||||
|
||||
.idm-products-banner__add-to-basket {
|
||||
display: flex;
|
||||
align-items: end;
|
||||
flex-direction: column;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.btn.--solid.--medium.idm-products-banner__add-to-basket-button {
|
||||
height: 4rem;
|
||||
background: #000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
.btn.--solid.--medium.idm-products-banner__add-to-basket-link {
|
||||
width: 100%;
|
||||
height: 4rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #000;
|
||||
border: 1px solid #000;
|
||||
margin-top: auto;
|
||||
}
|
||||
Reference in New Issue
Block a user