Page #1 contains a link to page #2. Page #2 contains a form which runs my script upon submission.
If the data doesn't validate, I would like to reload page #2 with an error message. (I can handle adding the message, I just need a way to trigger the page reload)
If the data does validate, I would like to force the browser to backup and display page #1. I do not wish to add a new iteration of page #1 after page #2, I want to go back to the previous page.
I considered using javascript to submit the form, but I cannot figure out a way to inform javascript whether the validation passed/failed.
Does anybody have any suggestions?
Here's an "outline" that might work for you. Instead of having a "page #2", just put it all in your script. This allows you to dynamically populate the fields on error. So page one, you have
<a href="join.cgi">join now</a>
And the "outline" would be something like this:
%data = &read_parse;
Whatever read parse routine you use, be sure to cleanse the data at the same time, probably a topic for another thread.
With all input in key/value pairs in %data, look for anything that equates to "form submitted." You could use, say, a hidden field right in the form,
<input type="hidden" name="fs" value="1">
Alternatively, use any of the form fields to determine if it's submitted.
So your program starts off with
$errors = '';
if ($data{'fs'}) { &attempt_to_process; }
## or, "if ($data{'email'}," or any other form field
else { &display_form; }
&display_form does just what your page #2 does, outputs the form, but if there is user-submitted data, you populate the fields. If there is any error in &attempt_to_process, you output those errors above the form. Something like
sub display_form {
my ($form);
if ($errors ne '') {
$form .= qq¦<p style="color:#ff0000; font-weight:700;">Errors were encountered in processing this form:</p><ul>$errors</ul>¦;
}
$form .= qq¦
<form method="post" action="join.cgi">
<input type="hidden" name="fs" value="1">
<label for="email">Email:</label> <input type="text" name="email" id="email" value="$data{'email'}">
...
</form>
¦;
print "content-type: text/html\n\n";
print $form;
exit 0;
}
So the first time it loads,
- There are no errors, so just the form displays.
- There is no "$data{'email'}" (or other submitted data) so the field values are blank. But if it gets submitted, and there's a value there, it will populate whatever they entered.
In attempt_to_process, you'd do your data checks with a third sub that compiles a list of errors (note the "<ul>" in the error string.) If no errors are encountered, you process the form. Some typical error checks:
- required fields blank?
- valid email address?
- malicious data found?
sub attempt_to_process {
$errors = &check_data;
if ($errors ne '') { &display_form; }
else {
®ister_in_database;
&send_email_confirmation;
&thank_you;
}
}
sub check_data {
my ($dataError,$v,%requireds);
$dataError = '';
%requireds = (
'email' => 'email address',
'pwd' => 'password',
'fn' => 'first name',
'ln' => 'last name'
);
foreach $v (keys %requireds) {
unless ($data{$v} =~ /\w+/) {
$dataError .= qq¦<li>The $requireds{$v} field is required.</li>¦;
}
## You'd also add valid email checks here, check for malicious data, etc.
return $dataError;
}
If you really want to redirect back to page 1, that's fine, &thank_you can be a simple
sub thank_you {
print "Location:page1.html\n\n";
}
but why do that when you already have all the data in hand . . .
sub thank_you {
my ($out);
$out = qq¦
<p>Thank you for joining $data{'fn'}! An email confirmation has been sent to $data{'email'}.</p>
...... (you could emulate all submitted data here, or display help files . . whatever . . . . )
<p><a href="/">Main Page</a> \¦ <a href="page1.html">Page One</a></p>
¦;
print "content-type: text/html\n\n";
print $out;
exit 0;
}
There's a lot of blanks to fill in here, but it's a fun journey, good luck!