Click to See Complete Forum and Search --> : Trouble with function to get subtotals


ksp
07-27-2003, 03:59 PM
Hi,

I'm just not any good at javascript, but I'm desperate to get a form up and running by tomorrow morning. As it is, because I can't get the totals to work with an array, I'm doing it the long way.

There are several categories (each need to be subtotaled then all totaled at the end taking into consideration varying tax and shipping rates).

This is the function I'm trying to use to subtotal the Retail and Wholesale Price fields. When I click the UPDATE button, nothing happens.

What am I doing wrong in my calcSubFood() function?




// Calculate the subtotals for the Food Categories

function calcSubFood() {
var f = window.document.mProducts; // f for form
var rFoodSubtotal = (f.rPrice1.value + f.rPrice2.value + f.rPrice3.value);
var wFoodSubtotal = (f.wPrice1.value + f.wPrice2.value + f.wPrice3.value);
f.rSubFood.value = "$" + round(rFoodSubtotal);
f.wSubFood.value = "$" + round(wFoodSubtotal);
}



The HTML is basically this:




<form name="mProducts" action="" method="">

<table width="100%" cellpadding="1" class="wsproducts">
<tr>
<th colspan="8">FOOD PRODUCTS</th>
</tr>
<tr>
<th width="4%">Qty</th>
<th width="8%">Stock No.</th>
<th width="25%">Product</th>
<th width="12%">Retail</th>
<th width="11%">Wholesale</th>
<th width="12%">Total Retail</th>
<th width="12%"><p>Total<br>
Wholesale</p></th>
<th width="16%"> </th>
</tr>
<tr>
<td><input name="qty1" type="text" size="3" onblur="determineRWPrices(this)"></td>
<td><input type="hidden" name="stock" value="100">
100</td>
<td><input type="hidden" name="product" value="Beer Bread">
Old World Beer Bread</td>
<td><input type="hidden" name="drPrice1" value="4.99">
$4.99</td>
<td><input type="hidden" name="dwPrice1" value="3.24">
$3.24</td>
<td><input name="rPrice1" type="text" size="10" readonly="readonly"></td>
<td><input name="wPrice1" type="text" size="10" readonly="readonly"></td>
<td> </td>
</tr>
<tr>
<td><input name="qty2" type="text" id="qty2" size="3" onblur="determineRWPrices(this)"></td>
<td><input type="hidden" name="stock" value="101">
101</td>
<td><input type="hidden" name="product" value="Cranberry Muffins">
Cranberry Orange Muffins</td>
<td><input type="hidden" name="drPrice2" value="5.99">
$5.99</td>
<td><input type="hidden" name="dwPrice2" value="3.89">
$3.89</td>
<td><input name="rPrice2" type="text" id="rPrice2" size="10" readonly="readonly"></td>
<td><input name="wPrice2" type="text" id="wPrice2" size="10" readonly="readonly"></td>
<td> </td>
</tr>
<tr>
<td><input name="qty3" type="text" size="3" onblur="determineRWPrices(this)"></td>
<td><input type="hidden" name="stock" value="110">
110</td>
<td><input type="hidden" name="product" value="BBQ Dip">
BBQ & Dipping Sauce</td>
<td><input type="hidden" name="drPrice3" value="5.99">
$5.99</td>
<td><input type="hidden" name="dwPrice3" value="3.89">
$3.89</td>
<td><input name="rPrice3" type="text" size="10" readonly="readonly"></td>
<td><input name="wPrice3" type="text" size="10" readonly="readonly"></td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td colspan="3"><div align="right"><strong>Subtotal Food Items:</strong></div></td>
<td><input name="rSubFood" type="text" size="10"></td>
<td><input name="wSubFood" type="text" size="10"></td>
<td><input type="button" value="UPDATE" onclick="calcSubFood(); return false;" name="button"></td>
</tr>
<tr>
<td> </td>
<td> </td>
<td colspan="3"><div align="right"><strong>Enter Your State's Non-Food Tax
Rate, <br />
If Applicable:</strong></div></td>
<td><input type="text" name="nonfood tax" size="10"></td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td colspan="3"><div align="right"><strong>Total Food Products: </strong></div></td>
<td><input name="rSubFood" type="text" size="10" onFocus="subRetailFood();"></td>
<td><input name="wSubFood" type="text" size="10"></td>
<td><input type="button" value="UPDATE" onClick="calcTotalFood(); return false;" name="button"></td>
</tr>
<tr>
<td> </td>
<td> </td>
<td colspan="5"> </td>
<td> </td>
</tr>


Any help is very much appreciated...

David Harrison
07-27-2003, 05:43 PM
Well I haven't waded through all of your HTML because I spotted an error in your script. You put:f.rSubFood.value = "$" + round(rFoodSubtotal);
What you should have put is:
f.rSubFood.value = "$" + Math.round(rFoodSubtotal);

But are you aware that this will round it to the nearest whole number, if you want to round it to the nearest hundredth use this:

f.rSubFood.value = "$" + rFoodSubtotal.toFixed(2);

Khalid Ali
07-27-2003, 05:47 PM
You can probably tell the I had some time on hand..:D

Here is the complete working code..I have presumed few things that you might be doing and made the code work.


<script type="text/javascript">

<!--
function Process(){
var frm = document.getElementById("form1");
var len = frm.length;
}

// Calculate the subtotals for the Food Categories

function calcSubFood() {
var frm = document.mProducts; // f for form
var rFoodSubtotal = (parseFloat(frm.rPrice1.value) + parseFloat(frm.rPrice2.value) + parseFloat(frm.rPrice3.value));
var wFoodSubtotal = (parseFloat(frm.wPrice1.value) + parseFloat(frm.wPrice2.value) + parseFloat(frm.wPrice3.value));

frm.rSubFood.value = (rFoodSubtotal).toFixed(2);
frm.wSubFood.value = (wFoodSubtotal).toFixed(2);
}

function calcTotalFood(){
var frm = document.mProducts; // f for form
var rFoodSubtotal = (parseFloat(frm.rPrice1.value) + parseFloat(frm.rPrice2.value) + parseFloat(frm.rPrice3.value));
var wFoodSubtotal = (parseFloat(frm.wPrice1.value) + parseFloat(frm.wPrice2.value) + parseFloat(frm.wPrice3.value));
validateNum(frm.nonfoodtax);
var nft = parseFloat(frm.nonfoodtax.value);
frm.rTotalFood.value = ((rFoodSubtotal * nft) + rFoodSubtotal).toFixed(2);
frm.wTotalFood.value = ((wFoodSubtotal * nft) + wFoodSubtotal).toFixed(2);
}
function determineRWPrices(obj){
var quantity = obj.value;
validateNum(obj);
var data = getIndex(obj.name);
var nqty = parseInt(quantity);
var frm = document.mProducts;
(eval('frm.rPrice'+data[0])).value = (nqty * data[1]).toFixed(2);
(eval('frm.wPrice'+data[0])).value = (nqty * data[2]).toFixed(2);
}

function validateNum(obj){
var quantity = obj.value;
if(isNaN(Number(quantity))){
alert("Quantity is not a valid numerical value.")
obj.focus();
obj.select();
return false;
}
return true;
}

function getIndex(obj){
switch(obj){
case 'qty1':
return new Array(1,4.99,3.24);
break;
case 'qty2':
return new Array(2,5.99,3.89);
break;
case 'qty3':
return new Array(3,5.99,3.89);
break;
}
}
//-->
</script>
</head>

<body>
<form name="mProducts" action="" >

<table width="100%" cellpadding="1" class="wsproducts">
<tr>
<th colspan="8">FOOD PRODUCTS</th>
</tr>
<tr>
<th width="4%">Qty</th>
<th width="8%">Stock No.</th>
<th width="25%">Product</th>
<th width="12%">Retail</th>
<th width="11%">Wholesale</th>
<th width="12%">Total Retail</th>
<th width="12%"><p>Total<br>
Wholesale</p></th>
<th width="16%"> </th>
</tr>
<tr>
<td><input name="qty1" type="text" size="3" onkeyup="determineRWPrices(this)"></td>
<td><input type="hidden" name="stock" value="100">
100</td>
<td><input type="hidden" name="product" value="Beer Bread">
Old World Beer Bread</td>
<td><input type="hidden" name="drPrice1" value="4.99">
$4.99</td>
<td><input type="hidden" name="dwPrice1" value="3.24">
$3.24</td>
<td><input name="rPrice1" type="text" size="10" readonly="readonly"></td>
<td><input name="wPrice1" type="text" size="10" readonly="readonly"></td>
<td> </td>
</tr>
<tr>
<td><input name="qty2" type="text" id="qty2" size="3" onkeyup="determineRWPrices(this)"></td>
<td><input type="hidden" name="stock" value="101">
101</td>
<td><input type="hidden" name="product" value="Cranberry Muffins">
Cranberry Orange Muffins</td>
<td><input type="hidden" name="drPrice2" value="5.99">
$5.99</td>
<td><input type="hidden" name="dwPrice2" value="3.89">
$3.89</td>
<td><input name="rPrice2" type="text" id="rPrice2" size="10" readonly="readonly"></td>
<td><input name="wPrice2" type="text" id="wPrice2" size="10" readonly="readonly"></td>
<td> </td>
</tr>
<tr>
<td><input name="qty3" type="text" size="3" onkeyup="determineRWPrices(this)"></td>
<td><input type="hidden" name="stock" value="110">
110</td>
<td><input type="hidden" name="product" value="BBQ Dip">
BBQ & Dipping Sauce</td>
<td><input type="hidden" name="drPrice3" value="5.99">
$5.99</td>
<td><input type="hidden" name="dwPrice3" value="3.89">
$3.89</td>
<td><input name="rPrice3" type="text" size="10" readonly="readonly"></td>
<td><input name="wPrice3" type="text" size="10" readonly="readonly"></td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td colspan="3"><div align="right"><strong>Subtotal Food Items:</strong></div></td>
<td><input type="text" name="rSubFood" size="10"></td>
<td><input type="text" name="wSubFood" size="10"></td>
<td><input type="button" value="UPDATE" onclick="calcSubFood();" name="button"></td>
</tr>
<tr>
<td> </td>
<td> </td>
<td colspan="3"><div align="right"><strong>Enter Your State's Non-Food Tax
Rate, <br />
If Applicable:</strong></div></td>
<td><input type="text" name="nonfoodtax" size="10"></td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td colspan="3"><div align="right"><strong>Total Food Products: </strong></div></td>
<td><input name="rTotalFood" type="text" size="10" onFocus="subRetailFood();"></td>
<td><input name="wTotalFood" type="text" size="10"></td>
<td><input type="button" value="UPDATE" onClick="calcTotalFood();" name="button"></td>
</tr>
<tr>
<td> </td>
<td> </td>
<td colspan="5"> </td>
<td> </td>
</tr>

ksp
07-27-2003, 06:55 PM
Khalid, thanks! I must admit, I'm glad you have time on hand... I've spent all mine on this but without the skills to go further and where I need to be by tomorrow morning.

It works great! Wow! The only thing I noticed is that if the quantity is entered on only one item, when the update button is clicked, the subtotal and total fields read NaN. How to get around that?

I'm trying to understand all the code so that I can add more items and categories, and hopefully get it to the grand total when shipping is added.

Thanks so very much!

Kathy

ksp
07-27-2003, 07:01 PM
Lavalamp, thank you too. I was over the character limit on the original post, I think, and didn't include the function for rounding:

function round (n, d) {
n = n - 0;
d = d || 2;
var f = Math.pow(10, d);
n = Math.round(n * f) / f;
n += Math.pow(10, - (d + 1));
n += '';
return d == 0 ? n.substring(0, n.indexOf('.')) :
n.substring(0, n.indexOf('.') + d + 1);
}

But I know in some version of this I've worked on that it wasn't rounding correctly at all times (2 + 15 would equal 18, for example) so I appreciate the code.

Thanks,
Kathy

Khalid Ali
07-27-2003, 07:33 PM
Here ya go..replace the whole javascript part of the code with the one below


<script type="text/javascript">

<!--
// Calculate the subtotals for the Food Categories

function calcSubFood() {

var frm = document.mProducts; // f for form
//alert(validateNum(frm.rPrice2))
var rFoodSubtotal = parseFloat(validateNum(frm.rPrice1)) +
parseFloat(validateNum(frm.rPrice2)) +
parseFloat(validateNum(frm.rPrice3));
var wFoodSubtotal = parseFloat(validateNum(frm.wPrice1)) +
parseFloat(validateNum(frm.wPrice2)) +
parseFloat(validateNum(frm.wPrice3));

frm.rSubFood.value = (rFoodSubtotal).toFixed(2);
frm.wSubFood.value = (wFoodSubtotal).toFixed(2);
}

function calcTotalFood(){
var frm = document.mProducts; // f for form
var rFoodSubtotal = parseFloat(validateNum(frm.rPrice1)) +
parseFloat(validateNum(frm.rPrice2)) +
parseFloat(validateNum(frm.rPrice3));
var wFoodSubtotal = parseFloat(validateNum(frm.wPrice1)) +
parseFloat(validateNum(frm.wPrice2)) +
parseFloat(validateNum(frm.wPrice3));

var nft = parseFloat(validateNum(frm.nonfoodtax));
frm.rTotalFood.value = ((rFoodSubtotal * nft) + rFoodSubtotal).toFixed(2);
frm.wTotalFood.value = ((wFoodSubtotal * nft) + wFoodSubtotal).toFixed(2);
}
function determineRWPrices(obj){
var quantity = obj.value;
var nqty = parseInt(validateNum(obj));
var data = getIndex(obj.name);
var frm = document.mProducts;
(eval('frm.rPrice'+data[0])).value = (nqty * data[1]).toFixed(2);
(eval('frm.wPrice'+data[0])).value = (nqty * data[2]).toFixed(2);
}

function validateNum(obj){
var quantity = obj.value;
if(isNaN(Number(quantity))){
alert("Quantity is not a valid numerical value.")
obj.focus();
obj.select();
return false;
}

return Number(quantity);
}

function getIndex(obj){
switch(obj){
case 'qty1':
return new Array(1,4.99,3.24);
break;
case 'qty2':
return new Array(2,5.99,3.89);
break;
case 'qty3':
return new Array(3,5.99,3.89);
break;
}
}
//-->
</script>

ksp
07-27-2003, 07:58 PM
Thanks again!!! That works perfectly.

To add another category, would I just repeat the code, substituting new values (i.e., Candle Category, wcPrice2 instead of wPrice2, etc?)


function calcSubCandles() {
var frm = document.mProducts; // f for form
var rCandlesSubtotal = (parseFloat(frm.rcPrice1.value) + parseFloat(frm.rcPrice2.value) + parseFloat(frm.rcPrice3.value));
var wCandleSubtotal = (parseFloat(frm.wcPrice1.value) + parseFloat(frm.wcPrice2.value) + parseFloat(frm.wcPrice3.value));

frm.rSubCandle.value = (rCandleSubtotal).toFixed(2);
frm.wSubCandle.value = (wCandleSubtotal).toFixed(2);
}



Logically it seems like it should to me, but I don't know if there's something that might conflict doing it that way...

Thanks again and bless you!