Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #15769 > unrolled thread
| Started by | Mike Winter <usenet@michael-winter.me.invalid> |
|---|---|
| First post | 2012-09-07 15:26 +0100 |
| Last post | 2012-09-07 20:57 +0100 |
| Articles | 9 — 4 participants |
Back to article view | Back to comp.lang.javascript
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: How to do calculation with dynamic form field names? Mike Winter <usenet@michael-winter.me.invalid> - 2012-09-07 15:26 +0100
Re: How to do calculation with dynamic form field names? justaguy <lichunshen84@gmail.com> - 2012-09-07 08:03 -0700
Re: How to do calculation with dynamic form field names? Gene Wirchenko <genew@ocis.net> - 2012-09-07 10:05 -0700
Re: How to do calculation with dynamic form field names? justaguy <lichunshen84@gmail.com> - 2012-09-07 11:39 -0700
Re: How to do calculation with dynamic form field names? SAM <stephanemoriaux.NoAdmin@wanadoo.fr.invalid> - 2012-09-07 21:56 +0200
Re: How to do calculation with dynamic form field names? Mike Winter <usenet@michael-winter.me.invalid> - 2012-09-07 20:05 +0100
Re: How to do calculation with dynamic form field names? justaguy <lichunshen84@gmail.com> - 2012-09-07 12:36 -0700
Re: How to do calculation with dynamic form field names? justaguy <lichunshen84@gmail.com> - 2012-09-07 12:51 -0700
Re: How to do calculation with dynamic form field names? Mike Winter <usenet@michael-winter.me.invalid> - 2012-09-07 20:57 +0100
| From | Mike Winter <usenet@michael-winter.me.invalid> |
|---|---|
| Date | 2012-09-07 15:26 +0100 |
| Subject | Re: How to do calculation with dynamic form field names? |
| Message-ID | <8un2s.290330$Lp7.53018@fx08.am4> |
On 07/09/2012 05:07, justaguy wrote:
[snip]
> <form>
> <input type="text" id="item1">, <input type="text" id="qty1">, <input
> type="text" id="price1">, fieldX1 t1
[snip]
> a) t{n} = subtotal field.
> b) number of rows is unknown, it could be 1 to 30.
>
> What I'd like to do is: calculate subtotal and total.
> each subtotal = qty{n} * parseFloat(price{n})
>
> My attempt is to loop through the entire form, I'm able to retrieve
> all the values for the qty{n} field,
> but I don't know how to retrieve the value of its Corresponding
> Price{n}.
[snip]
What you're looking for is bracket notation; the ability to construct
property names through string concatenation. This is described in the
FAQ (and elaborated in the notes):
<http://jibbering.com/faq/#propertyAccessAgain>
As you don't know the number of rows, you can leverage the fact that a
nonexistent property will return null to simplify your loop (no need to
use String.prototype.indexOf):
var i = 0,
element;
// 'item' may be a better choice below if that's always
// present in a row and 'qty' isn't, in which case the
// condition below should become a null comparison instead
// of an assignment expression/boolean type-conversion.
while ((element = form.elements['qty' + i])) {
var subtotal = form.elements['qty' + i]
* form.elements['price' + i];
// ...
i++;
}
Alternatively, you could of course inject a script element that contains
a variable initialised with the number of rows when the page is generated.
Hope that helps,
--
Mike Winter
Replace ".invalid" with ".uk" to reply by e-mail.
[toc] | [next] | [standalone]
| From | justaguy <lichunshen84@gmail.com> |
|---|---|
| Date | 2012-09-07 08:03 -0700 |
| Message-ID | <c40ba0e0-3f3a-4333-b9da-60949a55c236@n9g2000yqn.googlegroups.com> |
| In reply to | #15769 |
On Sep 7, 10:26 am, Mike Winter <use...@michael-winter.me.invalid>
wrote:
> On 07/09/2012 05:07, justaguy wrote:
>
> [snip]
>
> > <form>
> > <input type="text" id="item1">, <input type="text" id="qty1">, <input
> > type="text" id="price1">, fieldX1 t1
>
> [snip]
>
> > a) t{n} = subtotal field.
> > b) number of rows is unknown, it could be 1 to 30.
>
> > What I'd like to do is: calculate subtotal and total.
> > each subtotal = qty{n} * parseFloat(price{n})
>
> > My attempt is to loop through the entire form, I'm able to retrieve
> > all the values for the qty{n} field,
> > but I don't know how to retrieve the value of its Corresponding
> > Price{n}.
>
> [snip]
>
> What you're looking for is bracket notation; the ability to construct
> property names through string concatenation. This is described in the
> FAQ (and elaborated in the notes):
> <http://jibbering.com/faq/#propertyAccessAgain>
>
> As you don't know the number of rows, you can leverage the fact that a
> nonexistent property will return null to simplify your loop (no need to
> use String.prototype.indexOf):
>
> var i = 0,
> element;
>
> // 'item' may be a better choice below if that's always
> // present in a row and 'qty' isn't, in which case the
> // condition below should become a null comparison instead
> // of an assignment expression/boolean type-conversion.
> while ((element = form.elements['qty' + i])) {
> var subtotal = form.elements['qty' + i]
Beautiful, Mike, many thanks.
Strange. After I changed the script a bit to get subtotal value for
each row,
var i = 0, t=0,
element;
while ((element = forms[0].elements['qty' + i])) {
var subtotal = forms[0].elements['qty' + i] *
forms[0].elements['price' + i];
forms[0].elements['total' + i].value = subtotal;
t = t + parseFloat(subtotal);
alert(t);
// ...
i++;
}
forms[0].elements['totalFinal'].value = t;
I got the following error, attempted to use form reference of the
first form (there's only one form anyway),
"ReferenceError: forms is not defined"
Am I missing something here?
[toc] | [prev] | [next] | [standalone]
| From | Gene Wirchenko <genew@ocis.net> |
|---|---|
| Date | 2012-09-07 10:05 -0700 |
| Message-ID | <04ak48ls7n8nbasj13prbn9lc1vpmrv4a7@4ax.com> |
| In reply to | #15770 |
On Fri, 7 Sep 2012 08:03:49 -0700 (PDT), justaguy
<lichunshen84@gmail.com> wrote:
[snip]
>each row,
>
> var i = 0, t=0,
> element;
> while ((element = forms[0].elements['qty' + i])) {
> var subtotal = forms[0].elements['qty' + i] *
>forms[0].elements['price' + i];
> forms[0].elements['total' + i].value = subtotal;
> t = t + parseFloat(subtotal);
> alert(t);
> // ...
> i++;
> }
>
> forms[0].elements['totalFinal'].value = t;
>
>I got the following error, attempted to use form reference of the
>first form (there's only one form anyway),
>
>"ReferenceError: forms is not defined"
>
>Am I missing something here?
I think you need
document.forms[0] ...
^^^^^^^^^
in front of the forms reference.
Sincerely,
Gene Wirchenko
[toc] | [prev] | [next] | [standalone]
| From | justaguy <lichunshen84@gmail.com> |
|---|---|
| Date | 2012-09-07 11:39 -0700 |
| Message-ID | <cba9bfae-6484-474f-93b8-f40209be5c8e@u19g2000yqo.googlegroups.com> |
| In reply to | #15775 |
On Sep 7, 1:05 pm, Gene Wirchenko <ge...@ocis.net> wrote:
> On Fri, 7 Sep 2012 08:03:49 -0700 (PDT), justaguy
>
> <lichunshe...@gmail.com> wrote:
>
> [snip]
>
>
>
>
>
>
>
>
>
> >each row,
>
> > var i = 0, t=0,
> > element;
> > while ((element = forms[0].elements['qty' + i])) {
> > var subtotal = forms[0].elements['qty' + i] *
> >forms[0].elements['price' + i];
> > forms[0].elements['total' + i].value = subtotal;
> > t = t + parseFloat(subtotal);
> > alert(t);
> > // ...
> > i++;
> > }
>
> > forms[0].elements['totalFinal'].value = t;
>
> >I got the following error, attempted to use form reference of the
> >first form (there's only one form anyway),
>
> >"ReferenceError: forms is not defined"
>
> >Am I missing something here?
>
> I think you need
> document.forms[0] ...
> ^^^^^^^^^
> in front of the forms reference.
>
> Sincerely,
>
> Gene Wirchenko
Thanks alot. That helps. Now, the alert(t) line does not return
alert. I added another alert as the first line for the loop and it
does not return alert neither. How's wrong? Firefox 15 with Firebug.
[toc] | [prev] | [next] | [standalone]
| From | SAM <stephanemoriaux.NoAdmin@wanadoo.fr.invalid> |
|---|---|
| Date | 2012-09-07 21:56 +0200 |
| Message-ID | <504a516d$0$21255$ba4acef3@reader.news.orange.fr> |
| In reply to | #15777 |
Le 07/09/12 20:39, justaguy a écrit :
> On Sep 7, 1:05 pm, Gene Wirchenko <ge...@ocis.net> wrote:
>> On Fri, 7 Sep 2012 08:03:49 -0700 (PDT), justaguy
>>
>> <lichunshe...@gmail.com> wrote:
>>
>> [snip]
function t(el) { // el = one of the quantity inputs
var f = el.form, // in which form are we ?
n = f.elements.length, // how many elements are there ?
z = 0,
p = 0, // sub-total
s = 0; // total
// if the quantity is greater than zero
if(el.value>0) {
// we will calculate each row whith a loop thru all elements
while(n--)
if( f[n] && f[n].name.indexOf('qty')>=0) {
// we get that row
el = f[n].parentNode;
while (el.tagName.toLowerCase() != 'tr') el = el.parentNode;
// collection of textfields of the row
el = el.getElementsByTagName('INPUT'); z = el.length;
// calcul the row
el[z-1].value = p = el[z-2].value * el[z-3].value;
// add result to the total
s += p*1;
}
// finaly complete the textfield 'total'
f['total'].value = s;
}
}
<form>
<table>
<tr>
<td>Article 1:</td>
<td><input value="15.25"></td>
<td> * <input name="qty[]"></td>
<td> = <input name="subTotal[]"></td>
</tr>
<tr>
<td>Article 2:</td>
<td><input value="15.25"></td>
<td> * <input name="qty[]" onblur="t(this)"></td>
<td> = <input name="subTotal[]"></td>
</tr>
<tr>
<td colspan="3">total : </td>
<td><input name="total"></td>
</tr>
</table>
</form>
We certainly could do the loop with the rows of the table
function t(el) { // el = quantity input
var f = el.form, // in which form are we ?
r = f.getElementsByTagName('TR'), // collection of rows
n = r.length, // how many rows ?
p = 0, // sub-total
s = 0; // total
// if the quantity is greater than zero
if(el.value>0) {
// we will calculate each row whith a loop thru rows
while(n--)
{
// we get the inputs of that row
el = r[n].getElementsByTagName('INPUT'); z = el.length;
if(z==3) {
el[z-1].value = p = el[z-2].value * el[z-3].value;
// add result to the total
s += p*1;
}
}
// finaly we complete the textfield 'total'
f['total'].value = s;
}
}
--
Stéphane Moriaux avec/with iMac-intel
[toc] | [prev] | [next] | [standalone]
| From | Mike Winter <usenet@michael-winter.me.invalid> |
|---|---|
| Date | 2012-09-07 20:05 +0100 |
| Message-ID | <Tzr2s.523194$6h3.7439@fx25.am4> |
| In reply to | #15770 |
On 07/09/2012 16:03, justaguy wrote:
> On Sep 7, 10:26 am, Mike Winter <use...@michael-winter.me.invalid>
> wrote:
>> On 07/09/2012 05:07, justaguy wrote:
>>
>> [snip]
>>
>>> <form>
>>> <input type="text" id="item1">, <input type="text" id="qty1">, <input
>>> type="text" id="price1">, fieldX1 t1
[snip]
> Strange. After I changed the script a bit to get subtotal value for
> each row,
>
> var i = 0, t=0,
Here, i should've been initialised to 1: the first row has a "qty1", not
a "qty0". This was an oversight on my part.
> element;
> while ((element = forms[0].elements['qty' + i])) {
As Gene pointed out, you cannot just use "forms" as-is. With the code I
originally posted. the simple adaptation would be to declare and
initialise form:
var form = document.forms[0];
I didn't include it as that might not be the best way to obtain that
reference. If your function is called from the form element's submit or
the button's click event handler, then:
<form ... onsubmit="return calculateTotal(this.form);">
function calculateTotal(form) {
// ...
would be better. Regardless, using a single reference has the advantage
of avoiding repeated property references and, in my opinion at least,
improving readability.
> var subtotal = forms[0].elements['qty' + i] *
> forms[0].elements['price' + i];
> forms[0].elements['total' + i].value = subtotal;
> t = t + parseFloat(subtotal);
t += subtotal;
The subtotal variable will already be a floating-point number as the
multiplication operator attempts to type-convert strings to numbers
automatically. There's no need to call parseFloat here. If you're
concerned with values not being numbers, you need to be validating those
values.
[snip]
> Am I missing something here?
Hopefully that's cleared up a few things.
Kind regards,
--
Mike Winter
Replace ".invalid" with ".uk" to reply by e-mail.
[toc] | [prev] | [next] | [standalone]
| From | justaguy <lichunshen84@gmail.com> |
|---|---|
| Date | 2012-09-07 12:36 -0700 |
| Message-ID | <8999254d-5896-4ba3-becd-ae08c3b242d0@v15g2000yqi.googlegroups.com> |
| In reply to | #15778 |
On Sep 7, 3:05 pm, Mike Winter <use...@michael-winter.me.invalid>
wrote:
> On 07/09/2012 16:03, justaguy wrote:
>
> > On Sep 7, 10:26 am, Mike Winter <use...@michael-winter.me.invalid>
> > wrote:
> >> On 07/09/2012 05:07, justaguy wrote:
>
> >> [snip]
>
> >>> <form>
> >>> <input type="text" id="item1">, <input type="text" id="qty1">, <input
> >>> type="text" id="price1">, fieldX1 t1
>
> [snip]
>
> > Strange. After I changed the script a bit to get subtotal value for
> > each row,
>
> > var i = 0, t=0,
>
> Here, i should've been initialised to 1: the first row has a "qty1", not
> a "qty0". This was an oversight on my part.
>
> > element;
> > while ((element = forms[0].elements['qty' + i])) {
>
> As Gene pointed out, you cannot just use "forms" as-is. With the code I
> originally posted. the simple adaptation would be to declare and
> initialise form:
>
> var form = document.forms[0];
>
> I didn't include it as that might not be the best way to obtain that
> reference. If your function is called from the form element's submit or
> the button's click event handler, then:
>
> <form ... onsubmit="return calculateTotal(this.form);">
>
> function calculateTotal(form) {
> // ...
>
> would be better. Regardless, using a single reference has the advantage
> of avoiding repeated property references and, in my opinion at least,
> improving readability.
>
> > var subtotal = forms[0].elements['qty' + i] *
> > forms[0].elements['price' + i];
> > forms[0].elements['total' + i].value = subtotal;
> > t = t + parseFloat(subtotal);
>
> t += subtotal;
>
> The subtotal variable will already be a floating-point number as the
> multiplication operator attempts to type-convert strings to numbers
> automatically. There's no need to call parseFloat here. If you're
> concerned with values not being numbers, you need to be validating those
> values.
>
> [snip]
>
> > Am I missing something here?
>
> Hopefully that's cleared up a few things.
> Kind regards,
> --
> Mike Winter
> Replace ".invalid" with ".uk" to reply by e-mail.
Many thank, Mike. I was a bit careless myself.
Here's the code that works except that I have a checkbox dynamic field
name starting with
"Remove_" keyword, I attempted to determine if some of such checkbox
has been checked with
the following line of code to no effect,
document.forms[0].elements['Remove_' + i]
or
document.forms[0].elements['Remove_' + i].checked // this line threw
an error.
To remove/subtract the subtotal from such row(s).
var i = 1, t=0,
element;
while ((element = document.forms[0].elements['qty' + i])) {
var subtotal = document.forms[0].elements['qty' + i].value *
document.forms[0].elements['priceLabel' + i].value;
// alert(subtotal);
document.forms[0].elements['total' + i].value = subtotal;
t = t + subtotal;
if (document.forms[0].elements['Remove_' + i]) {
t = t - subtotal;
}
//alert(t);
document.forms[0].elements['totalFinal'].value = t;
i++;
}
[toc] | [prev] | [next] | [standalone]
| From | justaguy <lichunshen84@gmail.com> |
|---|---|
| Date | 2012-09-07 12:51 -0700 |
| Message-ID | <117baeeb-bb31-4b2d-a11d-01ef7ef5eeb0@l14g2000yqo.googlegroups.com> |
| In reply to | #15779 |
On Sep 7, 3:36 pm, justaguy <lichunshe...@gmail.com> wrote:
> On Sep 7, 3:05 pm, Mike Winter <use...@michael-winter.me.invalid>
> wrote:
>
>
>
>
>
>
>
>
>
> > On 07/09/2012 16:03, justaguy wrote:
>
> > > On Sep 7, 10:26 am, Mike Winter <use...@michael-winter.me.invalid>
> > > wrote:
> > >> On 07/09/2012 05:07, justaguy wrote:
>
> > >> [snip]
>
> > >>> <form>
> > >>> <input type="text" id="item1">, <input type="text" id="qty1">, <input
> > >>> type="text" id="price1">, fieldX1 t1
>
> > [snip]
>
> > > Strange. After I changed the script a bit to get subtotal value for
> > > each row,
>
> > > var i = 0, t=0,
>
> > Here, i should've been initialised to 1: the first row has a "qty1", not
> > a "qty0". This was an oversight on my part.
>
> > > element;
> > > while ((element = forms[0].elements['qty' + i])) {
>
> > As Gene pointed out, you cannot just use "forms" as-is. With the code I
> > originally posted. the simple adaptation would be to declare and
> > initialise form:
>
> > var form = document.forms[0];
>
> > I didn't include it as that might not be the best way to obtain that
> > reference. If your function is called from the form element's submit or
> > the button's click event handler, then:
>
> > <form ... onsubmit="return calculateTotal(this.form);">
>
> > function calculateTotal(form) {
> > // ...
>
> > would be better. Regardless, using a single reference has the advantage
> > of avoiding repeated property references and, in my opinion at least,
> > improving readability.
>
> > > var subtotal = forms[0].elements['qty' + i] *
> > > forms[0].elements['price' + i];
> > > forms[0].elements['total' + i].value = subtotal;
> > > t = t + parseFloat(subtotal);
>
> > t += subtotal;
>
> > The subtotal variable will already be a floating-point number as the
> > multiplication operator attempts to type-convert strings to numbers
> > automatically. There's no need to call parseFloat here. If you're
> > concerned with values not being numbers, you need to be validating those
> > values.
>
> > [snip]
>
> > > Am I missing something here?
>
> > Hopefully that's cleared up a few things.
> > Kind regards,
> > --
> > Mike Winter
> > Replace ".invalid" with ".uk" to reply by e-mail.
>
> Many thank, Mike. I was a bit careless myself.
> Here's the code that works except that I have a checkbox dynamic field
> name starting with
> "Remove_" keyword, I attempted to determine if some of such checkbox
> has been checked with
> the following line of code to no effect,
> document.forms[0].elements['Remove_' + i]
> or
> document.forms[0].elements['Remove_' + i].checked // this line threw
> an error.
> To remove/subtract the subtotal from such row(s).
>
> var i = 1, t=0,
> element;
> while ((element = document.forms[0].elements['qty' + i])) {
> var subtotal = document.forms[0].elements['qty' + i].value *
> document.forms[0].elements['priceLabel' + i].value;
> // alert(subtotal);
> document.forms[0].elements['total' + i].value = subtotal;
> t = t + subtotal;
>
> if (document.forms[0].elements['Remove_' + i]) {
> t = t - subtotal;
> }
>
> //alert(t);
> document.forms[0].elements['totalFinal'].value = t;
>
> i++;
> }
The following line does the trick. Problem resolved. Many thanks.
if (document.forms[0].elements['Remove_' + i] &&
document.forms[0].elements['Remove_' + i].checked) {
t = t - subtotal;
}
[toc] | [prev] | [next] | [standalone]
| From | Mike Winter <usenet@michael-winter.me.invalid> |
|---|---|
| Date | 2012-09-07 20:57 +0100 |
| Message-ID | <Wks2s.295006$Xu5.65204@fx10.am4> |
| In reply to | #15779 |
On 07/09/2012 20:36, justaguy wrote:
> On Sep 7, 3:05 pm, Mike Winter <use...@michael-winter.me.invalid>
> wrote:
>
> [snip]
>
>> If your function is called from the form element's submit or
>> the button's click event handler, then:
>>
>> <form ... onsubmit="return calculateTotal(this.form);">
Sorry, I'm obviously not thinking clearly today. With a form, the value
passed would be simply the object referenced by the this keyword. With a
form control, it would be the expression, this.form
[snip]
> Here's the code that works except that I have a checkbox dynamic field
> name starting with
> "Remove_" keyword, I attempted to determine if some of such checkbox
> has been checked with
> the following line of code to no effect,
> document.forms[0].elements['Remove_' + i]
> or
> document.forms[0].elements['Remove_' + i].checked // this line threw
> an error.
That expression would only produce an error if the control didn't exist.
Are these checkboxes present in every row? If not, you'll need to test
for both the presence of the control and whether it's checked:
var skipRowCheckbox = form.elements['Remove_' + i];
if (skipRowCheckbox && skipRowCheckbox.checked) {
t -= subtotal;
}
Or to reverse the logic, so that the subtotal is only increased if there
is no checkbox, or there is but it's unchecked:
var skipRowCheckbox = form.elements['Remove_' + i];
if (!skipRowCheckbox || !skipRowCheckbox.checked) {
t += subtotal;
}
[snip]
--
Mike Winter
Replace ".invalid" with ".uk" to reply by e-mail.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web