Re: Data validation
[prev]
[thread]
[next]
[Date index for 2004/11/10]
On Wed, 2004-11-10 at 09:56, Drew Taylor wrote:
> First my form display and processing code is in separate methods.
[...]
> If a DFV profile was defined, then run DFV using that profile. If
> there are any errors, store them for later inclusion into the template
> params and DON'T run the processing code. If everything passes, change
> the runmode via prerun_mode() and run the processing method. This
> assumes that the processing will either return a redirect (what I
> typically do to avoid form resubmission problems), or output
> something.
Take a look at CGI::Application::Plugin::ValidateRM. It's pretty
similar to what you're describing, but adds HTML::FillInForm to the
mix. I find it very easy to add new forms this way. I have it hooked
up so that I can inherit from a basic form class and just add a profile
and processing logic. (The template is selected in my base class by
looking at the URI.)
Here's an example:
use base qw/My::Control::Form/;
sub form_profile {
my $self = shift;
my $profile = {
required => [
qw(
password
password_confirmation
)
],
constraints => {
password => {
constraint_method => sub { $_[1] eq $_[2] },
params => [qw( password password_confirmation )],
},
},
};
return $profile;
}
sub fulfill_request {
my $self = shift;
# do important database things here
}
> The only big thing left on my todo list
> is a way to get the templates (TT of course) to automatically include
> the error messages - "[% err_element_name %] beside the form elements.
I set DFV to use specific prefixes so I could grab what I want. This
passes the messages to a template (HTML::Template here, but the
principle is the same):
if ($errs) {
# This ugly piece of code takes the hash of errors and turns the
keys
# and values into hash keys in the template data, using the
message text
# returned by D::FV. The result is that { password => 'invalid' }
becomes
# { invalid_password => 1 }. This is all so that we can keep the
error
# messages in the template, and not in this script.
foreach my $field_name ( keys %{$errs} ) {
# There could be multiple errors on one field
my @error_types = split( /\s/, $errs->{$field_name} );
foreach my $error_type (@error_types) {
my $tmpl_var = $error_type . '_' . $field_name;
$template->param( { $tmpl_var => 1 } );
if ( $error_type ne $FIELD_MISSING ) {
# put invalid fields in so they can be displayed to
the user
$template->param(
{ $field_name =>
$self->query()->param($field_name) } );
}
}
}
$template->param( { 'has_errors' => 1 } );
}
The $error_type is either "missing" or "invalid" and the field name
follows the name of the constraint in my DFV profile. You could use a
strings table or something for these messages, but doing it this way
means I can just keep them in the template:
[% IF invalid_password %]
Your passwords must match.
[% END %]
- Perrin
|
(message missing)
|