0

Currently i can input a value into a number box and it would calculate the quantity * Price, into a subtotal field. I'm having an issue where i would like the subtotal calculated after i click on (+) and (-) buttons. what is happening is after i click the button it wont calculate the number in the quantity box, only the previous number that was there. i.e- when i click (+) it will display 1 in the quantity field, but subtotal wont change. i click (+) again the quantity will display 2, but the subtotal will display $99 which is the price of a single product. it should be displaying $198.

var total_items = 1;
    function CalculateItemsValue() {
    var total = 0;

    for (i=1; i<=total_items; i++) {
         
        itemID = document.getElementById("qnt_"+i);
        if (typeof itemID === 'undefined' || itemID === null) {
            alert("No such item - " + "qnt_"+i);
        } else {
            total = total + parseInt(itemID.value) * parseInt(itemID.getAttribute("data-price"));
        }
        }
         
    
    document.getElementById("ItemsTotal").innerHTML = "$" + total;
     }
<input type="button" value="-" class="qtyminus" field="qnt_1" onmouseup="CalculateItemsValue()">
<input type="number" name="qnt_1" id="qnt_1" value="0" class="qty" data-price="99.95" onkeyup="CalculateItemsValue()" oninput="validity.valid||(value='');">
<input type="button" value="+" class="qtyplus" field="qnt_1" onmouseup="CalculateItemsValue()">
<div id="ItemsTotal">$0</div>
James
  • 20,957
  • 5
  • 26
  • 41

1 Answers1

0

You didn't include any HTML for the ItemsTotal.

This is a lot simpler than what you are doing. The key is setting up the correct event handlers. You have 2 buttons and the input, so 3 ways that the quantity could be changed. So, you need to set up 3 event handlers. But, don't do the event handling in the HTML, do it in the JavaScript (more on that below).

A couple of notes:

  • Don't use inline HTML event handling attributes (onclick, etc.). There are many reasons why you should not use this ancient technique.
  • Don't use .innerHTML unless the string you are setting has HTML in it. Otherwise, you are just asking the browser to parse HTML when there isn't any. Use .textContent for strings that have no HTML in them.
  • parseInt() isn't necessary on an input type="number" since only numbers can be entered. All you need to do to convert the value is prepend a + on to the value.
  • We can do currency formatting with JavaScript, so no need to concatenate $ into the result of your math.

See the comments for explanations:

// Get references to DOM elements:
var minusBtn = document.querySelector(".qtyminus");
var plusBtn = document.querySelector(".qtyplus");
var input = document.getElementById("qnt_1");
var total = document.getElementById("total");

// Get the data-price and convert to a number
var price = +input.dataset.price;

// Set up event handlers that call a common function with an 
// argument that specifies what kind of operation to perform:
minusBtn.addEventListener("click", function() { calc("subtract"); });
plusBtn.addEventListener("click", function() { calc("add"); });
input.addEventListener("input", calc);

// Single function to perform all calculations
// dependant on the argument pased
function calc(operation) {
  if(operation === "add"){
     input.value = +input.value + 1;
  } else  if(operation === "subtract"){
     // Set value, but don't let it go below zero
     input.value = (input.value - 1 < 1) ? 0 : input.value -1;    
  }
  
  // Update the total no matter what and format the result
  // in the US currency format
  total.textContent = (input.value * price).toLocaleString("en-us", { style: "currency", currency: "USD" });
}
<input type="button" value="-" class="qtyminus" field="qnt_1">
<input type="number" name="qnt_1" id="qnt_1" min="0" value="0" class="qty" data-price="99.95">
<input type="button" value="+" class="qtyplus" field="qnt_1">
<div>Your total is: <span id="total"></span></div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • This will work fine if there is only one of these widgets per page. It could easily be modified to handle multiple widgets. – James Feb 08 '18 at 23:58
  • 1
    @James That was never a requirement stated in the question. – Scott Marcus Feb 08 '18 at 23:59
  • Not in the question but in the code. `for (i=1; i<=total_items; i++)` If total_items == 1 then your solution is great. – James Feb 09 '18 at 00:33
  • @James ?? What is it you are trying to say? I thin the solution is pretty great already. – Scott Marcus Feb 09 '18 at 00:41
  • Thank you Scott for the detailed explanation. I appreciate it. – Juniortear Feb 09 '18 at 04:01
  • if i wanted to take this a step further and have the span sent into the submitted form. how would i do this? – Juniortear Feb 12 '18 at 05:03
  • @Juniortear You can't include a `span`s data in a form's submit, but you can create an `` and then add one more line to the code I've already shown: `document.querySelector('input[type=hidden]').value = total.textContent`. Then, when you submit the form, the hidden form field will submit its data. – Scott Marcus Feb 12 '18 at 23:25