jdtoronto has asked for the wisdom of the Perl Monks concerning the following question:

UPDATED: Code for test case added to message

In a CGI::Application application, I am using CGI::Application::ValidateRM to validate form data. Today I have found a case where ValidateRM appears to fail the validation of a field. It is a time field, and is required in hh:mm:ss format, but if I enter say, 09, I get the following in the results object:

'invalid' => { 'intstart' => [ 'date_and_time' ] }
So I can see the Data::FormValidator seems to be doing its part. Now comes the fun. I am supposed to get an error page back, but I don't!

Here is the runmode that is doing the validating:

sub pr_businesshours_process { my $self = shift; my $q = $self->query; my ($results, $err_page) = $self->check_rm('pr_businesshours_edit_ +display', { required => [qw/intervalid/], optional => [qw/intstart intend intint/], filters => ['trim'], validator_packages => [qw(Data::FormValidator::Constraints +::Dates)], constraints => { intstart => { name => 'date_and_time', constraint_method => 'date_and_time', params => [ \'hh:mm:ss' ], }, intend => { name => 'date_and_time', constraint_method => 'date_and_time', params => [ \'hh:mm:ss' ], }, }, msgs => { constraints => { 'date_and_time' => "Invalid time format", }, any_errors => 'err__', prefix => 'err_', }, } ); print STDERR Dumper $results; #print STDERR $err_page; return $err_page if $err_page; # do something with $results->valid here. my $output = $q->start_html; $output .= "<p>Page appears to have validated<br>Start: " . $q->pa +ram('intstart') . " End: " . $q->param('intend'); return $output; }
And I get this as the output:
Page appears to have validated Start: 09 End: 00:00:00
So you can see that the error page is not being generated.

To try and see what was happening I created a test, and would you know it, it worked perfectly (it is at http://posiedon.mine.nu/app/date_form_validation.cgi if you want to have a look. And the entire code, including the template can be found on jdtoronto's scratchpad. UPDATED: Code here also:

/* date_form_validation.cgi #!/usr/local/bin/perl use strict; use DateFormValidation; my $webapp = DateFormValidation->new(); $webapp->run(); /* DateFormValidation.pm #!/usr/local/bin/perl # package DateFormValidation; use base CGI::Application; use CGI::Application::ValidateRM; use Data::Dumper; use strict; sub setup { my $self = shift; $self->tmpl_path('/home/appsys/www/htdocs/templates/'); $self->start_mode('form_display'); $self->run_modes ( 'form_display' => \&form_display, 'mode_0114' => \&form_process, ); } sub form_display { my $self = shift; my $errs = shift; my $t = $self->load_tmpl('app03/pr_businesshours_edit_test.html', +die_on_bad_params => 0); $t->param($errs) if ref $errs; $t->param( intdow => 'Mon', inttype => 0, intstart => '00:00:00', intend => '00:00:00', intint => 30, dow => 0, providerid => 4, intervalid => 1, ); return $t->output; } sub form_process { my $self = shift; my $q = $self->query; my ($results, $err_page) = $self->check_rm('form_display', $self-> +_bh_profile ); print STDERR Dumper $results; #print STDERR $err_page; return $err_page if $err_page; # do something with $results->valid here. my $output = $q->start_html; $output .= "<p>Page appears to have validated<br>Start: " . $q->pa +ram('intstart') . " End: " . $q->param('intend'); return $output; } sub _bh_profile { return { required => [qw/intervalid/], optional => [qw/intstart intend intint/], filters => ['trim'], validator_packages => [qw(Data::FormValidator::Constraints::Da +tes)], constraints => { intstart => { name => 'date_and_time', constraint_method => 'date_and_time', params => [ \'hh:mm:ss' ], }, intend => { name => 'date_and_time', constraint_method => 'date_and_time', params => [ \'hh:mm:ss' ], }, }, msgs => { constraints => { 'date_and_time' => "Invalid time format", }, any_errors => 'err__', prefix => 'err_', }, }; } 1; /* The template <p>Provider ID: <tmpl_var provider_id></p> <div align="left"> <table border="0" cellpadding="2" cellspacing="2" width="436"> <tr> <td class="lbl">Day</td> <td class="lbl">Type</td> <td></td> <td></td> <td></td> <td></td> </tr> <form name="FormName" action="/app/date_form_validation.cgi" m +ethod="post"> <tr> <td class="value"><tmpl_var intdow></td> <td class="value"><tmpl_var inttype></td> <td class="lbl">Start</td> <td class="value"><input type="text" name="intstart" s +ize="10" value="<tmpl_var intstart>"></td> <td class="err"><tmpl_var err_intstart></td> </tr> <tr> <td></td> <td></td> <td class="lbl">End</td> <td class="value"><input type="text" name="intend" siz +e="10" value="<tmpl_var intend>"></td> <td class="err"><tmpl_var err_intend></td> </tr> <tr> <td></td> <td></td> <td class="lbl">Interval</td> <td class="value"><input type="text" name="intint" siz +e="10" value="<tmpl_var intint>"></td> <td class="err"><tmpl_var err_intint></td> <td><input type="submit" name="_save" value="Save"></t +d> <input type="hidden" value="<tmpl_var dow>" name="dow" +><input type="hidden" value="<tmpl_var providerid>" name="prov"><inpu +t type="hidden" value="<tmpl_var intervalid>" name="intervalid"><inpu +t type="hidden" value="mode_0114" name="rm"></tr> </tr> </form> </table> </div>

CGI::Application::ValidateRM is used extensively throughout the application and works just fine. This is the only place where I use the date/time constraints though.

If anybody has any clues they would be greatly apprecaited, or I am going to have to hack together something else to handle this until I can make it work.

jdtoronto

Replies are listed 'Best First'.
Re: CGI::Application::ValidateRM detects error, but doesn't act on it
by jdtoronto (Prior) on Feb 18, 2004 at 17:44 UTC
    The solution has been found.

    My test case worked because I didn't make the same mistake I made in my Application.

    In my application I have one or two runmodes that handle two actions. Usually a case where I have two buttons on a single form for two related actions on the same data. What I had done was to have two if() blocks for the execution of the two conditions.

    Thus the runmode which is doing the validating gets nothing returned from it when it tries to build the response because it does not have the button parameters from the original CGI.pm query.

    For CGI::Application::ValidateRM to work the runmode being validated must return valid data to the validating method. Internally the ValidateRM module actually runs the method it is being used to validate. It does this to get the messages into the right place, basically. Then it passes the resultant HTML through HTML::FillInForm with the query parameters it used in the validation process, to get the original values back in the form. If it can't do part one of the process then, well, you get nothing!

    Special thank to William McKee on the dfv mailing list for his insightful comment that led me to the solution.

    jdtoronto