I am trying to write a block with prices in which the price per unit of goods changes depending on its quantity. Something like that:

 Quantity - Price per unit
 1______________________1 ₽
 10_____________________105 ₽
 20_____________________100 ₽
 ...
 Number of goods:__
 Total:
 Unit price:

There is a need to write an input field in which the user enters the quantity of goods, and all this is recalculated and summed up on the fly.

Here is my implementation:

var price1 = 110, price2 = 105, price3 = 100, qty1 = 1, qty2 = 10, qty3 = 20; function conversion(val) { var div = document.getElementById("div"), price = document.getElementById("price"); if (isNaN(val)) { div.innerHTML = ""; price.innerHTML = ""; } else { switch (true) { case (val <= 0): { div.innerHTML = ""; price.innerHTML = ""; break; } case (val >= qty1 && val < qty2): { div.innerHTML = val * price1; price.innerHTML = price1; break; } case (val >= qty2 && val < qty3): { div.innerHTML = val * price2; price.innerHTML = price2; break; } case (val >= qty3): { div.innerHTML = val * price3; price.innerHTML = price3; break; } } } } 
 <div> <div>1 шт. — 110 ₽</div> <div>10 шт. — 105 ₽</div> <div>20 шт. — 100 ₽</div> </div> <div> Количество товаров: <div> <input id="txt" onblur="conversion(this.value)" onchange="conversion(this.value)" onkeypress="conversion(this.value)" onkeyup="conversion(this.value)" type="number"> </div> </div> <div> Итого: <div id="div"></div> </div> <div> Цена за шт.: <div id="price"></div> </div> 

I ask you to suggest how this can be correctly implemented, given that the lines with the number and price per unit can be from one to infinity (the values ​​are taken from the base). It comes to mind to record the price and quantity in the data artifacts and somehow sort through these lines with the script.

 ... <div data-quantity="1" data-price="115" id="shop"> <span class="quantity">1</span> <span class="price">115</span> </div> ... 

Thank!

    1 answer 1

    I'm not sure that I understood the essence correctly, but try this.

     var prices = { 1: 110, 10: 105, 20: 100 } var pricesDiv = document.getElementById('prices'), countInput = document.getElementById('count'), summarySpan = document.getElementById('summary'), priceSpan = document.getElementById('price'); for (i in prices) { var div = document.createElement('div'); div.innerHTML = i + ' шт. — ' + prices[i] + '₽' pricesDiv.appendChild(div); } function calculate() { var val = parseInt(this.value) || 0 var multiplier; for (i in prices) { if (val < i) { if (multiplier === undefined) { multiplier = prices[i]; } break; } multiplier = prices[i]; } summarySpan.innerHTML = val * multiplier priceSpan.innerHTML = multiplier } countInput.addEventListener('keyup', calculate); countInput.addEventListener('mouseup', calculate); 
     <div id="prices"> </div> <div> <div> Количество товаров: </div> <div> <input id="count" type="number"> </div> </div> <div> Итого: <span id="summary">0</span> </div> <div> Цена за шт.: <span id="price">0</span> </div> 

    Option with data-quantity and data-price

     var countInput = document.getElementById('count'), summarySpan = document.getElementById('summary'), priceSpan = document.getElementById('price'), priceDivs = document.getElementById('prices').getElementsByTagName('div'); var prices = { }; Array.prototype.forEach.call(priceDivs, function(el) { prices[el.getAttribute('data-quantity')] = el.getAttribute('data-price'); }) function calculate() { var val = parseInt(this.value) || 0 var multiplier; for (i in prices) { if (val < i) { if (multiplier === undefined) { multiplier = prices[i]; } break; } multiplier = prices[i]; } Array.prototype.forEach.call(priceDivs, function(el) { if (el.getAttribute('data-price') == multiplier) { el.style.background = "#FF0000" } else { el.style.background = "none" } }) summarySpan.innerHTML = val * multiplier priceSpan.innerHTML = multiplier } countInput.addEventListener('keyup', calculate); countInput.addEventListener('mouseup', calculate); 
     <div id="prices"> <div data-quantity="1" data-price="110">1 шт. — 110₽</div> <div data-quantity="10" data-price="105">10 шт. — 105₽</div> <div data-quantity="20" data-price="100">20 шт. — 100₽</div> </div> <div> <div> Количество товаров: </div> <div> <input id="count" type="number"> </div> </div> <div> Итого: <span id="summary">0</span> </div> <div> Цена за шт.: <span id="price">0</span> </div> 

    • Yes, that's just an example with data-attributes - that’s what you need, thanks! But is it possible for the line whose data-quantity falls into the value entered in the text field to add a style / class? That is, we enter the number 12, and the line with data-quantity="10" is highlighted, and so on. - bakusterus
    • A little edited the second option - Alexander
    • Thank! Only here I would like to clarify to my previous comment that it would be necessary to select the line in which the data-quantity falls into a value in a smaller direction. In general, when entering the number 12 from the example above, you need to select the line 10 шт. — 105₽ 10 шт. — 105₽ . I tried previousElementSibling , but the last line is ignored (well, it is clearly obvious that this method is not appropriate: D). - bakusterus
    • Probably I'm late in the day, but I corrected the code a bit, there was a small logical error - Alexander
    • Now everything is so, thank you very much! - bakusterus