...

View Full Version : form validation when looped form.



turpentyne
03-29-2012, 01:02 AM
I've been using a script for verifying forms across several pages, and I've run into a page where it won't work the way it is.

It's a form that loops through and creates a set of fields over and over, depending on the number of attendees. I'm assuming this disrupts the form verification because the fields get generated with the same id. I think I need to find another way to make sure the user enters valid and complete information. Here's what I've been using:


function myForm(){
// Make quick references to our fields
var fname = document.getElementById('fname');
var lname = document.getElementById('lname');
var birth_month = document.getElementById('birth_month');
var birthday = document.getElementById('birthday');
var birthyear = document.getElementById('birthyear');


// Check each input in the order that it appears in the form!
if(isAlphabet(fname, "Please enter only letters for your first name")){
if(isAlphabet(lname, "Please enter only letters for your last name")){
if(madeSelection(birth_month, "Pleace choose a birth month")){
if(madeSelection(birthday, "Please choose a birth day")){
if(madeSelection(birthyear, "Please choose a birth year")){
return true;
}
}
}
}
}


return false;
}



function isAlphabet(elem, helperMsg){
var alphaExp = /^[a-zA-Z ]+$/;
if(elem.value.match(alphaExp)){
return true;
}else{
alert(helperMsg);
elem.focus();
return false;
}
}


function madeSelection(elem, helperMsg){
if(elem.value == ''){
alert(helperMsg);
elem.focus();
return false;
}else{
return true;
}
}

</script>

<!-- the snippet that creates the form fields is here: -->

$count = $line;
$i = 1;
while ($i <= $count) {
$i++; /* the printed value would be
$i before the increment
(post-increment) */
$x = $i-1;


?>
<form name="register1" class="registration_form" method="post" action="register2.php" target="_self" onsubmit="return myForm()">


First Name<br><input type="text" name="kfname[]" id="fname" onfocus="this.className='reg_live';" onblur="this.className='reg_off';" /><br>

Kid's Last Name<br><input type="text" name="klname[]" id="lname" onfocus="this.className='reg_live';" onblur="this.className='reg_off';" /><br>

Birthdate<br>
<select style="width:75px;" id="birth_month" name="bdate2[]" onfocus="this.className='reg_live';" onblur="this.className='reg_off';" >
<option value="">month</option>
<option value="01">Jan</option>
<option value="02">Feb</option>
<!-- etcetera -->
</select>


<select style="width:57px;" id="birthday" name="bdate[]" onfocus="this.className='reg_live';" onblur="this.className='reg_off';" >
<option value="">day</option>
<option value="01">01</option>
<option value="02">02</option>
<!-- etcetera -->
</select>

<select style="width:60px;" id="birthyear" name="bdate3[]" onfocus="this.className='reg_live';" onblur="this.className='reg_off';" >
<option value="">year</option>
<option value="1993">1993</option>
<option value="1994">1994</option>
<!-- etcetera -->

</select>

</form>

Old Pedant
03-29-2012, 01:28 AM
I'm assuming this disrupts the form verification because the fields get generated with the same id.

Which of course is illegal HTML.

But why do you need id's at all?

Why not do your validation based on the name fields? Which are of course arrays:


<form name="register1" class="registration_form" method="post"
action="register2.php" target="_self" onsubmit="return myForm(this)">

...

function myForm(form)
{
// Make quick references to our field *ARRAYS*:
var fnames = form["fname[]"];
var lname = form["lname[]"];
var birth_month = form["bdate2[]"];
var birthday = form["bdate[]"];
var birthyear = form["bdate3[]"];

for ( var f = 0; f < fname.length; ++f )
{
var n = f+1;
if( ! isAlphabet(fname[f], "Please enter only letters for first name " +n)
|| ! isAlphabet(lname[f], "Please enter only letters for last name " +n)
|| ! madeSelection(birth_month[f], "Pleace choose a birth month for name " + n)
|| ! madeSelection(birthday[f], "Please choose a birth day for name " +n)
|| ! madeSelection(birthyear[f], "Please choose a birth year for name " +n)
) {
return false;
}
}
return true;
}

turpentyne
03-29-2012, 02:09 AM
Ah, just 'cause I'm scared of arrays! hehe. Still learning how to deal with them.

This looks like the right solution to me. I was using id's in other situations.

It doesn't seem to be executing right, though. Goes to the next page without checking the fields. I'll have to figure out the script so I can check where the issue is.

Old Pedant
03-29-2012, 02:23 AM
Ugh...not it doesn't work. Now why not? Looking at it...

turpentyne
03-29-2012, 02:27 AM
I did catch a couple of tiny things so far, but they didn't solve the problem. I changed fnames to fname where the variables are getting set, and I deleted the space between +n on one of the if statements.

Does: var fname = form["fname[]"];
need to read myForm["fname[]"]

I tried that too, for giggles, but it didn't work either.

Old Pedant
03-29-2012, 02:27 AM
Oh...just a typo:

var fnames = form["fname[]"];

The "s" on "fnames" shouldn't be there.

turpentyne
03-29-2012, 02:32 AM
Yeah, I caught that. Tried to post that before you found it so you knew it wasn't the issue.

:(

Old Pedant
03-29-2012, 03:15 AM
The spaces don't matter.

Old Pedant
03-29-2012, 03:16 AM
I don't suppose you can show this live? Give a URL?

turpentyne
03-29-2012, 04:10 AM
Sure..

You have to get to it from a starting registration page: http://www.workshopsaz.org/register.php

The page we're working with is here:
http://www.workshopsaz.org/register1.php

Old Pedant
03-29-2012, 07:50 AM
You aren't even *GETTING* to the validation function!

Put a breakpoint on the first line of the function and you never get there.

I think it may be because the function and the <form> have the same name.

Change the name of the function to maybe validateMyForm and change the call in onsubmit

turpentyne
03-30-2012, 01:46 AM
Well, I made at least a little progress. The opening html form tag was inside the loop, I moved that outside.

I also spotted an extra bracket in the javascript function. Now it looks like it's getting to the function, but still doesn't trigger a popup on form field errors.

I checked it in firebug's console to see what errors might show up. nada.

The form name and the javascript function aren't named the same, so that's not an issue.

Grrrr!

turpentyne
03-30-2012, 01:57 AM
hallelujah!

Syntax of the variables being set. I did it this way, and it works like a charm:

var fname = document.getElementsByName("kfname[]");

var lname = document.getElementsByName("klname[]");
var birth_month = document.getElementsByName("bdate2[]");
var birthday = document.getElementsByName("bdate[]");
var birthyear = document.getElementsByName("bdate3[]");

Old Pedant
03-30-2012, 02:53 AM
??? I just checked it and it is working perfectly in Firefox.

Have you changed it since you posted?

**********

Personally, I find it annoying to only get one error alert at a time.

Might I suggest some alternative validation code? If you don't like it, don't use it. But try it out.



<script type='text/javascript'>

var oops = "";

function validation1()
{
// Make quick references to our fields
// doesnt even make it this far
// Make quick references to our field *ARRAYS*:
var fname = document.getElementsByName("kfname[]");
var lname = document.getElementsByName("klname[]");
var birth_month = document.getElementsByName("bdate2[]");
var birthday = document.getElementsByName("bdate[]");
var birthyear = document.getElementsByName("bdate3[]");

oops = ""; // init the error collector

for ( var f = 0; f < fname.length; ++f )
{
var n = f+1;
isAlphabet(fname[f], "Please enter only letters for first name of child " +n);
isAlphabet(lname[f], "Please enter only letters for last name of child " +n);
madeSelection(birth_month[f], "Pleace choose a birth month for child " +n);
madeSelection(birthday[f], "Please choose a birth day for child " +n);
madeSelection(birthyear[f], "Please choose a birth year for child " +n);
}
if ( oops != "" )
{
alert("Correct these errors and then hit Next again:" + oops);
return false;
}
return true;
}
function isAlphabet(elem, helperMsg)
{
var alphaExp = /^[a-zA-Z ]+$/;
if( ! elem.value.match(alphaExp))
{
if ( oops == "" ) elem.focus();
oops += "\n " + helperMsg;
}
}
function isAlphanumeric(elem, helperMsg)
{
var alphaExp = /^[0-9a-zA-Z\s]+$/;
if( ! elem.value.match(alphaExp))
{
if ( oops == "" ) elem.focus();
oops += "\n " + helperMsg;
}
}
function madeSelection(elem, helperMsg)
{
if(elem.value == ''){
if ( oops == "" ) elem.focus();
oops += "\n " + helperMsg;
}
}
</script>

Old Pedant
03-30-2012, 02:59 AM
Ummm...except getElementsByName doesn't exist in MSIE prior to version 9.

Which means it won't work for roughly 40% of your users, on average.

We could write a quickie replacement.



function getFormElementsByName( fldname )
{
var elems = [];
var form = document.forms[0];
for ( var e = 0; e < form.elements.length; ++e )
{
var fld = form.elements[e];
if ( fld.name == fldname ) elems.push(fld);
}
return elems;
}

And then invoke it via (example)


var lname = getFormElementsByName("lname[]");

Now tested. Works.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum