Welcome to WebmasterWorld Guest from 184.73.126.70

Forum Moderators: open

Message Too Old, No Replies

Counting Filled Fields in a Form

   
4:21 am on Jun 6, 2008 (gmt 0)

5+ Year Member



I am trying to count how many specific fields of a form are filled in. My search brought me to this forum. i found some code that does the job, but when a table (or other HTML) is integrated into the form, the count function ceases to work.

Here is the code that works:

<script>
function countCompletedFormFields(formName, classToCheck)
{
var formObject = document.getElementById(formName);
var count = 0;

for (i=0;i<formObject.childNodes.length;i++)
{
currentNode = formObject.childNodes[i];
if(currentNode.nodeType==1 && currentNode.className == classToCheck && currentNode.value!= '')
{
count=count+1;
}
}
alert(count);
return(count);
}
</script>
<form id="myForm" method="get" action="" onSubmit="countCompletedFormFields('myForm','checkThis');this.submit();"/>
<input id="box1" class="checkThis" type="text"/><br>
<input id="box2" class="checkThis" type="text"/><br>
<input id="box3" class="checkThis" type="text"/><br>
<input id="box4" class="checkThis" type="text"/> <br>
<select name="select" class="checkThis">
<option>Please Select...</option>
<option value="1">1</option>
</select><br>
<input id="box5" class="checkThis" type="text"/><br>
<input id="" type="submit" />
</form>

But when the fields are put into a table, or additional HTML is placed between the form fields the count does not work:

<script>
function countCompletedFormFields(formName, classToCheck)
{
var formObject = document.getElementById(formName);
var count = 0;

for (i=0;i<formObject.childNodes.length;i++)
{
currentNode = formObject.childNodes[i];
if(currentNode.nodeType==1 && currentNode.className == classToCheck && currentNode.value!= '')
{
count=count+1;
}
}
alert(count);
return(count);
}
</script>
<form id="myForm" method="get" action="" onSubmit="countCompletedFormFields('myForm','checkThis');this.submit();"/>
<table border="1" style="border-collapse: collapse" width="100%" id="table1">
<tr>
<td>
<input type="text" name="B2PlayerFirstName1" class="checkThis" size="20"
<input id="box1" class="checkThis" type="text"/></td>
</tr>
<tr>
<td>
<input id="box2" class="checkThis" type="text" name="T1" size="20"/></td>
</tr>
<tr>
<td>
<input id="box3" class="checkThis" type="text" name="T2" size="20"/></td>
</tr>
<tr>
<td>
<input id="box4" class="checkThis" type="text" name="T3" size="20"/></td>
</tr>
</table>
<br>
<select name="select" class="checkThis"><br>
<option>Please Select...</option>
<option value="1">1</option>
</select><br>
<input id="box5" class="checkThis" type="text"/><br>
<input id="" type="submit" />

</p>

</form>

I have been pulling my hair out for 3 days trying to figure this out.
Any help would be greatly appreciated.

Hal

4:42 pm on Jun 11, 2008 (gmt 0)

WebmasterWorld Senior Member penders is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month



Your function steps through the childNodes of the form. This is OK if your form elements are direct children of the form, but as soon as you place them inside another container (like a <table> or a <div>) then they are no longer direct children of the form. In the case of a table, they are now children of the <td> element, which is a child of the <tr> element, which is a child of the <table> element, which is a child of the <form>! Phew!

Instead of stepping through all childNodes of the form, I think it would be better to simply step through all <input> elements contained within your form, regardless of whether they are contained inside other elements or not. So, your function becomes:

function countCompletedFormFields(formName, classToCheck) {  
var formObject = document.getElementById(formName);
var inputs = formObject.getElementsByTagName('input'); // Get all INPUT's inside the form
var count = 0;
for (var n=0; n<inputs.length; n++) {
if ((inputs[n].className == classToCheck) && (inputs[n].value != '')) {
count++;
}
}
alert(count);
return(count);
}

(Not tested)

(I've substituted your 'i' variable for 'n' just because it messed up the formatting of the post.)

Just to note... Safer to declare the 'n' variable using var to make it local to the function. Also, now there's no need to check the nodeType since all <input>'s are nodeType 1 (a standard element node).

7:06 pm on Jun 11, 2008 (gmt 0)

5+ Year Member



Thank You for the reply. I understand now why the count did not work. I was unaware of how child relationship within elements worked. The reason I was attempting to use the childnode and class was to identify which elements I would count. My form has a total of 85 possible input fields, but I only want to track 24 of them. I want to count how many of those specific 24 fields are filled in. If I understand the solution you recommend, I will be counting all of the filled input fields. So, the question is, how do I identify those 24 fields I want to count?

Thanks,
Hal

9:45 am on Jun 13, 2008 (gmt 0)

10+ Year Member



Give those 24 fields a classname.

HTH, Tom

10:40 am on Jun 13, 2008 (gmt 0)

WebmasterWorld Senior Member penders is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month



If I understand the solution you recommend, I will be counting all of the filled input fields. So, the question is, how do I identify those 24 fields I want to count?

The modified function steps through all the <input> fields but it only counts the fields that match the class you pass to the function, similar to your original function:

if ((inputs[n].className == classToCheck) && (inputs[n].value != '')) {

Your HTML should be able to remain unchanged - with a class on those 24 fields (as Arno_Adams suggests).

12:08 am on Jun 16, 2008 (gmt 0)

5+ Year Member



Thanks! It works. This is the last piece of a project I have been working many hours on. I really appreciate the help.

hal