How to efficiently use jQuery to multiply columns of dynamically rendered table - javascript

I'm working on a pretty big table/form that is dynamically created depending on stock availability. The table has 5 fields: Code, Prod.Name, Amount, Price and SubTotal. The user is supposed to set a number in the Amount field and then there's a jQuery script that multiplies that amount for the price to display the SubTotal. In the table, a product looks like this:
<tr>
<td>Princess 01</td>
<td>Conjunto corpiño y cola less <strong>Talle 85</strong></td>
<td><input type="text" id="princess-lingerie-id-963" name="[princess-lingerie][id_963]" value=""></td>
<td>$<input type="text" id="price_princess-lingerie-id-963" value="99" readonly="readonly"/></td>
<td id="subTotal_princess-lingerie-id-963" name="subTotal"></td>
</tr>
My problem is that I have many different products that belong to different product categories, so while this belongs to the "princess-lingerie" (don't laugh) category, a product from the "cosmetica" category looks like this:
<tr>
<td>D02/3</td>
<td>Magic Dual aroma Frutos Rojos</td>
<td><input type="text" id="cosmetica-stock-id-1008" name="[cosmetica-stock][id_1008]" value=""></td>
<td>$<input type="text" id="price_cosmetica-stock-id-1008" value="26" readonly="readonly"/></td>
I have actually already created the little bit of logic which would work for only one field, but I don't know how to extend it to the whole table. Could anyone give me a hand with it? ...I'm a little bit overwhelmed and don't know where to start right now.
$(document).ready(function(){
$("#princess-lingerie-id-963").keyup(function() {
var howMany = parseInt($("#princess-lingerie-id-963").val());
var subTotal = parseInt($("#price_princess-lingerie-id-963").val()) * howMany;
//assign subTotal to the td
$("#subTotal_princess-lingerie-id-963").html(subTotal);
});
});

Shad is right to suggest adding useful classes. To handle the calculations in a sustainable way across a multi-row table, you'll also need a way to generically identify which row you're calculating on. I'm sure this could be greatly improved, but here's a basic example:
The jsfiddle demo is here.
// there are two cells where the 'id' has this pattern, but only one is selectable (the other is read-only)
// still, it would be better to give it a class if at all possible to avoid confusion
// and possible tampering by users
$("input[id*=-id-]").keyup(function() {
var howMany = parseInt($(this).parent().next().find('input').val(), 10);
var subTotal = parseInt($(this).val(), 10) * howMany;
//assign subTotal to the td
$(this).parent().next().next().html(subTotal);
});
EDIT:
Updated to include radix and condition for blank value:
http://jsfiddle.net/RzBeM/2/
$("input[id*=-id-]").keyup(function() {
var howMany = parseInt($(this).parent().next().find('input').val(), 10);
var subTotal = parseInt($(this).val(), 10) * howMany;
if (isNaN(subTotal)) subTotal = 0;
//assign subTotal to the td
$(this).parent().next().next().html(subTotal);
});

First, I would start giving your inputs useful classes, like 'qty' and 'price', and then the final cell can have a class of 'subtotal'. That makes the next step possible:
jQuery('#TABLEID tr').each(function(i,E){
var subT=parseInt(jQuery(E).find('.qty').val(),10) * parseFloat(jQuery(E).find('.price').val());
jQuery(E).find('.subtotal').text('$' + subT.toFixed(2));
});
I use jQuery to iterate over each tr in the table, and run the necessary calculations.
The final solution could use a further tweaked version:
jQuery(function(){
jQuery('.qty').keyup(function(){
var E=jQuery(this).parents('tr').filter(':first');
var subT=parseInt(E.find('.qty').val(),10) * parseFloat(E.find('.price').val());
E.find('.subtotal').text('$' + subT.toFixed(2));
});
});

Related

Calculate quantity and total on an order form in javascript

I'm looking for some help with a bit of code please. I'm supposed to create a form that allows the user to input a quantity for items which they wish to purchase. When the quantity is input, the total price for that particular item is displayed, and the grand total (at the bottom of the form) for all purchases.
When the user presses the submit button, an alert popup appears.
I'm having trouble with the calculation part in javascript. It is not calculating any of the total amount or quantity values.
(For some reason the code won't indent here properly but they are in the actual documents).
function calc(){
var QtyA = 0; var QtyB = 0; var QtyC = 0;
var TotA = 0; var TotB = 0; var TotC = 0;
var PrcA = 3; var PrcB = 4; var PrcC = 5.50;
if (document.getElementById('QtyA').value > "");{
QtyA = document.getElementById('QtyA').value;}
TotA = eval(QtyA) * eval(PrcA);
TotA = TotA.toFixed(2);
(document.getElementById('TotalA').value = TotA);
if (document.getElementById('QtyB').value > "");{
QtyB = document.getElementById('QtyB')value;}
TotB = eval(QtyB) * eval(PrcB);
TotB = TotB.toFixed(2);
(document.getElementById('TotalB').value = TotB);
if (document.getElementById('QtyC').value > "");{
QtyC = document.getElementById('QtyC')value;}
TotC = eval(QtyC) * eval(PrcC);
TotC = TotC.toFixed(2);
(document.getElementById('TotalC')value = TotC);
Totamt = eval(TotA) + eval(TotB) + eval(TotC);
Totamt = Totamt.toFixed(2); //fix to 2 decimal places
(document.getElementById('Grand Total is: ').value = Totamt);
alert (Totamt);
<html>
<head>
<meta charset="UTF-8">
<title>Order Form</title>
<style>
#import "css/OrderForm.css";
</style>
<body>
<form>
<table border="1">
<tr>
<th>Item</th>
<th>Image</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
<tr>
<td width="80">Hat</td>
<td><img src="images/hat.jpg" alt="Hat"></td>
<td><input type="text" id="QtyA" size="5" onchange "calc()"></td>
<td>€3.00</td>
<td>
<input type="text" id="TotalA" size="12" onchange "calc()">
</td>
</tr>
<tr>
<td width="80">T Shirt</td>
<td><img src="images/t_shirt.jpg" alt="Hat"></td>
<td><input type="text" id="QtyA" size="5" onchange "calc()"></td>
<td>€4.00</td>
<td>
<input type="text" id="TotalA" size="12" onchange "calc()">
</td>
</tr>
<tr>
<td width="80">Glasses</td>
<td><img src="images/glasses.jpg" alt="Hat"></td>
<td><input type="text" id="QtyA" size="5" onchange "calc()"></td>
<td>€5.50</td>
<td>
<input type="text" id="TotalA" size="12" onchange "calc()">
</td>
</tr>
<tr>
<td> Total: </td>
<td><input type="text" id="GrandTotal" size="15" onchange="calc()"></td>
</tr>
</table>
<input type="submit" value="Submit">
<input type="reset" value="Reset">
</form>
</body>
</html>
Ok, as a teacher, I just can't let all the bad habits that someone is trying to teach you go. So, here we go....
eval() is EVIL - Don't use it, ever!
eval() tells the JavaScript runtime to process a string as if it were JavaScript. This is very dangerous because if the string contains malicious code, eval() will run it. In your code, you run eval() on the value entered into a text box and since you have no idea what value will be entered, you also have no idea what string eval() will receive. This equates to a huge security hole and is one of the reasons eval() should not be used. Secondly, even in a perfect world, eval() is slow, so from a purely performance standpoint, you wouldn't want to use it. Frankly, I'm shocked that someone taught you to use it and especially for converting strings to numbers. That alone is enough to ask for your money back!
In your case, you need to convert the string input into numbers so that you can do math with the input. JavaScript offers several ways to do this:
parseInt(stringContainingNumber, radix)
parseFloat(stringContainingNumber)
Number(stringContainingNumber)
+stringThatIsNumber Unary Operator
Don't set up your event handling in HTML with event attributes.
When JavaScript was first created (25+ years ago), the way to set up an event handler for an HTML element (a.k.a DOM element) was to use HTML attributes such as onclick, onchange, onmouseover, etc. inline with the element in the HTML. Unfortunately, because of how simple that technique looks it gets used over and over again instead of dying the quick death it deserves. There are several reasons not to use this outdated technique. Today, we have modern standards and best practices to follow and so, event handling should be done in JavaScript, separate from HTML, with .addEventListener()
Also, your code of: onchange "calc()" was incorrect anyway because the code should have been: onchange = "calc()".
Additionally, think about what elements need events set up for them. Your original code had it set up so that if the total gets changed, calc() would run, but that makes no sense. Why would someone be able to change the total directly and what would doing so actually cause to happen? Should the quantity change because the total has changed?
Pay attention to details
You have 3 rows to calculate 3 quantities * 3 prices to get 3 totals, but you just copied/pasted the HTML for the 3 rows and wound up with 3 input elements with the same id of QtyA even though your JavaScript was correctly looking for QtyB and QtyC.
Do your styling with CSS, not HTML
All of your quantity input fields need to have their width set to a size of 5. Don't use the HTML size attribute for that, do it with the width CSS property. The HTML will be cleaner and you won't have to repeat the same instruction 3 times.
#import is being used incorrectly
The CSS #import directive is meant to be used as the first line in external stylesheets that import instructions from another stylesheet, effectively combining multiple sheets into one. If you have only one stylesheet to use, you don't import it, you link to it.
Instead of: <style> #import "css/OrderForm.css";</style>
use: <link href="css/OrderForm.css" rel="stylesheet">
When you are just displaying a result, don't place it into a form field.
There's no reason to put a total into an input field when you don't want the user to be able to modify that result. Instead, just place it as the text of a non-editable element - - in your case the appropriate cell of the table.
Lastly: Use the developer's tools!
All modern browsers incorporate "developer's tools", which you can activate by pressing F12. There are many tabs in the tools, but the "Console" tab is probably the most important for you right now. If you have errors in your syntax (as you did), the Console will show them and the line number. You must eliminate all of your syntax errors before you can expect your code to run.
The Console is also an invaluable tool for testing values in your code. You can insert:
console.log(anything that is supposed to produce a value);
into your code to verify that variables, elements, etc. have the values you think they do.
Now, in reality, I would go about solving this problem in a very different way that you are attempting, but that is more complex than you are ready for at this stage, so I've gone along with your approach somewhat.
Please read through the HTML and JavaScript comments carefully to explain what's being done.
<!DOCTYPE html> <!-- The DOCTYPE tells the browser what version of HTML it should be expecting. -->
<html>
<head>
<meta charset="UTF-8">
<title>Order Form</title>
<!-- To reference a single stylesheet, use the link element: -->
<link href="css/OrderForm.css" rel="stylesheet">
<style>
/* Make all the input elements that have an id that starts with Qty
be 5 characters wide. (Now size=5 isn't needed in the HTML 3 times) */
input[id^=Qty] { width:5em; }
/* The first <td> in each row should be 80px wide. Now we don't have to
clutter up the HTML with this and we don't have to repeat it 3 times. */
td:first-child { width:80px; }
</style>
</head> <!-- You didn't close your <head> tag! -->
<body>
<form>
<table border="1">
<tr>
<th>Item</th>
<th>Image</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
<tr>
<td>Hat</td>
<td><img src="images/hat.jpg" alt="Hat"></td>
<td><input type="text" id="QtyA"></td>
<td>€3.00</td>
<!-- You shouldn't be putting results of calculations into input fields
when you don't want the user to modify the data. Just place it into
an elmeent as its .textContent -->
<td id="TotalA"></td>
</tr>
<tr>
<td>T Shirt</td>
<td><img src="images/t_shirt.jpg" alt="T-Shirt"></td>
<td><input type="text" id="QtyB"></td>
<td>€4.00</td>
<!-- You shouldn't be putting results of calculations into input fields
when you don't want the user to modify the data. Just place it into
an elmeent as its .textContent -->
<td id="TotalB"></td>
</tr>
<tr>
<td>Glasses</td>
<td><img src="images/glasses.jpg" alt="Glasses"></td>
<td><input type="text" id="QtyC"></td>
<td>€5.50</td>
<!-- You shouldn't be putting results of calculations into input fields
when you don't want the user to modify the data. Just place it into
an elmeent as its .textContent -->
<td id="TotalC"></td>
</tr>
<tr>
<td> Total: </td>
<!-- You shouldn't be putting results of calculations into input fields
when you don't want the user to modify the data. Just place it into
an elmeent as its .textContent -->
<!-- You need to have this cell span over the remaining columns of the
table, so colspan=4 needs to be added. -->
<td id="grandTotal" colspan="4"></td>
</tr>
</table>
<!-- Your form doesn't actually submit data anywhere, so you shouldn't
have a submit button. A regular button will do. -->
<input type="button" value="Get Grand Total">
<input type="reset" value="Reset">
</form>
<script>
// Get references to the HTML elements that you'll be working with
var qtyBoxA = document.getElementById('QtyA');
var qtyBoxB = document.getElementById('QtyB');
var qtyBoxC = document.getElementById('QtyC');
var totBoxA = document.getElementById('TotalA');
var totBoxB = document.getElementById('TotalB');
var totBoxC = document.getElementById('TotalC');
var grandTot = document.getElementById('grandTotal');
var btnGetTot = document.querySelector("input[type=button]");
var btnReset = document.querySelector("input[type=reset]");
// Set up event handling in JavaScript, not HTML.
qtyBoxA.addEventListener("change", calc);
qtyBoxB.addEventListener("change", calc);
qtyBoxC.addEventListener("change", calc);
btnGetTot.addEventListener("click", getGrandTotal);
btnReset.addEventListener("click", reset);
var gt = null; // Will hold the grand total
function calc() {
var priceA = 3;
var priceB = 4;
var priceC = 5.50;
gt = 0;
// Convert the values in the quantity textboxes to numbers. The 10 that
// is being passed as the second argument indicates the "radix" or the
// numeric base system that should be used when the string is being
// interpreted. Here (and often), we work in the base 10 numeral system.
var qtyA = parseInt(qtyBoxA.value, 10);
var qtyB = parseInt(qtyBoxB.value, 10);
var qtyC = parseInt(qtyBoxC.value, 10);
// If each of the quantity fields are not empty, calculate the price * quantity
// for that row, place the answer in that row's total field and add the answer
// to the grand total
// NOTE: You had semicolons like this: if(); {}, which is incorrect.
// NOTE: Notice that there are + signs right in front of the total box references?
// this forces a conversion of the string in the text to a number. Since we
// just put a number into the cell, we know for sure it can be converted.
// NOTE: If parseInt() can't parse a number from the string provided, it returns NaN
// (Not A Number), we can check to see if we got NaN with the isNaN() function
// and here, we want to know if we don't have a NaN, so we prepend a ! to it
// (the logical NOT operator) to test the opposite of the isNaN() function result.
if (!isNaN(qtyA)) { totBoxA.textContent = qtyA * priceA; gt += +totBoxA.textContent; }
if (!isNaN(qtyB)) { totBoxB.textContent = qtyB * priceB; gt += +totBoxB.textContent; }
if (!isNaN(qtyC)) { totBoxC.textContent = qtyC * priceC; gt += +totBoxC.textContent; }
grandTot.textContent = gt.toFixed(2); // Just place the answer in an element as its text
}
function getGrandTotal(){
calc(); // Make sure all values are up to date
alert(gt);
}
function reset(){
// The built-in functionality of the <input type=reset> will clear out
// the quantity input fields automatically, but we need to manually reset
// non form field element that have been modified:
totBoxA.textContent = "";
totBoxB.textContent = "";
totBoxC.textContent = "";
grandTot.textContent = "";
}
</script>
</body>
</html>

value of a text box based on the value of other text box

I have an issue where I am trying to build a system where people can see the realtime data like, if I put 500 grams of milk then people can see the value content of fat, sweets , solid in it and for that I have a test box of weight of milk and readonly textboxes for other things like fat, sweet, solids etc.
now I want to update the value of fat,sweet,solids on change of weight of milk
I have achieved it to some extent but the problem is the value keeps on multplying even on decreasing the value of milk .
I am adding the code here please check and any help/ suggestions is deeply appreciated.
HTML
<td><input type="text" name="name" placeholder="Weight" class='smalltextbo onlynumbers' id="w<?=$thedetails_array['sno']?>" onkeyup="return updatevalues(this);" onkeypress="return isNumber(event);"; value='1'/></td>
<td><input type="text" name='fat' value="<?=$thedetails_array['fat']?>" id="fat<?=$thedetails_array['sno']?>" readonly></td>
<td><input type="text" name='sweet' value="<?=$thedetails_array['sweet']?>" id="sweet<?=$thedetails_array['sno']?>" readonly></td>
<td><input type="text" name='solid1' value="<?=$thedetails_array['solid1']?>" id="solid<?=$thedetails_array['sno']?>" readonly></td>
JAVASCRIPT
function updatevalues(vale){
var mainid=$(vale).attr("id");
var onlyidis=mainid.substr(1);
var mainval=$('#w'+onlyidis).val();
var varfatval=$('#fat'+onlyidis).val();
$('#fat'+onlyidis).val(varfatval*mainval);
var varfatval=$('#sweet'+onlyidis).val();
$('#sweet'+onlyidis).val(varfatval*mainval);
}
I have a data of real solids, fat and sweet in 1 gram of milk then update it with the real weight of milk here ...
here is an image
still cant get any solution is there any one who can help me better please ??
Your mistake is that the value of solids will take into account their previous value and multiply it to the value you have.
This is clearly wrong:
var varfatval=$('#fat'+onlyidis).val();
$('#fat'+onlyidis).val(varfatval*mainval);
var varfatval=$('#sweet'+onlyidis).val();
$('#sweet'+onlyidis).val(varfatval*mainval);
since varfatval is the previous value and you multiply mainval with it, instead of multiplying it with the value you need. You should somehow initialize the values you will need, for example like this (use the correct values instead of 12 and 13, respectively):
<script type="text/javascript">
var fat = 12;
var sweet = 13;
</script>
and then use these values for your updates, like this:
function updatevalues(vale){
var mainid=$(vale).attr("id");
var onlyidis=mainid.substr(1);
var mainval=$('#w'+onlyidis).val();
$('#fat'+onlyidis).val(fat*mainval);
$('#sweet'+onlyidis).val(sweet*mainval);
}
You have to empty those input before update that value..
function updatevalues(vale){
var mainid=$(vale).attr("id");
var onlyidis=mainid.substr(1);
var mainval=$('#w'+onlyidis).val();
var varfatval=$('#fat'+onlyidis).val();
$('#fat'+onlyidis).val();
$('#fat'+onlyidis).val(varfatval*mainval);
var varfatval=$('#sweet'+onlyidis).val();
$('#sweet'+onlyidis).val();
$('#sweet'+onlyidis).val(varfatval*mainval);
}
I am trying to build a system where people can see the realtime data like, if I put 500 grams of milk then people can see the value content of fat, sweets [...]
the problem is the value keeps on multiplying even on decreasing the value of milk
As noted by others, If you want to compute the value of different contents based on the input weight in realtime (client-side), you need to store the original multipliers in client-side code.
E.g. if we want to display the amount of fat of an ingredient, and know that the ingredient has 0.4 grams of fat per gram of ingredient, the multiplier is 0.4. When the actual weight changes, we must recompute the content value from its multiplier.
In your code, it appears that you insert the multiplier values from server-side code, but do not store the original multipliers separately for client-side recomputation. You could either store them in JavaScript code, for example like this:
<script>
var milkMultipliers = {
fat: 0.01,
sweetness: 3.2
}
</script>
Or, you could store the multipliers as data attributes of the corresponding HTML elements, e.g. along the lines of the demo code below:
function update(elm){
var ingredient = elm.id;
var computables = ['fat', 'protein', 'carbo'];
for(var i = 0; i < computables.length; i++){
var tableCell = document.getElementById(ingredient + '-' + computables[i]);
var multiplier = tableCell.getAttribute('data-multiplier');
tableCell.innerHTML = (+elm.value) * (+multiplier);
}
}
update(document.getElementById('milk'));
update(document.getElementById('butter'));
th, td{
text-align: left;
padding: 0.4em;
}
body, input{
font-family: sans-serif;
}
<table>
<tr>
<th>Ingredient</th>
<th>Weight</th>
<th>Fat</th>
<th>Protein</th>
<th>Carbohydrates</th>
</tr>
<tr>
<td>Milk</td>
<td>
<input id="milk" onkeyup="update(this)" value="1"/>
</td>
<td id="milk-fat" data-multiplier="0.01"></td>
<td id="milk-protein" data-multiplier="0.034"></td>
<td id="milk-carbo" data-multiplier="0.05"></td>
</tr>
<tr>
<td>Butter</td>
<td>
<input id="butter" onkeyup="update(this)" value="1"/>
</td>
<td id="butter-fat" data-multiplier="0.81"></td>
<td id="butter-protein" data-multiplier="0.009"></td>
<td id="butter-carbo" data-multiplier="0.001"></td>
</tr>
</table>
instead of calculating the content of fat, sweet etc you are just multiplying with the previous value in fat, sweet input boxes.
// calculate amount of fat from milk amount i.e from mainval
$('#fat'+onlyidis).val(calculatedValue);
// calculate amount of sweet from milk amount i.e from mainval
$('#sweet'+onlyidis).val(calculatedValue);

jQuery change number inside a name attribute

I'm writing some JavaScript to clone a table row containing form elements.
It's working well so far but there's one piece I can't quite figure out.
The element names have a number which increases with every row.
E.g:
<table>
<tbody>
<tr>
<td><input type="text" name="name[0][abc]" /></td>
<td><button class="add-row-button">+</button></td>
</tr>
<tr>
<td><input type="text" name="name[1][abc]" /></td>
<td><button class="add-row-button">+</button></td>
</tr>
</tbody>
</table>
I need the cloned row to update the number. There are multiple fields in each row which need this updated number so I can't just include the new name in the jQuery code. What I think has to happen is I need get the name, use a regex replace, then update the attribute.
Here's my current (simplified for the example) jQuery:
// Current num of elements. Names are 0 based so this will be the number used
// for the new name.
var formRowCount = $('table tr').length;
$('.add-row-button').click(function() {
// Clone the last row.
$(this).closest('tr').last().clone().insertAfter($(this).closest('tr'));
// Set the new field selector.
var $newRow = $(this).closest('tr').next();
$newRow.find('input[type="text"]').val('');
formRowCount++;
});
Can someone point me in the right direction. Before formRowCount++; I need to get the current element name and update the number with formRowCount.
Yeah, you can use regex if you want.
var formRowCount = $('table tr').length;
$('.add-row-button').click(function() {
// Clone the last row and insert it.
$(this).closest('tr').last().clone().insertAfter($(this).closest('tr'));
// Select the input field
var $newInput = $(this).closest('tr').next().find('input[type="text"]');
// Update the input value and name attribute
var newName = $newInput.attr('name').replace(/^(name\[)\d+(\].+)$/, '$1' + formRowCount + '$2');
$newInput.val('').attr('name', newName);
// Update the number
formRowCount++;
});

Order Form Line Pricing with jQuery

I have a simple product order form where I'm calculating line totals. The price for a particular product changes based on the quantity being ordered.
So, for 10 or more of "product" the price is $895. For less than 10 the price is $925.
I've got the form calculating my line total when a quantity is entered, but I'm stuck on the conditional statement required for the separate pricing schemes.
Any help is greatly appreciated.
<tr>
<td>G Plus Mariner Sport 36V 250W</td>
<td>$1,299</td>
<td>$925</td>
<td>$895</td>
<td>0</td>
<td><input class="qty" id="qtybox" type="text" /></td>
<td>$<span id="linetotal"></span></td>
$(document).ready(function(){
$('#qtybox').change(function(){
$('#linetotal').text($(this).val() * 925);
});
});
You can use if statement to put condition like this,
Live Demo
$(document).ready(function(){
$('#qtybox').change(function(){
qty = $(this).val()
if(qty < 10)
$('#linetotal').text(qty * 925);
else
$('#linetotal').text(qty * 895);
});
});

Calculation using jquery onkeypress

I have this type of exercise in jquery. Go here http://jsfiddle.net/LAntL/3/
For Item 1, if I add #no of quantity of Size 7, it should be multiplied by Item 1's Price displayed in text box and the result should be shown in Item 1's Ext textbox.
then if I do same for size 8.5 of Item 1, it should perform the same.
But the Ext will have (Price x Size 7 Qty) + (Price x Size 8.5 Qty)
Same will happen for Item 2. And along with this, Total quantity and Total price will be updated on keypress event of each textbox.
I'm a beginner in jquery and got this killing exercise.
Please help someone.
Thanks in advance.
I'd suggest that you assign some classes to your fields so that jQuery can easily find them:
"lineQty" - add this class to all the qty fields
"lineTotal" - add this class to all the line total fields
"linePrice" - I think you can see where I'm going with this
"lineExt" - add to all ext fields
Then the following .keyup function will do the updates on all lines automatically.
$(document).ready(function() {
$(".lineQty").keyup(function() {
// 'this' is the field the user is typing in
// so find the tr that it belongs to
var $row = $(this).closest("tr"),
total = 0,
// get the price for the current row:
price = $row.find(".linePrice").val();
// loop through every qty field for the current row and add
// the entered value to the total, using unary plus to convert
// to a number, and a default of 0 if non-numeric data is entered
$row.find(".lineQty").each(function() {
total += +this.value || 0;
});
// set the total for the current row
$row.find(".lineTotal").val(total);
// set the price for the current row
$row.find(".lineExt").val(total * price);
// now add up the grand totals
var grandTotal = 0,
grandPrice = 0;
$(".lineTotal").each(function() {
grandTotal += +this.value || 0;
});
$(".lineExt").each(function() {
grandPrice += +this.value || 0;
});
$("[name='data[totalQuantity]']").val(grandTotal);
$("[name='data[totalPrice]']").val(grandPrice);
});
});
Working demo: http://jsfiddle.net/LAntL/5/ (only works on the first line because I couldn't be bothered assigning classes to all your fields - you would need to add the classes I talk about above to every field as per what I did for the first line).
Okay, you want to learn something, so I will describe a possible way, and don't give you the finished solution.
First of all, you should mark the tables which contains items with class="item". Now you can write a selector in jQuery which gets every item separately. Then you should mark all cells (<td>) which have a special function. Total, Price, Disc and Ext. Your table should look like this:
<table class="item">
<tr>
<td>...</td>
<td class="total">...</td>
<td class="price">...</td>
<td class="disc">...</td>
<td class="ext">...</td>
</tr>
</table>
Now you can write a selector for all input fields inside of the table with class "item".
$('.item input').change(function(){});
Inside of this function you can handle the calculation. At first I would recommend to get the item:
$('.item input').change(function(){
var item = $(this).closest('table.item');
var totalInput = $(item).find('.total input');
var priceInput = $(item).price('.price input');
// ...
var allWriteableInputs = $(item).find('input[readonly!="readonly"]');
// do the calculation
var sum = 0;
$(allWriteableInputs).each(function(i, input){
sum += $(input).val();
});
$(totalInput).val(sum);
});
If you go this way, you don't need:
The onkeypress="return isNumberKey(event);" and
the id="product1Total" for every inputbox
I hope this thought-provoking impulse helps you a little bit. You have still a long way to go, my young padawan ;-)

Categories

Resources