Reputation: 1
I'm programming an invoice program. I want to calculate prices row by row. I have a table with rows and columns. A single row consists of 6 columns: "product", "description", "unit cost", "quantity", "vat%" and "total price". VATs can be selected from 4 options in dropdown list.
How to read selected values from dropdown list row by row?
My HTML is like this:
<table id="items">
... ...
... ...
<td><form action="dropdown">
<select id="dropdown-vat">
<option value="0">0%</option>
<option value="10">10%</option>
<option value="14">14%</option>
<option value="24" selected>24%</option>
</select>
</form></td>
... ...
... ...
</table>
I did a JS function like this but it works properly only on the first line.
function update_price() {
var row = $(this).parents('.item-row');
var e = document.getElementById("dropdown-vat");
var vatUser = e.options[e.selectedIndex].value / 100 +1; // THIS IS THE PROBLEM
vatUser = roundNumber(vatUser,2);
var price = row.find('.cost').val().replace("€","") * row.find('.qty').val() * strUser;
price = roundNumber(price,2);
isNaN(price) ? row.find('.price').html("N/A") : row.find('.price').html(price+"€");
The function works properly on the first line. The price is calculated "cost" * "qty" * "1 + selected VAT" For example 10 * 1 * 1.20 = 12. // HERE vat is 20% so 1 + 0.2 = 1.2
The problem appears if user adds a second line. Then the calculator uses vat from the first line.
If the first line is 10 * 1 * 1.2 = 12, Then second line works like this: 10 * 1 * 1.0 = 12. Instead of using 0% (1.0), program uses 20% (1.2, from the first line).
EDIT: Function update_price() is called when user changes a cost (blur), a qty(blur) or a vat(click) value.
Upvotes: 0
Views: 90
Reputation: 2146
Here's how I recently resolved a similar-ish issue - and why you are seeing what you are seeing.....
You get the number from the first line as JS (and, therefore, jQuery) can only have UNIQUE 'ids', so the second line (with the same id) is never read.
To solve it, use a 'combo' of things - namely, use a class for a common listener, then grab the info on a 'change' function.
<select id="dropdown-vat" class="vat">
<option>..... as you have them </option>
</select>
in the script....
$(".vat").change(function() {
var selected = this.selectedOptions[0]);
// now you can get its value, classes, whatever
console.log("value of selected is ", selected.val());
});
There may be more direct ways to get this, though this worked for what I needed.
The point here is that IDs must be unique, so you could also make a unique id for each line, then process the change (similar to what I have shown). If you need the id from that line:
var theIdOfTheSelectedLine = selected.id;
There is likely a lot more to totally answering the question, though this should help you with the main issue (non-unique ids on elements).
Upvotes: 1
Reputation: 3020
You can just use the value of the select element
var e = document.getElementById("dropdown-vat");
e.onchange = function() {
// value of e... this or event.target
console.log(this.value);
console.log(event.target.value);
}
<select id="dropdown-vat">
<option value="0">0%</option>
<option value="10">10%</option>
<option value="14">14%</option>
<option value="24" selected>24%</option>
</select>
EDIT: your question is unclear as we don't know what .item-row
is and we can't see what a cost (blur), a qty(blur)
is about.
My best guess is that following should work:
First change select to use class: <select class="dropdown-vat">
Then, seeing you use jQuery:
function update_price() {
var row = $(this).parents('.item-row'); // the parent table row???
var vatUser = row.find(".dropdown-vat").val();
// etc
}
For dynamically added elements you should use delegated event handlers. Assuming your table already created when running js code:
$("table#items").on("change", ".dropdown-vat", update_price);
Upvotes: 0