PDA

View Full Version : Please help. Addition script having issue with IE



vanbao
05-23-2007, 10:31 PM
Hi,

I have an addition script that is suppose to total up a number of inputs. However, it works fine on FF but does not work on IE. I have looked and looked and can not figure out what is the problem. Can some please help me figure out what is causing it.

The link is http://www.nailsnow.net/members_registration2.shtml

thank you so much in advance.

codeexploiter
05-24-2007, 03:48 AM
Try the attached code

Try to use the following type of code for options

<option value="1">1</option>

In your case the value attribute is not present and IE is unable to find the value in case of FF it takes the text value that comes between <option></option> tags is treated as the value.

jscheuer1
05-24-2007, 04:20 AM
This worked:


<script type="text/javascript">
// <!-- Copyright http://javascript.internet.com -->
function startCalc(){
interval = setInterval("calc()",1);
}
function calc(){
var A1 = document.forms.form1.A1.options[document.forms.form1.A1.selectedIndex].text;
var A2 = document.forms.form1.A2.options[document.forms.form1.A2.selectedIndex].text;
var A3 = document.forms.form1.A3.options[document.forms.form1.A3.selectedIndex].text;
var A4 = document.forms.form1.A4.options[document.forms.form1.A4.selectedIndex].text;
var A5 = document.forms.form1.A5.options[document.forms.form1.A5.selectedIndex].text;
var A6 = document.forms.form1.A6.options[document.forms.form1.A6.selectedIndex].text;
var A7 = document.forms.form1.A7.options[document.forms.form1.A7.selectedIndex].text;
var A8 = document.forms.form1.A8.options[document.forms.form1.A8.selectedIndex].text;
var A9 = document.forms.form1.A9.options[document.forms.form1.A9.selectedIndex].text;
var A10 = document.forms.form1.A10.options[document.forms.form1.A10.selectedIndex].text;
var A11 = document.forms.form1.A11.options[document.forms.form1.A11.selectedIndex].text;
var A12 = document.forms.form1.A12.options[document.forms.form1.A12.selectedIndex].text;
var A13 = document.forms.form1.A13.options[document.forms.form1.A13.selectedIndex].text;
var A14 = document.forms.form1.A14.options[document.forms.form1.A14.selectedIndex].text;
var A15 = document.forms.form1.A15.options[document.forms.form1.A15.selectedIndex].text;
var A16 = document.forms.form1.A16.options[document.forms.form1.A16.selectedIndex].text;
var A17 = document.forms.form1.A17.options[document.forms.form1.A17.selectedIndex].text;
var A18 = document.forms.form1.A18.options[document.forms.form1.A18.selectedIndex].text;
var A19 = document.forms.form1.A19.options[document.forms.form1.A19.selectedIndex].text;
var A20 = document.forms.form1.A20.options[document.forms.form1.A20.selectedIndex].text;
document.form1.total1.value = (A1 * 1) + (A2 * 1) + (A3 * 1) + (A4 * 1) + (A5 * 1) + (A6 * 1) + (A7 * 1) + (A8 * 1) + (A9 * 1) + (A10 * 1) + (A11 * 1) + (A12 * 1) + (A13 * 1) + (A14 * 1) + (A15 * 1) + (A16 * 1) + (A17 * 1) + (A18 * 1) + (A19 * 1) + (A20 * 1);
}
function stopCalc(){
clearInterval(interval);
}
</script>

Don't use HTML type comments inside of javascript. Overall, the design of the form and its functions isn't conducive to straightforward coding in IE. The onchange event is better suited to this than the focus and blur pairing with the interval. Onchange could handle just about everything without requiring an interval.

Trinithis
05-24-2007, 05:21 AM
I would suggest doing this for each calc() set:



function calc() {
var sum = 0;
for(var i=1; i<=20; i++) {
sum += parseInt(document.forms.form1['A'+i].options[document.forms.form1['A'+i].selectedIndex].text);
}
document.form1.total1.value = sum;
}


All you have to do is change the "i" limits, "total#", and "calc#()";

Or better yet, let's just make one master calc() function:


function calc(start, end, totalIndex) {
var sum = 0;
for(var i=start; i<=end; i++) {
sum += parseInt(document.forms.form1['A'+i].options[document.forms.form1['A'+i].selectedIndex].text);
}
document.form1['total'+totalIndex].value = sum;
}

jscheuer1
05-24-2007, 07:10 AM
Very nice, Trinithis. You inspired me to go ahead and add the events onload:


<script type="text/javascript">
function calc(start, end, totalIndex) {
for(var i=start, sum = 0; i<=end; i++) {
sum += parseInt(document.forms.form1.elements['A'+i].options[document.forms.form1.elements['A'+i].selectedIndex].text);
}
document.forms.form1.elements['total'+totalIndex].value = sum;
}

onload=function(){
var group=[]; group[0]=[];
for (var i = 0, g=0, els = document.forms.form1.elements; i < els.length; i++)
if(els[i].tagName.toLowerCase()=='select')
group[g][group[g].length]=els[i];
else
group[g=group.length]=[];
for (var i = 0, s=1, e=0; i < group.length; i++){
e=e+group[i].length;
for (var j = 0; j < group[i].length; j++)
group[i][j].onfocus=group[i][j].onchange=new Function('calc('+s+','+e+','+[i+1]+')');
s=s+group[i].length;
}
}
</script>

This works out well with the example markup minus the events, example group:


<form name="form1" action="cgi-bin/news/maika-register2.pl" method=POST>
<div align="center"><center><b><u>NEW CLIENT REGISTRATION FORM</u></b><br>Please complete the form below.<br>
</center></div><div align="center"><center>

<table border="0" width="600" cellspacing="1" cellpadding="0" height="712" >
<tr>
<td width="600" colspan="2" height="21">Response Questions:</td>
</tr>
<tr>
<td width="50" height="21" align="right"><select NAME="A1" id="A1">
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select></td>
<td width="550" height="21" align="left"><p align="left">1 - Alcohol</td>
</tr>
<tr>

<td width="50" height="21" align="right"><select NAME="A2" id="A2">
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select></td>
<td width="550" height="21"><p align="left">2 - Artificial sweeteners</td>
</tr>

<tr>
<td width="50" height="21" align="right"><select NAME="A3" id="A3">
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select></td> . . .


. . . th="50" height="21" align="right"><select NAME="A19" id="A19">
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select></td>

<td width="550" height="21"><p align="left">19 - Water, well</td>
</tr>
<tr>
<td width="50" height="21" align="right"><select NAME="A20" id="A20">
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select></td>
<td width="550" height="21"><p align="left">20 - Diet often for weight control<br></td>
</tr>



<tr>
<td width="50" height="21" align="right"><input readonly type="text" type="text" NAME="total1" size="3">
</td>

<td width="550" height="21"><p align="left">Sum: This number is the sum of selection 1-20 and will be written to the database in field named "Total1"<br></td>
</tr>

vanbao
05-24-2007, 05:16 PM
Wow, that is very impressive with all the responses. Thank you so much everyone. You guys are awesome.

I am currious about the onload function. What exactly does that do and how is it a help.

Thank you.

jscheuer1
05-24-2007, 05:31 PM
Wow, that is very impressive with all the responses. Thank you so much everyone. You guys are awesome.

I am currious about the onload function. What exactly does that do and how is it a help.

Thank you.

It assigns the events to the markup. It has pluses and minuses. On the plus side, as long as you follow the markup template that you have established, no onfocus, onblur or whatever events need to go in the body. On the minus side, if you deviate too far from the markup template that you have established, it will fail.

Your template basically is:


<form>

<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<input type="text">

<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<input type="text">

</form>

With the form, selects and the inputs numbered and named as you have done, in sequence. You could have as many of the:


<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<select></select>
<input type="text">

in the form as you like as long as you stick to your established naming convention. But, if you start putting other form elements in there, or change the way the elements are named, the onload function and/or the calc function would probably no longer work.

vanbao
05-24-2007, 05:56 PM
John,

If suppose I want to expand this script and include say another function where the script will take "total1" and divide by a particular predefined number say 120 and convert that to a percentage, would that be possible.

In other word, each of the sections have a possible maximum total of 120 if a person chooses all 3s. Now ofcourse that is not going to happen so whatever total it turns out as the total for each individual, I want to find out what is the percentage of that total in relate to the maximum total.

vanbao
05-24-2007, 06:13 PM
John,

I am assuming that the onload function you added allow me to have just want script and work with more than 1 section which I have. In other word, each section, I have a value name total1, total2, total3, etc. If section one is contains questions 1-20, section two: 21-50, section 3: 51-75, how do I change the i variable in the script to reflect that. I tried changing it but did not get it to work with other sections.

jscheuer1
05-24-2007, 06:50 PM
It does it automatically:

1031

if you follow the general layout and naming template, you could have 50 sections or just one, each with however many selects you like, each with one and only one total, all of them inside of form1 with no other elements in form1. You could have other forms on the page that do other things.

vanbao
05-24-2007, 08:29 PM
Thanks John,

In your post above, you mean I can only have follow exactly the layout you had or else it won't work? I tried adding a small section (see the section between the <!-----------top section--------> and the script stop working after that. Here is what I mean.http://www.nailsnow.net/members_registration.shtml

If I take that section out, then it works fine.

Is there away to get the script to ignore that new section between the <!-----------top section--------> ?

jscheuer1
05-25-2007, 01:29 AM
This:


<!-----------top section-------->

is not a valid HTML comment. It will not work in FF, perhaps others. Use:


<!-- top section -->

Notice, only two dashes separated from the comment text by a space.

OK, that has nothing to do with why the onload stopped working though. BTW, I told you that it would stop working if you added other elements to the form. However, as long as you add them (as you have in your new demo) before the selects that have names starting with the capital letter 'A', this will work (additions red):


<script type="text/javascript">
function calc(start, end, totalIndex) {
for(var i=start, sum = 0; i<=end; i++) {
sum += parseInt(document.forms.form1.elements['A'+i].options[document.forms.form1.elements['A'+i].selectedIndex].text);
}
document.forms.form1.elements['total'+totalIndex].value = sum;
}

onload=function(){
var group=[]; group[0]=[];
for (var i = 0, g=0, els = document.forms.form1.elements; i < els.length; i++)
if(els[i].tagName.toLowerCase()=='select'&&els[i].name.indexOf('A')==0)
group[g][group[g].length]=els[i];
else if(group[g].length>0)
group[g=group.length]=[];
for (var i = 0, s=1, e=0; i < group.length; i++){
e=e+group[i].length
for (var j = 0; j < group[i].length; j++)
group[i][j].onfocus=group[i][j].onchange=new Function('calc('+s+','+e+','+[i+1]+')');
s=s+group[i].length
}
}
</script>

jscheuer1
05-25-2007, 01:55 AM
To answer your other question, to get a percentage out of 120, you would divide by 12 and round off. So, you could add another text input or whatever like so:


</td>
<td width="550" height="21"><p align="left">Sum: This number is the sum of selection 51-75 and will be written to the database in field named "Total3"<br></td>

</tr>
<tr>

<td width="25%" align="right" heigth="10"><input type="text" readonly name="gtpercent"><b></b></td>
<td width="75%" align="left">Grand Total Percentage </td>
</tr>
<tr>
<td width="25%" align="right"><b></b></td>
<td width="75%" align="left"> <input type="submit" value=" Submit " tabindex="6"><br></td>

</tr>

And add onto the calc function like so:


function calc(start, end, totalIndex) {
for(var i=start, sum = 0; i<=end; i++) {
sum += parseInt(document.forms.form1.elements['A'+i].options[document.forms.form1.elements['A'+i].selectedIndex].text);
}
document.forms.form1.elements['total'+totalIndex].value = sum;
calc.gsum=calc.gsum? calc.gsum+sum : sum;
document.forms.form1.elements['gtpercent'].value = Math.round(calc.gsum/12) + '%';
}

vanbao
05-25-2007, 04:15 AM
John,

You are a genius!! If I could bow to you I would. Thank you so much.