0

I have 2 <p> tags and an input field, wrapped in a while loop

<p id="price"></p>
<input  id="quantity"  oninput="calculate(<?php echo $cprice; ?>)" type="text" name="quantity">
<p id="total"></p>

I want to use JavaScript to perform arithmetic.

I want to multiply price and quantity and display the result in total. Without the while loop, it works but with the while loop, it only updates the first field.

function calculate(price) {
        var quantity = document.getElementById('quantity').value;
        var result = document.getElementById('total');  
        var myResult = price * quantity;
        document.getElementById('total').innerHTML = myResult;
}

I don't know how to dynamically update the total tag with js

3
  • You cannot have duplicate IDs - use a class Commented May 20, 2018 at 10:14
  • 2
    And show us your markup and code with while loop Commented May 20, 2018 at 10:18
  • @u_mulder that is pretty obvious Commented May 20, 2018 at 10:40

2 Answers 2

1

You need to change your IDs to class since IDs must be unique.

See example which is assuming price is alway there

I choose to not use nextElement since you can easily add other stuff to the html without it

I also made the code unobtrusive instead of having inline handlers

document.querySelectorAll(".quantity").forEach(function() {
  this.oninput = function() {
    var q = document.querySelectorAll(".quantity"),
      p = document.querySelectorAll(".price"),
      total = 0;
    q.forEach(function(qt, index) {
      var price = +p[index].innerText,
        quantity = +qt.value;
      if (!isNaN(quantity)) total += price * quantity;
    })
    document.getElementById('total').innerHTML = total;
  }
})
<p class="price">1</p>
<input class="quantity" type="text" name="quantity">
<p class="price">2</p>
<input class="quantity" type="text" name="quantity">
<p class="price">3</p>
<input class="quantity" type="text" name="quantity"><br/>
Total:<p id="total"></p>

Sign up to request clarification or add additional context in comments.

1 Comment

With your code, there's only 1 total. I'm sorry I didn't explain it better, but I want each price and quantity to have its own total
0

IDs need to be unique. If there are duplicates, document.getElementById will return the first one.

Instead of using IDs, use DOM navigation methods. You can pass in this to get a reference to the input element, then find the output element after it.

function calculate(price, input) {
  var quantity = input.value;
  var result = input.nextElementSibling;
  var myResult = price * quantity;
  result.innerHTML = myResult;
}
<p class="price">Price = 30</p>
<input class="quantity" oninput="calculate(30, this)" type="text" name="quantity">
<p class="total"></p>

<p class="price">Price = 45</p>
<input class="quantity" oninput="calculate(45, this)" type="text" name="quantity">
<p class="total"></p>

5 Comments

This code works without styling, the moment i add it to a styled version of the code, it displays the result in a different place. Maybe its because I don't understand the nextElementSibling
It returns the next element that's the child of the same parent. If you add additional elements in between, or wrap them, you'll need to do more complex navigation to match that. jQuery makes this kind of thing easier, using its .closest() and .find() methods.
there's only 1 element in between, how should I navigate?
Real programmers read the documentation if they're not sure how something works. developer.mozilla.org/en-US/docs/Web/API/…
input.nextElementSibling.nextElementSibling

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.