Reputation: 148
I have an invoice which is not a table but inside a div in html are some input fields. These fields are being created dynamically by clicking on a button.
<li><input type="text" id="cost[]" name="unit[]" value="<?php echo $val->unit ; ?>"> </li>
<li><input type="text" id="qty[]" name="rate[]" value="<?php echo $val->rate ; ?>"> </li>
<li><input type="text" id="price[]" name="total[]" value="<?php echo $val->total ; ?>"> </li>
Now I want to multiply unit with rate and display it in the total field.
My Javascript is
window.onkeyup=function() {
var str = document.getElementById("cost[]").value;
var str1 = document.getElementById("qty[]").value;
var price = parseFloat(str*str1);
document.getElementById("price[]").value = price;
}
The javascript above works fine but it works only for the first row. For the rest of the rows below the first row, it does not work. I want the calculation for all the rows. I have seen some of the answers but none of them works in my case.
Any help is welcome.
Upvotes: 2
Views: 2937
Reputation: 1960
var invoices = document.querySelectorAll('.invoice')
var handleChange = function (foo, bar, total) {
let str = +foo.value || 0
let str2 = +bar.value || 0
total.value = parseFloat(str*str2)
}
invoices.forEach(function(invoice) {
var foo = invoice.querySelector('input[name=foo]')
var bar = invoice.querySelector('input[name=bar]')
var total = invoice.querySelector('input[name=total]')
foo.addEventListener('keyup', function() {
handleChange(foo, bar, total)
})
bar.addEventListener('keyup', function() {
handleChange(foo, bar, total)
})
})
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo" value="">
<input type="text" name="bar" value="">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
Notice how i prepended a +
to the parse of str
& str2
this operator turns any String
number into a Number
I recommend you do this because when querying the value of a input[type=text]
- it will give you the value represented as a String
...
This is fine when multiplying e.g '1'*'2'// = 2
...
But, if you want to ADD
two numbers together, your sum will be interpreted as concatenation e.g '2'+'2' // = '22'
It may also be smart to default your values to 0 if a value is not provided or a Alphabetic or special character is put into the input e.g 'hello'*'2' // = NaN
try
var str = +foo.value || 0;
var str1 = +bar.value || 0;
var price = parseFloat(str*str1);
Alternatively, make your input type="number"
this will limit the user to only be able to input numbers.
Upvotes: 0
Reputation: 3424
What I observe from your code is that you might be using same ids for multiple items.
The "id" attribute assigns a name to an element. This name must be unique in a document.
Though we have a workaround like:
document.querySelectorAll("[id='someID']");
to select all elements with same "id"s, your HTML will be invalid.
And this is why we have "class" instead. A class is a group of elements.
Though I have used "name" attribute.
May be what you are looking for:
window.onkeyup=function() {
var items = document.querySelectorAll(".item");
var itemsArray = Array.prototype.slice.call(items,0);
var unit, rate, total, net = 0;
itemsArray.forEach(function(el){
unit = el.querySelector('input[name="unit[]"]').value;
rate = el.querySelector('input[name="rate[]"]').value;
total = unit * rate;
el.querySelector('input[name="total[]"]').value = total;
net+=total;
});
document.getElementById('net').value=net;
}
<div class='item'>
<li><input type="text" name="unit[]" value=""> </li>
<li><input type="text" name="rate[]" value=""> </li>
<li><input type="text" name="total[]" value=""> </li>
</div>
<br><br>
<div class='item'>
<li><input type="text" name="unit[]" value=""> </li>
<li><input type="text" name="rate[]" value=""> </li>
<li><input type="text" name="total[]" value=""> </li>
</div>
</br></br>
<li><input id='net' type="text" name="net[]" value=""> </li>
Upvotes: 1
Reputation: 557
As I've stated before, It's not recommended to keep multiple elements with the same id
on your HTML. But if you want to keep things that way, then you can make use of document.querySelectorAll
and iterate over the elements to sum their value and store it in the total:
window.onkeyup=function() {
var costs = document.querySelectorAll("input[id='cost[]'");
var qtys = document.querySelectorAll("input[id='qty[]'");
var price = 0;
for (var i = 0; i < costs.length; i++){
price += +costs[i].value + +qtys[i].value;
}
document.getElementById("price[]").value = price;
}
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<br>
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<br>
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<br>
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<input type="text" id="price[]" name="total[]" value="">
Upvotes: 0