How to show form errors on same page

Dave96

Perch
Hi,
i have an email form that gets validated through a php script. The php scripts shows the errors on a new page with a "back" button. I'd like to write a new script that would show the errors on the same page but i am unable to make it work.

Anyone would know of a simple code to make this work?
 
what I use to do is is pass the data on to a processing script that would verify the data. If the data is wrong, it would call the original page back passing back the data that was incorrect.

You can also use javascript to have verification done directly on the visitor's browser
 
you use sessions to bring the data back? and if and else i'm guessing?

would you mind giving a quick exemple?
 
Yash said:
You can also use javascript to have verification done directly on the visitor's browser

Bare in mind that client side form verification does not replace regular server side verification. It's only purpose should be to warn the user of mistakes before they actually submit a form.

If you don't do sufficient server side verification because you're already doing it client side, you're possibly leaving your site vulnerable to hacking (depending on what the form does of course).
 
Here's an example. It came out somewhat ugly as a result of trying to keep it short, but hopefully you'll get the idea.

I normally tend to put the actual processing of a form in a different file like Yash, but with forms such as these it's not very practical, unless you include() the other source file. Otherwise you'll have to redirect back and forth with a bunch of form variables in a querystring :p

PHP:
<?php

function VerifyForm(&$values, &$errors)
{
	// Do all necessary form verification
	
	if (strlen($values['name']) < 3)
		$errors['name'] = 'Name too short';
	elseif (strlen($values['name']) > 50)
		$errors['name'] = 'Name too long';
		
	// Needs better checking ;)
	if (!ereg('.*@.*\..{2,4}', $values['email']))
		$errors['email'] = 'Email address invalid';

	if (strlen($values['text']) == 0)
		$errors['text'] = 'Text required';
		
	return (count($errors) == 0);
}

function DisplayForm($values, $errors)
{
	?>
	<html>
	<head>
		<title>Yadda yadda</title>
		<style>
			TD.error
			{
				color: red;
				font-weight: bold;	
			}
		</style>
	</head>
	<body>
	
	<?php
	if (count($errors) > 0)
		echo "<p>There were some errors in your submitted form, please correct them and try again.</p>";
	?>
	
	<form action="<?= $_SERVER['PHP_SELF'] ?>" method="POST">
	<table>
		<tr>
			<td>Name:</td>
			<td><input type="text" size="30" name="name" value="<?= htmlentities($values['name']) ?>"/>
			<td class="error"><?= $errors['name'] ?></td>
		</tr>
		<tr>
			<td>Email:</td>
			<td><input type="text" size="30" name="email" value="<?= htmlentities($values['email']) ?>"/>
			<td class="error"><?= $errors['email'] ?></td>
		</tr>
		<tr>
			<td valign="top">Text:</td>
			<td>
				<textarea name="text" cols="30" rows="6"><?= htmlentities($values['text']) ?></textarea>
			</td>
			<td class="error"><?= $errors['text'] ?></td>
		</tr>
		<tr><td colspan="2" align="center"><input type="submit" value="Submit"></tr>
	</table>
	</form>
	
	</body>
	</html>
	<?php
}

function ProcessForm($values)
{
	mail('[email protected]', 'Form test', $values['text'], "From: \"{$values['name']}\" <{$values['email']}>");
	
	// Replace with actual page or redirect :P
	echo "<html><head><title>Thank you!</title></head><body>Thank you!</body></html>";
}

if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
	$formValues = $_POST;
	$formErrors = array();
	
	if (!VerifyForm($formValues, $formErrors))
		DisplayForm($formValues, $formErrors);
	else
		ProcessForm($formValues);
}
else
	DisplayForm(null, null);
?>

Note that the <?= ?> syntax is officially deprecated, so it's bad habit. I'm just being lazy here :p

I'm actually making a copy of the $_POST array here, which doesn't seem necessary. However, this method allows you to make adjustments to the form values that will appear back into the "retry" form.

If you aren't familiar with pass-by-reference variables, the &$variable syntax prevents PHP4 from making a copy of the passed variable. Instead, the local variable name will point to the same variable in memory, allowing you to make modifications to it that will be visible outside the function scope.
Alternatively, you could use global variables, but in general global variables are best avoided.
 
Hey thanks alot subspace that pretty much what i was looking for. I'd need to integrate this script into my already existing send mail form and other various forms since i'm already submitting these forms to other files not php self i'm trying to build a sign up form with on page error checking.

It looks quite complicated to execute that script without it being on the same html page code. Maybe i'm just too noobish


I have a method already but it just displays the error on top f the page it pretty simple.


PHP:
if(empty($name)) {
echo "<p class='style3'>Fill in your name";
include('form.php');
exit;
}

instead of

PHP:
if(empty($name)) {
include_header($header);
echo "<p class='style3'>Fill in your name";
include_footer($footer);
exit;
}
 
Hey subspace thank you very much for htis tiny script i managed to integrate it perfectly in my contact form as well as various others.

The only minor problem i had was keeping the value selected from a select menu (rolldown menu) when an error occured in another field.
The rolldown cam back as empty.

Would you have a fix for this problem? I tried putting html entity in each value but it would not work.
 
The syntax for dropdown lists is different, if you want a certain option in a dropdown list selected you have to use HTML such as:

Code:
<select name="duration">
  <option value="1">day</option>
  <option value="7" selected="selected">week</option>
  <option value="14">fortnight</option>
</select>

It's somewhat annoying to have to include a conditional statement in every option to have PHP produce the proper output, so I normally use a helper function to output option lists.

PHP:
<?php
function outputOptionList(&$list, $selected)
{
	foreach ($list as $item)
		echo "<option value=\"{$item['Value']}\"" . ($item['Value'] === $selected ? " selected=\"selected\"" : '') . ">{$item['Text']}</option>\n";
}

$optionList = array(
	array('Value' => '1', 'Text' => 'day'),
	array('Value' => '7', 'Text' => 'week'),
	array('Value' => '14', 'Text' => 'fortnight')
	);
?>

<select name="duration">
	<? outputOptionList($optionList, $values['duration']); ?>
</select>
?>

To see something similar in the complete example, see http://www.subbot.net/temp/mailform.php.txt.
To see it work, use http://www.subbot.net/temp/mailform.php (actual mailing is disabled :p)
 
thank you very very much this script is awsome!
my contact form is done, managed to integrate all the features your script offered plus my own personalized process function that autoresponds and other varioud features.

thanks again!
 
Would there be a way of doing the same thing to radio buttons and check boxes?? Sorry if i keep coming back, your support would be greatly appreciated!
 
Yes, you can output the correct HTML much in the same way as it's done in the outputOptionList function.

<input type="checkbox" name="optin" value="yes" checked="checked" />

Will result in a prechecked checkbox on your page (XHTML version)
Shouldn't be too hard to figure out :D
 
the line above is what will be outputed or what should be in the actual php?

I guess it should be in a seperate function? I'm new to php so I'm a little confused.

Here's what i tried

PHP:
<?
function outputRadio(&$radio, $checked) 
{ 
	foreach ($radio as $item) 
		echo "<input name=\"type_domain\" type=\"radio\" value=\"{$item['Value']}\"" . ($item['Value'] === $checked ? " checked=\"checked\"" : '') . ">\n";
} 
?>
     <form action="<?= $_SERVER['PHP_SELF'] ?>" method="POST" name="signup">
      				<? $optionRadio = array( 
 					array('Value' => 'sales', 'Text' => 'Sales'), 
   					array('Value' => 'billing', 'Text' => 'Billing'), 
   					array('Value' => 'support', 'Text' => 'Support'),
       				);
					?>
    <? 
outputRadio($optionRadio, $values['type_domain']);
  ?>
<input type="submit" name="Submit" value="Submit">
    </form>
And i noticed something if i gotta do this for a country rolladown list its gonna take me hours!!! 8o
 
SubSpace said:
Here's an example. It came out somewhat ugly as a result of trying to keep it short, but hopefully you'll get the idea.

I normally tend to put the actual processing of a form in a different file like Yash, but with forms such as these it's not very practical, unless you include() the other source file. Otherwise you'll have to redirect back and forth with a bunch of form variables in a querystring :p

PHP:
<?php

function VerifyForm(&$values, &$errors)
{
	// Do all necessary form verification
	
	if (strlen($values['name']) < 3)
		$errors['name'] = 'Name too short';
	elseif (strlen($values['name']) > 50)
		$errors['name'] = 'Name too long';
		
	// Needs better checking ;)
	if (!ereg('.*@.*\..{2,4}', $values['email']))
		$errors['email'] = 'Email address invalid';

	if (strlen($values['text']) == 0)
		$errors['text'] = 'Text required';
		
	return (count($errors) == 0);
}

function DisplayForm($values, $errors)
{
	?>
	<html>
	<head>
		<title>Yadda yadda</title>
		<style>
			TD.error
			{
				color: red;
				font-weight: bold;	
			}
		</style>
	</head>
	<body>
	
	<?php
	if (count($errors) > 0)
		echo "<p>There were some errors in your submitted form, please correct them and try again.</p>";
	?>
	
	<form action="<?= $_SERVER['PHP_SELF'] ?>" method="POST">
	<table>
		<tr>
			<td>Name:</td>
			<td><input type="text" size="30" name="name" value="<?= htmlentities($values['name']) ?>"/>
			<td class="error"><?= $errors['name'] ?></td>
		</tr>
		<tr>
			<td>Email:</td>
			<td><input type="text" size="30" name="email" value="<?= htmlentities($values['email']) ?>"/>
			<td class="error"><?= $errors['email'] ?></td>
		</tr>
		<tr>
			<td valign="top">Text:</td>
			<td>
				<textarea name="text" cols="30" rows="6"><?= htmlentities($values['text']) ?></textarea>
			</td>
			<td class="error"><?= $errors['text'] ?></td>
		</tr>
		<tr><td colspan="2" align="center"><input type="submit" value="Submit"></tr>
	</table>
	</form>
	
	</body>
	</html>
	<?php
}

function ProcessForm($values)
{
	mail('[email protected]', 'Form test', $values['text'], "From: \"{$values['name']}\" <{$values['email']}>");
	
	// Replace with actual page or redirect :P
	echo "<html><head><title>Thank you!</title></head><body>Thank you!</body></html>";
}

if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
	$formValues = $_POST;
	$formErrors = array();
	
	if (!VerifyForm($formValues, $formErrors))
		DisplayForm($formValues, $formErrors);
	else
		ProcessForm($formValues);
}
else
	DisplayForm(null, null);
?>

Note that the <?= ?> syntax is officially deprecated, so it's bad habit. I'm just being lazy here :p

I'm actually making a copy of the $_POST array here, which doesn't seem necessary. However, this method allows you to make adjustments to the form values that will appear back into the "retry" form.

If you aren't familiar with pass-by-reference variables, the &$variable syntax prevents PHP4 from making a copy of the passed variable. Instead, the local variable name will point to the same variable in memory, allowing you to make modifications to it that will be visible outside the function scope.
Alternatively, you could use global variables, but in general global variables are best avoided.
I tried to implement your piece of code and it worked in general. However, I need to pass some variables to another form if there were no errors found. I am new to php and any additional help to pass the variables to the new form would be great.
 
Back
Top