Problem with running totals in jquery
I'm having an issue trying to get an accurate running total for my calculations. When you enter numbers into the input field I get an accurate total for that line item, but the grand total comes out to a higher number. Note that this is a dynamic form and that the id's will change depending on how many form fields I have added to the form. Also, I have it set to make the calculations onKeyUp
for each input field instead of a calculate button.
The code that calculates a single item is this:
function calcLineItem(id) {
var id = $(id).attr("id");
var Item1 = $("#Item1" + id).val();
var Item2 = $("#Item2" + id).val();
var Item3 = $("#Item3" + id).val();
function calcTotal(Item1, Item2, Item3){
var total;
total = Math.round((Item1 * Item2) * Item3);
return total;
}
$("#total" + id).text(calcTotal(Item1, Item2, Item3));
calcAllFields();
}
This will give me the t开发者_JAVA技巧otal of this particular input field. The function at the end, calcAllFields()
, is supposed to do the calculations for all items in my form to give me the grand total of all input fields:
function calcAllFields(id) {
var id = $(id).attr("id");
$('#target1').text($("#total" + id).map(function() {
var currentValue = parseFloat(document.getElementById("currentTotal").value);
var newValue = parseFloat($("#total" + id).text());
var newTotal = currentValue + newValue;
document.getElementById("currentTotal").value = newTotal;
return newTotal;
}).get().join());
}
The variable currentTotal
is getting its value from a hidden field on my form:
<input type="hidden" id="currentTotal" value="0">
As I enter numbers a field the calculation for that line will be accurate, but the grand total will be inaccurate because the value for currentTotal
will continue to increment with every key stroke I make in the input field. Any ideas on how to avoid this from happening?
UPDATE: An example of what the form input fields would look like:
<tr id="row1">
<td><input type="text" id="field_1 onKeyUp="calcLineItem("#row1")></td>
<td><input type="text" id="field_2 onKeyUp="calcLineItem("#row1")></td>
</tr>
I hope this helps.
It appears that you are never removing the previous total when you calculate the grand total. For instance,
I start out with a grand total of 0. I change ID1 and get a total of 700. Now my grand total is 700. However, with your code, if I change ID1 again and set to 680, my grand total will be 1380 (700 + 680).
You should probably start with 0 and loop through all the totals again on calcGrandTotal() in order to pick up all client changes or track the previous total before you calculate the new line item total so that you can properly deduct it from the grand total. Also, if you have a lot of line items adding up to your grand total, you may consider only calling the calcGrandTotal() when on of your textboxes loses focus, else you could have a lot of JS calculations going on in the background which will interfere with animations and overall responsiveness of your site.
How's this?
function calcAllFields(id) {
var id = $(id).attr("id");
document.getElementById("currentTotal").value = 0; //reset the total as it will be caluclated next
$('#target1').text($("#total" + id).map(function() {
var currentValue = parseFloat(document.getElementById("currentTotal").value);
var newValue = parseFloat($("#total" + id).text());
var newTotal = currentValue + newValue;
document.getElementById("currentTotal").value = newTotal;
return newTotal;
}).get().join());
}
I would go about it slightly differently. You will need a function that returns the total for a row (Looks like calcLineItem pretty much does it, just remove the calcAlffields call. Add a class like calcrow to each row that needs to be totaled. Than just do something like this
function updateTotal () {
total = 0;
$.each($(".calcrow"), function(index, value) {
total += calcRow($(value).attr("id"));
});
$("#currentTotal").value(total);
}
Another if you don't want to calc each line again (it looked like you were storing a row total somewhere) have the row update function update the row total and than call this updateTotal.
function updateTotal () {
total = 0;
$.each($(".rowtotal"), function(index, value) {
total += $(value).attr("id");
});
$("#currentTotal").value(total);
}
精彩评论