1

I have the following three inputs:

<input type="text" name="cost" id="cost"  oninput="calculate()" value="">
<input type="text" name="quantity" id="quantity" oninput="calculate()" value="">
<input type="text" name="total" id="total" value="" readonly >

When the price and quantity are entered the following function calculates the total:

function calculate() {
    var price = document.getElementById('cost').value;  
    var num = document.getElementById('quantity').value;
    var total1 = document.getElementById('total');  
    var myResult = price * num;
    total.value = myResult;
}

The three inputs can be repeated an unknown number of times depending on the number of entry's in a database table. I would like to use the same function on all the inputs, but despite searching for hours, I'm no further forward. I believe I will need to use getElementsByName. Any help would be very much appreciated.

talkpoppycock
  • 147
  • 1
  • 9

2 Answers2

3

Use getElementsByClassName()

Use same class name for the repeating inputs and access them using document.getElementsByClassName() function as following:

function calculate() {
 var classes = document.getElementsByClassName('cost').length;
 for(i=0; i< classes; i++)
 {
    var price = document.getElementsByClassName('cost')[i].value;  
    var num = document.getElementsByClassName('quantity')[i].value;

    var myResult = price * num;
    document.getElementsByClassName('total')[i].value = myResult;
 }

}

and your html

  <h2>Group 1:</h2>

<input type="text" name="cost" class="cost" id="cost1"  oninput="calculate()" value="">
<input type="text" name="quantity" class="quantity" id="quantity1" oninput="calculate()" value="">
<input type="text" name="total" class="total" id="total1" value="" readonly >

  <h2>Group 2:</h2>

<input type="text" name="cost" class="cost" id="cost2"  oninput="calculate()" value="">
<input type="text" name="quantity" class="quantity" id="quantity2" oninput="calculate()" value="">
<input type="text" name="total" class="total" id="total2" value="" readonly >

  <h2>Group 3:</h2>

<input type="text" name="cost" class="cost" id="cost3"  oninput="calculate()" value="">
<input type="text" name="quantity" class="quantity" id="quantity3" oninput="calculate()" value="">
<input type="text" name="total" class="total" id="total3" value="" readonly > 

See Demo: http://jsbin.com/kabuduzozo/edit?html,js,output

Shadi Shaaban
  • 1,670
  • 1
  • 10
  • 17
  • +1 and a comment, elements IDs **should** be unique, http://stackoverflow.com/questions/5611963/can-multiple-different-html-elements-have-the-same-id-if-theyre-different-eleme – Okan Kocyigit May 29 '16 at 17:52
  • It's a pretty bad approach. `calculate` should not recalculate totals for all the fields, this is not necessary. Plus requerying the DOM for every change. @Fabricator provided decent solution. – dfsq May 29 '16 at 17:57
  • Agree, @Fabricator is more elegant and lean approach, I gave him +1. – Shadi Shaaban May 29 '16 at 18:00
  • Thanks you Shadi, that was sort of what I thought but couldn't get to. – talkpoppycock May 29 '16 at 18:02
3

Group your inputs together. So given one input, you can easily find the other inputs. Then use calculate(this) instead of calculate(). this in this case refers to the input that was changed.

function calculate(e) {
  var div = e.parentNode;
  var c = div.querySelector('.cost').value;
  var q = div.querySelector('.quantity').value;
  div.querySelector('.total').value = c * q;
}
<div>
  <input type="text" class="cost" oninput="calculate(this)" value="">
  <input type="text" class="quantity" oninput="calculate(this)" value="">
  <input type="text" class="total" value="" readonly>
</div>
<div>
  <input type="text" class="cost" oninput="calculate(this)" value="">
  <input type="text" class="quantity" oninput="calculate(this)" value="">
  <input type="text" class="total" value="" readonly>
</div>
<div>
  <input type="text" class="cost" oninput="calculate(this)" value="">
  <input type="text" class="quantity" oninput="calculate(this)" value="">
  <input type="text" class="total" value="" readonly>
</div>
Fabricator
  • 12,722
  • 2
  • 27
  • 40