Let's take a common scenario. A person is registering at a website. They fill in the form details and hit submit. At this point, one of two things can happen.
  1. If the form data is valid, then the form data is committed to data store and the user is acknowledged.
  2. If the form data is invalid, then the user is presented with the form again, and notified of his errors.
The purpose of this post is to show how the CGI::Application plugin CGI::Application::Plugin::ValidateRM can be used in concert with the HTML::Element::Library aspect of HTML::Seamstress to accomplish this task.

the phases of runmode process

In the first phase the user is presented an HTML page which has a section for listing errors:
<h1>Create New Affiliate</h1> <div id="form_errors"> <h1>Please correct the following errors:</h1> <dl id="form_errors_dl"> <dt>field</dt> <dd>problem</dd> </dl> </div> <form action="admin.cgi" method="post"> <table border="0" cellpadding="0" cellspacing="0"> <tr valign="top"> <td align="left"> <table cellspacing="0" class="ntable"> <tr align="left" valign="top"> <th align="right">First Name:</th> <td><input maxlength="64" name="fname" size="24" type="text" value=""></td> </tr> .... BLAH BLAH BLAH
Now, here is the CGI::Application runmode subroutine which renders this page:
sub affiliate_create { my ($app, $err) = @_; # render the 'shell' and 'core' of the webpage my ($s, $o) = $app->tree_guts_common ('Admin::Shell', 'Admin::Aff::Create'); # render (or remove) the error feedback $o->error_feedback($err); $s; }
There are only two lines in this subroutine. The first line renders the webpage. Most webpages have a shell (navbar, footer, sidebar) and a core - the actual content of the current page. That method call handles that... and returns an HTML::Element instance of the HTML tree for the shell and core

Then we call a method on the tree called error_feedback which will either render or remove the error feedback:

package Admin::Aff::Create; use base 'Admin::Base'; sub file { 'admin/aff/create.html' } sub error_feedback { my ($tree, $err) = @_; if ($err) { $tree->iter2(wrapper_ld => [ id => 'form_errors_dl' ], wrapper_data => [ map { [ $_ => $err->{$_} ] } (keys %$err) ], debug => 0 ); } else { $tree->look_down(id => 'form_errors')->delete; } } 1;
If you are familar with HTML::Tree then the above is not too difficult to follow... the iter2 subroutine is part of HTML::Element::Library, which is just a bunch of object-oriented methods for common HTML "templating" tasks.

Notice also that if there is no error feedback, then the error part of the HTML is simply deleted.

on to processing the form

So, within the actual form, we setup a HIDDEN input element which will have CGI::Application route to the runmode to process the form.
<input name="action" type="hidden" value="affiliate_create_process">
And that runmode looks like this:
sub affiliate_create_process { my $app = shift; my ($results, $err_page) = $app->check_rm ('affiliate_create' , 'affiliate_create_form_profile'); if ($err_page) { return $err_page; } else { return "Successful form submission will forward to affiliate detail"; } $results; }
So this reads almost like English. We basically take the form and validate it against a validation profile. And then we simply go back to the registration page or to a confirmation page based on the results of form submission.

what power there is in CPAN modules!

Data::FormValidator is nice. and CGI::Application is nice. But a plugin like CGI::Application::Plugin::ValidateRM is a ultra-powerful synergistic combination of the two.

Just imagine all the code you would have to write to get all that done without it! Thank you markstos for all your hardwork... and let's dont forget that backing all of this is TJ Mather's HTML::FillInForm.

what motivated this post

Recently on the CGI::Application mailing list someone asked the following:
A little bit off topic to the HTML::FillInForm discussion (or maybe no +t). But does anyone know of a module like HTML::FiF that would allow me to fill in other things such as: <span id='error_firstname'></span> So that if I had a static HTML file with a form on it, I could place the error message place holder right where I wanted them at the time that I write the HTML and only activate them on submit by re-reading the .html file and then using HTML::FiF to fill in the form AND the appropriate Fill-In other module to fill in the empty <spans> with the error messages and then return the entire output to the user. I'm about on the edge of rolling my own in a fashion similar to HTML::FillInForm, but thought I would check first. (Otherwise, I might roll out HTML::FillInAnything) I do understand that: a) The concept for this module would be moot if I was generating the form dynamically from a template that could include [% error_firstname %] tags. Which I'm not. But in respect, what I'm looking for is also cleaner than the syntax of <input type='text' name='firstname' value='[% firstname %]'>, which is what we'd be left with if we didn't have HTML::FiF in the first place. b) I could probably do something like <span><!--error_firstname--></span> and have the entire file re-parsed by TT using HTML comment tags as my start / end tags, but I think the fill in approach would still be cleaner.

In reply to form validation with CGI::Application::Plugin::ValidateRM and HTML::Seamstress by metaperl

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.