JSFiddle - React, Tailwind, and code Playground
HTML
<div class="item-price-block">
<template id="template">
<li>
<span class="associated-name"></span>
<span class="associated-price"></span>
<div>
<button data-value="-1">–</button>
<input name="quantity" type="number" min="0" value="0" />
<button data-value="1">+</button>
</div>
</li>
</template>
<div id="totalCount" class="total-count">0</div>
<div class="associated-items">
<h5>Список</h5>
<ul id="associatedList"></ul>
</div>
</div>
CSS
.associated-price:after,
.total-count:after {
content: 'грн';
margin-left: .25em;
}
JavaScript
const model = [{
"id": 8632,
"name": "Дверной короб",
"price": 750,
"count": 0
},
{
"id": 8633,
"name": "Комплект наличников",
"price": 300,
"count": 0
},
{
"id": 8634,
"name": "Комплект доборной доски (расширитель)",
"price": 350,
"count": 0
},
{
"id": 3000,
"name": "Установка межкомнатной двери",
"price": 1000,
"count": 0
}
];
const app = document.querySelector('.item-price-block');
const list = document.querySelector('#associatedList');
const template = document.querySelector('#template');
const liElems = model.reduce((frag, data) => {
const li = template.content.cloneNode(true);
li.querySelector('.associated-name').textContent = data.name;
li.querySelector('.associated-price').textContent = data.price;
const input = li.querySelector('input[type="number"]')
input.value = data.count;
input.id = data.id;
frag.appendChild(li);
return frag;
}, document.createDocumentFragment());
list.appendChild(liElems);
app.addEventListener('change', onInputChange);
app.addEventListener('click', onBtnClick);
function onBtnClick({
target
}) {
if (target instanceof HTMLButtonElement) {
const inc = +target.getAttribute('data-value');
const input = target.parentElement.querySelector('input');
setCount(input.id, (prev) => prev + inc);
}
}
function onInputChange({
target
}) {
setCount(target.id, target.value);
}
function setCount(id, val) {
const index = model.findIndex((item) => item.id + '' === id);
if (typeof val === 'function') {
val = val(+model[index].count);
}
if (isNaN(val)) {
throw new TypeError("First argument must be function or number");
}
model[index].count = Math.max(0, val);
const input = document.getElementById(id);
input.value = model[index].count;
getTotalSum();
}
function getTotalSum() {
const total = model.reduce((sum, {
price,
count
}) => {
return sum + price * count;
}, 0);
...