sub edit_form {
my $self = shift;
my $q = $self->query();
# load the HTML::Template object
my $template = $self->load_tmpl('FormTemplate.tmpl')
|| die "Can't find template FormTemplate.tmpl";
if ($q->param('first_name')) {
# The user has filled in the form, so we
# check the values and update the database
# if everything is OK
my %form_data = $q->Vars;
my %form_profile = (
required => [qw(first_name last_name)],
optional => [qw(email)],
constraints => {
email => 'email',
},
filters => [ 'trim' ],
);
my ($valid, $missing, $invalid, $unknown) = Data::FormValidator->v
+alidate(\%form_data, \%form_profile);
if (@$missing || @$invalid) {
# There were problems with the form
my @errors;
push @errors, map { { 'missing_'.$_ => 1 } } @$missing;
push @errors, map { { 'invalid_'.$_ => 1 } } @$invalid;
$template->param(errors => \@errors);
} else {
# Everything looks good, so update the database
eval {
### Do some database stuff here
My::DB::User->create($valid);
};
if ($@) {
$template->param(errors => [ { failed_on_update => 1} ]);
} else {
# The database was updated successfully
# so display a success page
$template->param(database_updated => 1);
}
}
}
return $self->fillinform(\$template->output());
}
sub fillinform {
my $self = shift;
my $html = shift; # ref to string of HTML
my $fif = new HTML::FillInForm;
return $fif->fill(scalarref => $html,
fobject => $self->query);
}
And the template would have the following fields in it:
<TMPL_INCLUDE NAME="../header.tmpl">
<h2>Registration Form</h2>
<TMPL_IF errors>
<h4 class="error_hdr">There was a problem processing your request</h4>
<ul>
<TMPL_LOOP errors>
<li class="error">
<TMPL_IF invalid_email>The email address you entered does not look l
+ike a valid email address</TMPL_IF>
<TMPL_IF missing_firstname>You are required to provide your first na
+me</TMPL_IF>
<TMPL_IF missing_lastname>You are required to provide your last name
+</TMPL_IF>
<TMPL_IF failed_on_create>Error: Failed to create the new user in t
+he database.</TMPL_IF>
</li>
</TMPL_LOOP>
</ul>
</TMPL_IF>
First Name: <input type="text" name="first_name" size="32" maxlength="
+72"><br />
Last Name: <input type="text" name="last_name" size="32" maxlength="
+72"><br />
email: <input type="text" name="email" size="32" maxlength="
+255"><br />
<input type="submit" name="submit" value="Submit"><input type="reset"
+ name="reset" value="Reset"><br />
<TMPL_INCLUDE NAME="../footer.tmpl">
CGI::Application keeps my code structured nicely, HTML::Template allows me to separate design from code (including the content of error messages intended for the end-user), Data::FormValidator does most of the input field checking, and HTML::FillInForm gives me sticky form fields. And I usually top it off with Class::DBI for the database interface.
This turned out to be a bit longer than I intended, but hopefully someone finds it useful (or someone points out where I can improve things :).
Cheers |