Forum Moderators: coopster

Message Too Old, No Replies

Form validation behaving strangely

         

humanexperience

12:45 am on Apr 28, 2010 (gmt 0)

10+ Year Member



Hi this is my first post and it's a pleasure to be here. I've read a lot of posts from this forum which have helped me greatly this year and i decided to sign up.

My issue.

When I insert my form validation php code after </form> the validation works incorrectly. (see second set of code pasted in this post)

It doesn't store information typed into text fields. E.G. I type in first name and last name correctly and then email incorrectly so I get then get a "please enter a valid email" message on the screen but the info I typed into first name and last name disappears.

This does not happen when I have my code as it is the first set of code I have pasted below.

The reason why I moved the form validation code from above the form to the after the closing tag was because i wanted the red validation messages to show underneath my sign up button rather than above the sign up fields.

I would like to probably even have this show in a box and i'm guessing I need javascript for this
<?php
// This is the registration page

require_once ('config.inc.php');
$page_title = 'Register';


if (isset($_POST['submitted'])) { // Handle the form.

require_once (MYSQL);

// Trim all the incoming data:
$trimmed = array_map('trim', $_POST);

// Assume invalid values:
$fn = $ln = $e = $p = FALSE;

// Check for a first name:
if (preg_match ('/^[A-Z \'.-]{2,20}$/i', $trimmed['first_name'])) {
$fn = mysqli_real_escape_string ($dbc, $trimmed['first_name']);
} else {
echo '<p class="error">Please enter your first name!</p>';
}

// Check for a last name:
if (preg_match ('/^[A-Z \'.-]{2,40}$/i', $trimmed['last_name'])) {
$ln = mysqli_real_escape_string ($dbc, $trimmed['last_name']);
} else {
echo '<p class="error">Please enter your last name!</p>';
}

// Check for an email address:
if (preg_match ('/^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/', $trimmed['email'])) {
$e = mysqli_real_escape_string ($dbc, $trimmed['email']);
} else {
echo '<p class="error">Please enter a valid email address!</p>';
}


// Check for a password and match against the confirmed password:
if (preg_match ('/^\w{4,20}$/', $trimmed['password'])) {
$p = mysqli_real_escape_string ($dbc, $trimmed['password']);
} else {
echo '<p class="error">Please enter a valid password!</p>';
}

if ($fn && $ln && $e && $p) { // If everything's OK...

// Make sure the email address is available:
$q = "SELECT user_id FROM users WHERE email='$e'";
$r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

if (mysqli_num_rows($r) == 0) { // Available.

// Create the activation code:
$a = md5(uniqid(rand(), true));

// Add the user to the database:
$q = "INSERT INTO users (email, pass, first_name, last_name, active, registration_date) VALUES ('$e', SHA1('$p'), '$fn', '$ln', '$a', NOW() )";
$r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

if (mysqli_affected_rows($dbc) == 1) { // If it ran OK.

// Send the email:
$body = "Thank you for registering at <YOUR SITE NAME>. To activate your account, please click on this link:\n\n";
$body .= BASE_URL . 'activate.php?x=' . urlencode($e) . "&y=$a";
mail($trimmed['email'], 'Registration Confirmation', $body, 'From: you@youremail.com');

// Finish the page:
echo '<h3>Thank you for registering! A confirmation email has been sent to your address. Please click on the link in that email in order to activate your account.</h3>';
//include ('includes/footer.html'); // Include the HTML footer.
exit(); // Stop the page.

} else { // If it did not run OK.
echo '<p class="error">You could not be registered due to a system error. We apologize for any inconvenience.</p>';
}

} else { // The email address is not available.
echo '<p class="error">That email address has already been registered. If you have forgotten your password, use the link at right to have your password sent to you.</p>';
}

} else { // If one of the data tests failed.
/*echo '<p class="error">Please re-enter your passwords and try again.</p>'; */
}

mysqli_close($dbc);

}
// End of the main Submit conditional.
?>

<form action="index_v2.php" method="post">
<h1>Sign Up</h1>
<h2>We connect students worldwide</h2>
<table width="100%" border="0">
<tr>
<td>First Name</td>
<td><input type="text" name="first_name" size="20" maxlength="20" value="<?php if (isset($trimmed['first_name'])) echo $trimmed['first_name']; ?>" /></td>
</tr>
<tr>
<td>Last Name</td>
<td><input type="text" name="last_name" size="20" maxlength="40" value="<?php if (isset($trimmed['last_name'])) echo $trimmed['last_name']; ?>" /></td>
</tr>
<tr>
<td>Email</td>
<td><input type="text" name="email" size="30" maxlength="80" value="<?php if (isset($trimmed['email'])) echo $trimmed['email']; ?>" /></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password" size="20" maxlength="20" /></td>
</tr>
<tr>
<td>Birthday</td>
<td>
<?php
include("bdayselect/DateDDLGenerator.class.php");
$ddl = new DateDDLGenerator;
$ddl_name_Change = new DateDDLGenerator;
$ddl_name_Change->setToCurrentDay();

print $ddl_name_Change->genDayDDL("day");
print $ddl_name_Change->genMonthDDL("month");
print $ddl_name_Change->genYearDDL("year");

?>

</td>
<tr>
<td>I am</td>
<td><select name="sex" class="select" id="sex" >
<option value="0">-Select-</option>
<option value="1">Male</option>
<option value="2">Female</option>
</select>
</td></tr>
<tr>
<td></td>
<td><su><input type="submit" name="submit" value="Sign-Up" /></su></td>
</tr>
</td>
</tr>
</table>


<input type="hidden" name="submitted" value="TRUE" /></p>


</form>






 

<form action="index_v2.php" method="post">
<h1>Sign Up</h1>
<h2>We connect students worldwide</h2>
<table width="100%" border="0">
<tr>
<td>First Name</td>
<td><input type="text" name="first_name" size="20" maxlength="20" value="<?php if (isset($trimmed['first_name'])) echo $trimmed['first_name']; ?>" /></td>
</tr>
<tr>
<td>Last Name</td>
<td><input type="text" name="last_name" size="20" maxlength="40" value="<?php if (isset($trimmed['last_name'])) echo $trimmed['last_name']; ?>" /></td>
</tr>
<tr>
<td>Email</td>
<td><input type="text" name="email" size="30" maxlength="80" value="<?php if (isset($trimmed['email'])) echo $trimmed['email']; ?>" /></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password" size="20" maxlength="20" /></td>
</tr>
<tr>
<td>Birthday</td>
<td>
<?php
include("bdayselect/DateDDLGenerator.class.php");
$ddl = new DateDDLGenerator;
$ddl_name_Change = new DateDDLGenerator;
$ddl_name_Change->setToCurrentDay();

print $ddl_name_Change->genDayDDL("day");
print $ddl_name_Change->genMonthDDL("month");
print $ddl_name_Change->genYearDDL("year");

?>

</td>
<tr>
<td>I am</td>
<td><select name="sex" class="select" id="sex" >
<option value="0">-Select-</option>
<option value="1">Male</option>
<option value="2">Female</option>
</select>
</td></tr>
<tr>
<td></td>
<td><su><input type="submit" name="submit" value="Sign-Up" /></su></td>
</tr>
</td>
</tr>
</table>


<input type="hidden" name="submitted" value="TRUE" /></p>


</form>

<?php
// This is the registration page

require_once ('config.inc.php');
$page_title = 'Register';


if (isset($_POST['submitted'])) { // Handle the form.

require_once (MYSQL);

// Trim all the incoming data:
$trimmed = array_map('trim', $_POST);

// Assume invalid values:
$fn = $ln = $e = $p = FALSE;

// Check for a first name:
if (preg_match ('/^[A-Z \'.-]{2,20}$/i', $trimmed['first_name'])) {
$fn = mysqli_real_escape_string ($dbc, $trimmed['first_name']);
} else {
echo '<p class="error">Please enter your first name!</p>';
}

// Check for a last name:
if (preg_match ('/^[A-Z \'.-]{2,40}$/i', $trimmed['last_name'])) {
$ln = mysqli_real_escape_string ($dbc, $trimmed['last_name']);
} else {
echo '<p class="error">Please enter your last name!</p>';
}

// Check for an email address:
if (preg_match ('/^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/', $trimmed['email'])) {
$e = mysqli_real_escape_string ($dbc, $trimmed['email']);
} else {
echo '<p class="error">Please enter a valid email address!</p>';
}


// Check for a password and match against the confirmed password:
if (preg_match ('/^\w{4,20}$/', $trimmed['password'])) {
$p = mysqli_real_escape_string ($dbc, $trimmed['password']);
} else {
echo '<p class="error">Please enter a valid password!</p>';
}

if ($fn && $ln && $e && $p) { // If everything's OK...

// Make sure the email address is available:
$q = "SELECT user_id FROM users WHERE email='$e'";
$r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

if (mysqli_num_rows($r) == 0) { // Available.

// Create the activation code:
$a = md5(uniqid(rand(), true));

// Add the user to the database:
$q = "INSERT INTO users (email, pass, first_name, last_name, active, registration_date) VALUES ('$e', SHA1('$p'), '$fn', '$ln', '$a', NOW() )";
$r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

if (mysqli_affected_rows($dbc) == 1) { // If it ran OK.

// Send the email:
$body = "Thank you for registering at <YOUR SITE NAME>. To activate your account, please click on this link:\n\n";
$body .= BASE_URL . 'activate.php?x=' . urlencode($e) . "&y=$a";
mail($trimmed['email'], 'Registration Confirmation', $body, 'From: you@youremail.com');

// Finish the page:
echo '<h3>Thank you for registering! A confirmation email has been sent to your address. Please click on the link in that email in order to activate your account.</h3>';
//include ('includes/footer.html'); // Include the HTML footer.
exit(); // Stop the page.

} else { // If it did not run OK.
echo '<p class="error">You could not be registered due to a system error. We apologize for any inconvenience.</p>';
}

} else { // The email address is not available.
echo '<p class="error">That email address has already been registered. If you have forgotten your password, use the link at right to have your password sent to you.</p>';
}

} else { // If one of the data tests failed.
/*echo '<p class="error">Please re-enter your passwords and try again.</p>'; */
}

mysqli_close($dbc);

}
// End of the main Submit conditional.
?>

Matthew1980

7:16 am on Apr 28, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there humanexperience,

Welcome aboard!

Well you seem to have the hang of most things here, there are only a couple of pointers I feel need mentioning.

Firstly.

This:-

value="<?php if (isset($trimmed['first_name'])) echo $trimmed['first_name']; ?>"

can be accomplished with this:-

value="<?php echo (isset($trimmed['first_name'])) ? $trimmed['first_name'] : ''); ?>"

do the sam for the rest of the in the same format, but if you prefer your method, do this:-

value="<?php if (isset($trimmed['first_name'])){ echo $trimmed['first_name'];} ?>"

the only thing wrong was that there were no braces ;-p

Secondly.

Your sql queries:-

$q = "SELECT user_id FROM users WHERE email='$e'";

try this:-

$q = "SELECT `user_id` FROM `users` WHERE `email` ='".$e."' LIMIT 1";

doing it this way I think is easier to read & just to note the backtick's are NOT mandatory, I just find that it is better to get into the habit of doing it just incase there is an occurence whereby you have a space in the field name etc (at least that how I have understood it)

The other sql query:-

$q = "INSERT INTO users (email, pass, first_name, last_name, active, registration_date) VALUES ('$e', SHA1('$p'), '$fn', '$ln', '$a', NOW() )";

Try to get into naming vars according to their tasks too - saves a headache later on ;-p, again, the formatting here can be done like:-

$q = "INSERT INTO `users` (`email`, `pass`, `first_name`, `last_name`, `active`, `registration_date`) VALUES ('".$e."', SHA1('".$p."'), '".$fn."', '".$ln."', '".$a."', NOW() )";

Other than that, everything seems to be ok ;-p

I'm please to see as you are using the mysql_real_escape_string() function though, so often people fail to use and wonder why their DB's are attacked, you can also use strip_tags() too, to get rid of html tags too.

To handle the form a bit better, you can check the value of the submit button:
if (isset($_POST['submitted']) && ($_POST['submitted'] == "Sign-Up")) but I stress this is just a couple of ways of checking, and at the end of the day its a personal preference I guess..

I must stress though, this is meant to be constructive criticisim, just trying to give advice ;-p

Hope this helps,

Cheers,
MRb

humanexperience

9:34 am on Apr 28, 2010 (gmt 0)

10+ Year Member



Thanks alot,

I didn't expect a reply but it's nice that I got one.
I followed some of your advice.

Here is what I changed:
This:-

value="<?php if (isset($trimmed['first_name'])) echo $trimmed['first_name']; ?>" <--original

can be accomplished with this:-

value="<?php echo (isset($trimmed['first_name'])) ? $trimmed['first_name'] : ''); ?>" <---this gave me parse error

so I used your other suggestion
value="<?php if (isset($trimmed['first_name'])){ echo $trimmed['first_name'];} ?>" <---this worked


My sql queries

$q = "SELECT `user_id` FROM `users` WHERE `email` ='".$e."' LIMIT 1"; <--- changed to this

and also edited insert info to:
$q = "INSERT INTO `users` (`email`, `pass`, `first_name`, `last_name`, `active`, `registration_date`) VALUES ('".$e."', SHA1('".$p."'), '".$fn."', '".$ln."', '".$a."', NOW() )"; <-- worked perfectly

I had trouble implementing your suggested value of my submit button.

I would appreciate if you could type out the whole thing for me e.g.

<td><su><input type="submit" name="submit" value="Sign-Up" /></su></td>

Maybe if I copy and paste what you have written it will work.

I also shifted the php code below the </form> but I still get the issue with text typed in the text fields disappearing after signup is clicked and errors are givien.

Please enter your first name!

Please enter your last name!

Please enter a valid email address!

Please enter a valid password!

I basically click signup as soon as my page loads up to see if the errors are workings and they work fine.

So I then fill out only 2 of the required fields e.g. first_name, last_name

The first name and lastname errors disappear when i click signup but the text typed in the box also does this. Then when I click signup again all errors come back.

Also when signup is clicked after all info it filled in the fields no longer disappear and display thank you for registering message.

I find it strange that this all works correctly when the php code is shifted above the form.

(please note the birthday and gender fields aren't in use yet. I'm having trouble deciding how to insert these into the database.. maybe a separate field for day month and year? or have that info inserted into one field dd/mm/year?

Also with gender I'm still wondering whether i should use char or enum or maybe even something else?)

Any ideas?


Edited code
<?php
// This is the registration page for

require_once ('config.inc.php');
$page_title = 'Register';


if (isset($_POST['submitted'])) { // Handle the form.

require_once (MYSQL);

// Trim all the incoming data:
$trimmed = array_map('trim', $_POST);

// Assume invalid values:
$fn = $ln = $e = $p = FALSE;

// Check for a first name:
if (preg_match ('/^[A-Z \'.-]{2,20}$/i', $trimmed['first_name'])) {
$fn = mysqli_real_escape_string ($dbc, $trimmed['first_name']);
} else {
echo '<p class="error">Please enter your first name!</p>';
}

// Check for a last name:
if (preg_match ('/^[A-Z \'.-]{2,40}$/i', $trimmed['last_name'])) {
$ln = mysqli_real_escape_string ($dbc, $trimmed['last_name']);
} else {
echo '<p class="error">Please enter your last name!</p>';
}

// Check for an email address:
if (preg_match ('/^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/', $trimmed['email'])) {
$e = mysqli_real_escape_string ($dbc, $trimmed['email']);
} else {
echo '<p class="error">Please enter a valid email address!</p>';
}


// Check for a password and match against the confirmed password:
if (preg_match ('/^\w{4,20}$/', $trimmed['password'])) {
$p = mysqli_real_escape_string ($dbc, $trimmed['password']);
} else {
echo '<p class="error">Please enter a valid password!</p>';
}

if ($fn && $ln && $e && $p) { // If everything's OK...

// Make sure the email address is available:
//$q = "SELECT user_id FROM users WHERE email='$e'"; <--original of below
$q = "SELECT `user_id` FROM `users` WHERE `email` ='".$e."' LIMIT 1";
$r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

if (mysqli_num_rows($r) == 0) { // Available.

// Create the activation code:
$a = md5(uniqid(rand(), true));

// Add the user to the database:
$q = "INSERT INTO `users` (`email`, `pass`, `first_name`, `last_name`, `active`, `registration_date`) VALUES ('".$e."', SHA1('".$p."'), '".$fn."', '".$ln."', '".$a."', NOW() )";
/* $q = "INSERT INTO users (email, pass, first_name, last_name, active, registration_date) VALUES ('$e', SHA1('$p'), '$fn', '$ln', '$a', NOW() )"; */
$r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

if (mysqli_affected_rows($dbc) == 1) { // If it ran OK.

// Send the email:
$body = "Thank you for registering at <YOUR SITE NAME>. To activate your account, please click on this link:\n\n";
$body .= BASE_URL . 'activate.php?x=' . urlencode($e) . "&y=$a";
mail($trimmed['email'], 'Registration Confirmation', $body, 'From: you@youremail.com');

// Finish the page:
echo '<h3>Thank you for registering! A confirmation email has been sent to your address. Please click on the link in that email in order to activate your account.</h3>';
//include ('includes/footer.html'); // Include the HTML footer.
exit(); // Stop the page.

} else { // If it did not run OK.
echo '<p class="error">You could not be registered due to a system error. We apologize for any inconvenience.</p>';
}

} else { // The email address is not available.
echo '<p class="error">That email address has already been registered. If you have forgotten your password, use the link at right to have your password sent to you.</p>';
}

} else { // If one of the data tests failed.
/*echo '<p class="error">Please re-enter your passwords and try again.</p>'; */
}

mysqli_close($dbc);

}
// End of the main Submit conditional.
?>

<form action="index_v2.php" method="post">
<h1>Sign Up</h1>
<h2>Sign up to connect</h2>
<table width="100%" border="0">
<tr>
<td>First Name</td>
<td><input type="text" name="first_name" size="20" maxlength="20" value="<?php if (isset($trimmed['first_name'])){ echo $trimmed['first_name'];} ?>" /></td>
</tr>
<tr>
<td>Last Name</td>
<td><input type="text" name="last_name" size="20" maxlength="40" value="<?php if (isset($trimmed['last_name'])){ echo $trimmed['last_name'];} ?>" /></td>
</tr>
<tr>
<td>Email</td>
<td><input type="text" name="email" size="30" maxlength="80" value="<?php if (isset($trimmed['email'])){ echo $trimmed['email'];} ?>" /></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password" size="20" maxlength="20" /></td>
</tr>
<tr>
<td>Birthday</td>
<td>
<?php
include("bdayselect/DateDDLGenerator.class.php");
$ddl = new DateDDLGenerator;
$ddl_name_Change = new DateDDLGenerator;
$ddl_name_Change->setToCurrentDay();

print $ddl_name_Change->genDayDDL("day");
print $ddl_name_Change->genMonthDDL("month");
print $ddl_name_Change->genYearDDL("year");

?>

</td>
<tr>
<td>I am</td>
<td><select name="sex" class="select" id="sex" >
<option value="0">-Select-</option>
<option value="1">Male</option>
<option value="2">Female</option>
</select>
</td></tr>
<tr>
<td></td>
<td><su><input type="submit" name="submit" value="Sign-Up" /></su></td>
</tr>
</td>
</tr>
</table>


<input type="hidden" name="submitted" value="TRUE" /></p>


</form>

Matthew1980

10:21 am on Apr 28, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there humanexperience,

Oops! Hold my hands up there ;-p :-

value="<?php echo (isset($trimmed['first_name'])) ? $trimmed['first_name'] : ''); ?>"

Should have been:-

value="<?php echo (isset($trimmed['first_name']) ? $trimmed['first_name'] : ''); ?>"

I had an extra closing bracket there - I have been doing nested ternarys for the last few days ;-p That's my excuse and I'm sticking to it :)

I had trouble implementing your suggested value of my submit button.

I would appreciate if you could type out the whole thing for me e.g.

<td><su><input type="submit" name="submit" value="Sign-Up" /></su></td>

My suggestion was not regarding the html side but the <?php instead. IE:

if (isset($_POST['submitted']) && ($_POST['submitted'] == "Sign-Up")) { // Handle the form.

require_once (MYSQL);

// Trim all the incoming data:
$trimmed = array_map('trim', $_POST);

Maybe if I copy and paste what you have written it will work.


Doing this would negate the need for the hidden field - sorry I wasn't more clear in my original post :)

As for the fields 'retaining' their values if errors occur, you need to use the $_POST vars, not the $trimmed array.

So in a correction from my original post/code try this:-

value="<?php echo (isset($_POST['first_name']) ? $_POST['first_name'] : ''); ?>"

Just try this method, and you should be better..

Ho Hum, back to work ;-p

Cheers,
MRb

humanexperience

10:42 am on Apr 28, 2010 (gmt 0)

10+ Year Member



Thanks Matthew,

Works perfectly.

My next step is to get the birthday and gender fields working with the form and database. I will post in the mysql section for this.

After this I would like to implement captcha to come up on a page after signup is clicked before information is inserted into database.

Or maybe have a javascript popup captcha like on twitter.

So far I'm enjoying this whole programming thing and never thought it would be this interesting. After months of relying on useless programmers overcharging me for messy work I decided enough was enough and started learning myself.

All your help is appreciated. Thanks again.

Matthew1980

12:03 pm on Apr 28, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there humanexperience,

Cool, glad as you are enjoying it - there are times when you want to throw your PC/laptop out the window in frustration :)

Mostly good though.

Some pretty good captcha's out there, google php class repository, they have some good stuff,

Cheers,
MRb