Click to See Complete Forum and Search --> : Adding Values of Dynamically Generated Rows


sharapov
03-24-2003, 08:31 PM
Hello,

It seems that I hit a brick wall and need your help. I am generating a table from a database and I want to be able to sum one of the columns and display the result once the page loads. Look at the sample table here (http://home.pacbell.net/sharapov/example.htm) Also I want total value to update if user makes change to one or all of the fields in that column. I can't use T1.value + T2.value (for example) because as I said all data is taken from database, and I simply don't know which Item is going to show up. Can anybody help me with this?

Thanks.

dabush
03-24-2003, 10:09 PM
Hera ya go.

Step 1:
THIS IS VERY IMPORTANT
You forgot the <form> </form> tags
In the generator,
Before <table>, add <form name=pricesform>
After </table>, add </form>

Step 2:
This is the code. It is a smart code. It tells it to add the prices up at the beginning, and when a user edits a price, it will reformat that price with the $ symbol, and then recalc the total. check it out.

Add the following between <head> and </head>

<script language=JavaScript type=text/javascript>
<!--
function addPrices()
{
var ear = window.document.pricesform.elements;
var sum = 0;
var nums = '0123456789-.';
for (var loop = 0; loop < (ear.length-1); loop++)
{
for (var loop2 = 0; loop2 < ear[loop].value.length; loop2++)
{
var x1 = 0;
if (nums.indexOf(ear[loop].value.charAt(loop2)) != -1)
{
var x1 = loop2;
loop2 = ear[loop].value.length;
}
}
for (var loop3 = 0; loop3 < ear[loop].value.substring(x1,ear[loop].value.length).length; loop3++)
{
var x2 = ear[loop].value.length;
if (nums.indexOf(ear[loop].value.substring(x1,ear[loop].value.length).charAt(loop3)) == -1)
{
var x2 = x1 + loop3;
loop3 = ear[loop].value.substring(x1,ear[loop].value.length).length
}
}
var thenum = eval(ear[loop].value.substring(x1,x2));
var numstr = thenum*100;
var numstr = numstr.toString();
var numstr = numstr.substring(0,(numstr.length-2))+'.'+numstr.substring((numstr.length-2),numstr.length);
ear[loop].value = '$' + numstr;
sum += eval(thenum);
window.document.pricesform.elements[loop].onchange=addPrices;
}
var sumstr = sum*100;
var sumstr = sumstr.toString();
var sumstr = sumstr.substring(0,(sumstr.length-2))+'.'+sumstr.substring((sumstr.length-2),sumstr.length);
ear[ear.length-1].value = '$'+sumstr;
}
window.onload=addPrices;
// -->
</script>

dabush
03-24-2003, 10:19 PM
if you followed what i said to do correctly, it should work (i tested it). but let me know what happens.

sharapov
03-25-2003, 06:44 PM
dabush,

Thank you very much for your help. It looks exactly what I was looking for. The code works great, but I found a few small bugs. One bug is if you change part of the already existed number (ex. if replace 1.39 with 1.391) the total will be wrong. Also if replace 6.24 with 6.21 the total result will be wrong.

Look at the examples here: http://home.pacbell.net/sharapov/example.htm

The other bug that I found (which is not a big one) is ability of user to make change to the total sum. I dealt with this issue by making field not editable.

Finally it would be nice if user wouldn't be able to type any characters but numbers in the field.

If you could help me with those issues, I'll really appreciate it.

P.S. Sorry for the double post, I thought I would get better answers if I post to both DHTML and JavaScript forums.

dabush
03-25-2003, 07:45 PM
i got it, which i am very suprised. before i give u the code, IT IS IMPERATIVE THAT THIS FORM (named pricesform) DOES NOT CONTAIN ANY OTHER ELEMENTS BESIDS THE TEXTBOXES FOR EACH ITEM AND THE TEXT BOX FOR THE TOTAL. If it does, everything will be messed up.

now that that has been said, here is what i fixed:
1. the bug where if you enter an extra number in the box. now it just disreguard any extra numbers
2. the bug where if certain numbers are entered in the price boxes, the total is messed up
3. It will only allow numbers, decimal points, and dollar signs in the text boxes. the script is smart with the decimals: it will only allow one to be typed if the text box does not already have a decimal in it). it is also smart with dollar signs (it will only allow them if the box is empty - this restricts the box to only 1 dollar sign, and it must be at the beginning).

And just overwrite the old script with this one


<script language=JavaScript type=text/javascript>
<!--
function addPrices()
{
var ear = window.document.pricesform.elements;
var sum = 0;
var nums = '0123456789-.';

for (var loop = 0; loop < (ear.length-1); loop++)
{
for (var loop2 = 0; loop2 < ear[loop].value.length; loop2++)
{
var x1 = 0;
if (nums.indexOf(ear[loop].value.charAt(loop2)) != -1)
{
var x1 = loop2;
loop2 = ear[loop].value.length;
}
}
for (var loop3 = 0; loop3 < ear[loop].value.substring(x1,ear[loop].value.length).length; loop3++)
{
var x2 = ear[loop].value.length;
if (nums.indexOf(ear[loop].value.substring(x1,ear[loop].value.length).charAt(loop3)) == -1)
{
var x2 = x1 + loop3;
loop3 = ear[loop].value.substring(x1,ear[loop].value.length).length
}
}
var thenum = eval(ear[loop].value.substring(x1,x2));
var numstr = thenum*100;
var numstr = parseInt(numstr);
var numstr = numstr.toString();
var numstr = numstr.substring(0,(numstr.length-2))+'.'+numstr.substring((numstr.length-2),numstr.length);
ear[loop].value = '$' + numstr;
sum += eval(numstr);
window.document.pricesform.elements[loop].onblur=endRestrict;
window.document.pricesform.elements[loop].onfocus=startRestrict;
window.document.pricesform.elements[loop].onchange=addPrices;
}
var sumstr = Math.round(sum*100);
var sumstr = sumstr.toString();
var sumstr = sumstr.substring(0,(sumstr.length-2))+'.'+sumstr.substring((sumstr.length-2),sumstr.length);
ear[ear.length-1].value = '$'+sumstr;
}
var textfocus = 0;
function startRestrict()
{
textfocus = 1;
}
function endRestrict()
{
textfocus = 0;
}
function keyLogger()
{
var k = event.keyCode;
if (textfocus == 1)
{
if (((k<48)||(k>57))&&(k!=46)&&(k!=36)) return false;
if ((k==46)&&(event.srcElement.value.indexOf('.') != -1)) return false;
if ((k==36)&&(event.srcElement.value.length != 0)) return false;
}
}
window.onload=addPrices;
window.document.onkeypress=keyLogger;
// -->
</script>

dabush
03-25-2003, 07:46 PM
just like last time: let me know how it works. im interested!

sharapov
03-26-2003, 08:51 PM
dabush,

Once again thank you for your reply.
Now script works correctly. However, (and this is probably my fault, because I didn't think ahead) this code is limited to the one column of text fields. As you said:
IT IS IMPERATIVE THAT THIS FORM (named pricesform) DOES NOT CONTAIN ANY OTHER ELEMENTS BESIDS THE TEXTBOXES FOR EACH ITEM AND THE TEXT BOX FOR THE TOTAL. If it does, everything will be messed up.

But what if I need to add another field to this table. For example quantity. Look at the example here: http://home.pacbell.net/sharapov/example.htm
Based on your code it can't be done, because total will be messed up. I think I need a different approach to my problem. What if I give the name or id's to the text fields. The names/ids will correspond to the unique number with the letter in front of it. The unique number could be item id for example. Therefore I will end up with the text field that will look something like this:

<input type="text" name="A123456" size="12" value="123456">
<input type="text" name="B123456" size="12" value="Some Item 1">
<input type="text" name="C123456" size="12" value="1">
<input type="text" name="D123456" size="12" value="$1.39">
<input type="text" name="E123456" size="12" value="$1.39">

That just for the first row. The second row and so on will have it's own numbers. (Look at the example page) Now I can loop through the columns referring to name/ids of the text fields and get desirable result. What do you think? Is my approach too complicated? Is there other solution to this problem? I really appreciate your response.

P.S. Let me very briefly explain what I am trying to achieve (so that you have better understanding). I am trying to do a system that would allow users to e-mail or print quotes of the product (that is why I want user to be able to change the price). Once the price quantity is changed I want to send all results to a new "clean" page (where user won't be able to make any changes) for printing or e-mailing. And that is the reason why all my data is displayed in the text boxes. Unfortunately I got stuck with the calculating feature :(. And I really appreciate you helping me!!!

dabush
03-26-2003, 09:46 PM
i see that you had your generator name each of the form fields a letter corresponding to the column number + the item number. for example D123456.

i want you to edit your generator so that the name of inputs in the columns that have the prices is changed to "price"+item number.

let me explain this...in your example, the column that has the price is column D (name=D123456). only for the column that contains the prices, have your generator name the inputs price+item number

so, for the first item (item # = 123456). your generator you make the name of the input that contains the price (name="price123456")

the generator should name the input that contains the price for the second item (name="price246810")

you get the gist? good!

i noticed that you already named the input that contains the toal price (name="price"). this is PERFECT. just keep it like that.

good... now just replce the code with this...


<script language=JavaScript type=text/javascript>
<!--
function addPrices()
{
var ear = new Array();
for (var test = 0; test < window.document.pricesform.elements.length; test++)
{
if (window.document.pricesform.elements[test].name.substring(0,5) == 'price') ear[ear.length] = window.document.pricesform.elements[test];
}
var sum = 0;
var nums = '0123456789-.';
for (var loop = 0; loop < (ear.length-1); loop++)
{
for (var loop2 = 0; loop2 < ear[loop].value.length; loop2++)
{
var x1 = 0;
if (nums.indexOf(ear[loop].value.charAt(loop2)) != -1)
{
var x1 = loop2;
loop2 = ear[loop].value.length;
}
}
for (var loop3 = 0; loop3 < ear[loop].value.substring(x1,ear[loop].value.length).length; loop3++)
{
var x2 = ear[loop].value.length;
if (nums.indexOf(ear[loop].value.substring(x1,ear[loop].value.length).charAt(loop3)) == -1)
{
var x2 = x1 + loop3;
loop3 = ear[loop].value.substring(x1,ear[loop].value.length).length
}
}
var thenum = eval(ear[loop].value.substring(x1,x2));
var numstr = thenum*100;
var numstr = parseInt(numstr);
var numstr = numstr.toString();
var numstr = numstr.substring(0,(numstr.length-2))+'.'+numstr.substring((numstr.length-2),numstr.length);
ear[loop].value = '$' + numstr;
sum += eval(numstr);
ear[loop].onblur=endRestrict;
ear[loop].onfocus=startRestrict;
ear[loop].onchange=addPrices;
}
var sumstr = Math.round(sum*100);
var sumstr = sumstr.toString();
var sumstr = sumstr.substring(0,(sumstr.length-2))+'.'+sumstr.substring((sumstr.length-2),sumstr.length);
ear[ear.length-1].value = '$'+sumstr;
}
var textfocus = 0;
function startRestrict()
{
textfocus = 1;
}
function endRestrict()
{
textfocus = 0;
}
function keyLogger()
{
var k = event.keyCode;
if (textfocus == 1)
{
if (((k<48)||(k>57))&&(k!=46)&&(k!=36)) return false;
if ((k==46)&&(event.srcElement.value.indexOf('.') != -1)) return false;
if ((k==36)&&(event.srcElement.value.length != 0)) return false;
}
}
window.onload=addPrices;
window.document.onkeypress=keyLogger;
// -->
</script>

dabush
03-26-2003, 09:47 PM
and, like b4, let me know how it works.

dabush
03-26-2003, 09:53 PM
It is no longer necessary that the form (name="pricesform") contain only 1 column of elements. just make sure that the textboxes containing the prices, including the one with the total price have a name that begins with the word "price"

for instance.

name="price123456" will be counted as a price-containing box
name="price" will be counted as a price-containing box

just make sure that the textboxes containing the prices are the only boxes that have a name that start with "price". any other elements whose names begin with the work "price" will be counted as a price-containing box. i noticed in your example, you had a box named "extprice". this is totally ok. because it does not BEGIN with "price"

sharapov
03-27-2003, 10:27 PM
dabush,

Thank you for your help. I made all the cahnges you have suggested and it looks that the "price" column works great.

Check it out herer: http://home.pacbell.net/sharapov/example2.htm

I guess I can calculate the "Quantity" column in the same matter that you did with "price" column, right? But I also would want to calculate "Extended Price" (Quantity times Price) as well as Extended Price Total. Also it would be nice for the "price" and "Extended Price" to change if I make changes to the "Quantity" field. What do you think about it. Is it possible to do?

Thank you very much.

dabush
03-27-2003, 10:47 PM
of course, anything is possible,

sharapov
03-28-2003, 12:05 PM
dabush,

Can you help me to write that code?

Thanks.

dabush
03-28-2003, 12:20 PM
sure, i'll work on it tonight

sharapov
03-28-2003, 08:48 PM
Thank you. I really appreciate this.

dabush
03-28-2003, 10:35 PM
i got a good start and will have it for you tomorrow

dabush
03-29-2003, 08:14 AM
Here are your directions
For all textboxes that contain the quantities, their names are
C123456
C246810 etc.
just change the letter C to the word quant
quant123456
quant246810 etc.

For all textboxes that contain the extprices, their names are
E123456
E246810 etc.
just change the letter E to the word ext
ext123456
ext246810 etc.

For the total price, keep the name (name="price")
For the total quantity, keep the name (name="quantity")
For the total extprice, keep the name (name="extprice")

And here is the new script (just overwrite the old one)

<script language=JavaScript type=text/javascript>
<!--
var loadtest = 0;
function addPrices()
{
var ear = new Array();
for (var test = 0; test < window.document.pricesform.elements.length; test++)
{
if (window.document.pricesform.elements[test].name.substring(0,5) == 'price') ear[ear.length] = window.document.pricesform.elements[test];
}
var sum = 0;
var nums = '0123456789-.';
for (var loop = 0; loop < (ear.length-1); loop++)
{
if (ear[loop].value == '') ear[loop].value = '$0.00';
for (var loop2 = 0; loop2 < ear[loop].value.length; loop2++)
{
var x1 = 0;
if (nums.indexOf(ear[loop].value.charAt(loop2)) != -1)
{
var x1 = loop2;
loop2 = ear[loop].value.length;
}
}
for (var loop3 = 0; loop3 < ear[loop].value.substring(x1,ear[loop].value.length).length; loop3++)
{
var x2 = ear[loop].value.length;
if (nums.indexOf(ear[loop].value.substring(x1,ear[loop].value.length).charAt(loop3)) == -1)
{
var x2 = x1 + loop3;
loop3 = ear[loop].value.substring(x1,ear[loop].value.length).length
}
}
var thenum = eval(ear[loop].value.substring(x1,x2));
var numstr = thenum*100;
var numstr = parseInt(numstr);
var numstr = numstr.toString();
var numstr = numstr.substring(0,(numstr.length-2))+'.'+numstr.substring((numstr.length-2),numstr.length);
ear[loop].value = '$' + numstr;
sum += eval(numstr);
ear[loop].onblur=endRestrict;
ear[loop].onfocus=startRestrict1;
ear[loop].onchange=addPrices;
}
var sumstr = Math.round(sum*100);
var sumstr = sumstr.toString();
var sumstr = sumstr.substring(0,(sumstr.length-2))+'.'+sumstr.substring((sumstr.length-2),sumstr.length);
ear[ear.length-1].value = '$'+sumstr;
extPrice();
if (loadtest == 0) quantities();
loadtest = 1;
}
function quantities()
{
var ear = new Array();
for (var test = 0; test < window.document.pricesform.elements.length; test++)
{
if (window.document.pricesform.elements[test].name.substring(0,5) == 'quant') ear[ear.length] = window.document.pricesform.elements[test];
}
var sum = 0;
for (var loop = 0; loop < (ear.length-1); loop++)
{
if (ear[loop].value == '') ear[loop].value = '0';
var thenum = eval(ear[loop].value);
sum += thenum;
ear[loop].onblur=endRestrict;
ear[loop].onfocus=startRestrict2;
ear[loop].onchange=quantities;
}
var sumstr = Math.round(sum);
var sumstr = sumstr.toString();
ear[ear.length-1].value = sumstr;
extPrice();
}
function extPrice()
{
var ear = new Array();
for (var test = 0; test < window.document.pricesform.elements.length; test++)
{
if (window.document.pricesform.elements[test].name.substring(0,3) == 'ext') ear[ear.length] = window.document.pricesform.elements[test];
}
var sum = 0;
for (var loop = 0; loop < (ear.length-1); loop++)
{
var itemid = ear[loop].name.substring(3,ear[loop].name.length);
var price = document.getElementById('price'+itemid).value;
var price = eval(price.substring(1,price.length));
var quant = document.getElementById('quant'+itemid).value;
var quant = eval(quant);
var extprice = quant*price;
var extprice = Math.round(extprice*100);
var extprice = extprice.toString();
var extprice = extprice.substring(0,(extprice.length-2))+'.'+extprice.substring((extprice.length-2),extprice.length);
ear[loop].value = '$'+extprice;
sum += eval(extprice);
}
var sumstr = Math.round(sum*100);
var sumstr = sumstr.toString();
var sumstr = sumstr.substring(0,(sumstr.length-2))+'.'+sumstr.substring((sumstr.length-2),sumstr.length);
ear[ear.length-1].value = '$'+sumstr;
}
var textfocus = 0;
function startRestrict1()
{
textfocus = 1;
}
function startRestrict2()
{
textfocus = 2;
}
function endRestrict()
{
textfocus = 0;
}
function keyLogger()
{
var k = event.keyCode;
if (textfocus == 1)
{
if (((k<48)||(k>57))&&(k!=46)&&(k!=36)) return false;
if ((k==46)&&(event.srcElement.value.indexOf('.') != -1)) return false;
if ((k==36)&&(event.srcElement.value.length != 0)) return false;
}
if (textfocus == 2)
{
if ((k<48)||(k>57)) return false;
}
}
window.onload=addPrices;
window.document.onkeypress=keyLogger;
// -->
</script>

dabush
03-30-2003, 07:13 PM
did that work?

sharapov
03-31-2003, 01:32 AM
dabush,

Thank you very very much. It looks like it works great. The only glitch I noticed is when I put 0 in the quantity field the extended price becomes .0 not 0.00.

Check it out here: http://home.pacbell.net/sharapov/example2.htm

Also it would probably better that quantity default to 1 if user puts 0 or doesn't put anything at all in the quantity field.

Finally, (and that doesn't relate to this script). Let's say user makes appropriate changes and presses "Submit" button for example. Now I want to take all that info open a new page and display everything in a new non-editable table for printing. Can you tell me how can this be done. I would assume that I would need to collect all text boxes into an array and then somehow print them in the new opened page. Am I correct?

Thank you for all your help.

sharapov
03-31-2003, 06:58 PM
dabush,

I was able to fix problem with zeroes myself but I seem to run in into a stange problem. If you replace current price in the "Price" field once, it seems to work fine. But if you try to replace price in the same field with the same number 2 times in a row, it kind of hanges and doesn't compute. In other words if you replace "$1.39" with 0 and click on next field it will change to $0.00, but if you select $0.00 again, replace it with 0 and click on next field, it will not change to $0.00 but stay as 0. What do you think about it? Below are the changes I made. Check it out in action here: http://home.pacbell.net/sharapov/example2.htm

<script language=JavaScript type=text/javascript>
<!--
var loadtest = 0;
function addPrices()
{
var ear = new Array();
for (var test = 0; test < window.document.pricesform.elements.length; test++)
{
if (window.document.pricesform.elements[test].name.substring(0,5) == 'price') ear[ear.length] = window.document.pricesform.elements[test];
}
var sum = 0;
var nums = '0123456789-.';
for (var loop = 0; loop < (ear.length-1); loop++)
{
if (ear[loop].value == '') ear[loop].value = '$0.00';
for (var loop2 = 0; loop2 < ear[loop].value.length; loop2++)
{
var x1 = 0;
if (nums.indexOf(ear[loop].value.charAt(loop2)) != -1)
{
var x1 = loop2;
loop2 = ear[loop].value.length;
}
}
for (var loop3 = 0; loop3 < ear[loop].value.substring(x1,ear[loop].value.length).length; loop3++)
{
var x2 = ear[loop].value.length;
if (nums.indexOf(ear[loop].value.substring(x1,ear[loop].value.length).charAt(loop3)) == -1)
{
var x2 = x1 + loop3;
loop3 = ear[loop].value.substring(x1,ear[loop].value.length).length
}
}
var thenum = eval(ear[loop].value.substring(x1,x2));
var numstr = thenum*100;
var numstr = parseInt(numstr);
var numstr = numstr.toString();
var numstr = numstr.substring(0,(numstr.length-2))+'.'+numstr.substring((numstr.length-2),numstr.length);

if (numstr == 0){numstr = '0.00'}; //Changed Here

ear[loop].value = '$' + numstr;
sum += eval(numstr);
ear[loop].onblur=endRestrict;
ear[loop].onfocus=startRestrict1;
ear[loop].onchange=addPrices;
}
var sumstr = Math.round(sum*100);
var sumstr = sumstr.toString();
var sumstr = sumstr.substring(0,(sumstr.length-2))+'.'+sumstr.substring((sumstr.length-2),sumstr.length);
ear[ear.length-1].value = '$'+sumstr;
extPrice();
if (loadtest == 0) quantities();
loadtest = 1;
}

function quantities()
{
var ear = new Array();
for (var test = 0; test < window.document.pricesform.elements.length; test++)
{
if (window.document.pricesform.elements[test].name.substring(0,5) == 'quant') ear[ear.length] = window.document.pricesform.elements[test];
}
var sum = 0;
for (var loop = 0; loop < (ear.length-1); loop++)
{
if ((ear[loop].value == '') || (ear[loop].value.substring(0,1)) == '0') {ear[loop].value = '1';} //Changed Here
var thenum = eval(ear[loop].value);
sum += thenum;
ear[loop].onblur=endRestrict;
ear[loop].onfocus=startRestrict2;
ear[loop].onchange=quantities;
}
var sumstr = Math.round(sum);
var sumstr = sumstr.toString();
ear[ear.length-1].value = sumstr;
extPrice();
}

function extPrice()
{
var ear = new Array();
for (var test = 0; test < window.document.pricesform.elements.length; test++)
{
if (window.document.pricesform.elements[test].name.substring(0,3) == 'ext') ear[ear.length] = window.document.pricesform.elements[test];
}
var sum = 0;
for (var loop = 0; loop < (ear.length-1); loop++)
{
var itemid = ear[loop].name.substring(3,ear[loop].name.length);
var price = document.getElementById('price'+itemid).value;
var price = eval(price.substring(1,price.length));
var quant = document.getElementById('quant'+itemid).value;
var quant = eval(quant);
var extprice = quant*price;
var extprice = Math.round(extprice*100);
var extprice = extprice.toString();
var extprice = extprice.substring(0,(extprice.length-2))+'.'+extprice.substring((extprice.length-2),extprice.length);

if (extprice == 0){extprice = '0.00'}; //Changed Here

ear[loop].value = '$'+extprice;
sum += eval(extprice);
}
var sumstr = Math.round(sum*100);
var sumstr = sumstr.toString();
var sumstr = sumstr.substring(0,(sumstr.length-2))+'.'+sumstr.substring((sumstr.length-2),sumstr.length);
ear[ear.length-1].value = '$'+sumstr;
}
var textfocus = 0;
function startRestrict1()
{
textfocus = 1;
}
function startRestrict2()
{
textfocus = 2;
}
function endRestrict()
{
textfocus = 0;
}
function keyLogger()
{
var k = event.keyCode;
if (textfocus == 1)
{
if (((k<48)||(k>57))&&(k!=46)&&(k!=36)) return false;
if ((k==46)&&(event.srcElement.value.indexOf('.') != -1)) return false;
if ((k==36)&&(event.srcElement.value.length != 0)) return false;
}
if (textfocus == 2)
{
if ((k<48)||(k>57)) return false;
}
}
window.onload=addPrices;
window.document.onkeypress=keyLogger;
// -->
</script>

sharapov
04-07-2003, 07:35 PM
dabush,

Hi, it's me again. Sorry to bug you. I was finishing up with the code that you helped me to write, when I discovered a big bug! :( Take a look at the example here:

http://home.pacbell.net/sharapov/example2.htm

If you replace one of the values in the "Price" column with 0.02 (for example), 0.02 cents will not be inputed correctly. Instead of 0.02 cents script will turn it into 0.20 cents.

Can you help me to eleminate this bug?

Thanks in advance.