Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
After some discussion with grantm, it was suggested that I take a look at HTML::FillInForm because "it's magic". Having used it now, I agree!

HTML::FillInForm takes the form you give it and automagically populates fields on that form with parameters from a CGI object that you also pass it (read: sticky forms). You may be thinking, "I already can do sticky forms with CGI.pm! Why do I need this?" Templating!

While you can use HTML::FillInForm in most any instance (as a substitute for sticky forms with CGI.pm, for example), I have found it to be most invaluable when working with HTML::Template (I imagine it would provide the same benefits for users of TT or HTML::Mason too). It has drastically cut down the complexity and programming required to redisplay a form to a user with their information filled in.

How does it work? First we create the fill-in-form object:

my $form = new HTML::FillInForm; my $page = $form->fill(scalarref => \$html, fobject => $request);
$html contains the HTML of the form to fill in. $request is a CGI object that contains one or more parameters that you would like to fill in your form with. The call to fill() does the rest. It's that easy! fill() returns the HTML of the filled-in form. So how does this save work? Consider the following sample template:
<form method="post" action=<!-- TMPL_VAR NAME=action --> enctype="appl +ication/x-www-form-urlencoded"> <center> <table> <tr> <td valign="top">Pay by </td> <td valign="top"> <input type="radio" name="searchby" value="Parcel" + checked="checked" />Parcel <input type="radio" name="searchby" value="Name" / +>Name <input type="radio" name="searchby" value="Address +" />Address </td> </tr> <tr> <td>Enter Search Value</td> <td><input type="text" name="searchkey" value=<!-- TMP +L_VAR NAME=DEFAULT --> maxlength="255" length="50" /></td> </tr> </table> <input type="submit" name="action" value="Search" /> <input type="submit" name="action" value="Verify" /> <input type="submit" name=".defaults" value="Defaults" /> </center> <input type="hidden" name=".cgifields" value="searchby" /> </form>
The Perl to populate this looks something like:
$tmpl_form->param( ACTION => "/path/to/my/script.cgi", DEFAULT => $request->param("searchkey"), );
Essentially, I have to create an extra TMPL_VAR for each form field that I would like to fill in. With HTML::FillInForm, we can omit the DEFAULT TMPL_VAR and let fill() handle it for us. Not a big deal when dealing with a text field or two, I realize. But what about those radio buttons? Let's adjust our template to account for those:
<form method="post" action=<!-- TMPL_VAR NAME=action --> enctype="appl +ication/x-www-form-urlencoded"> <center> <table> <tr> <td valign="top">Pay by </td> <td valign="top"> <input type="radio" name="searchby" value="Parcel" + <!-- TMPL_IF NAME=PARCEL -->checked="checked"<!-- /TMPL_IF --> />Par +cel <input type="radio" name="searchby" value="Name" < +!-- TMPL_IF NAME=NAME -->checked="checked"<!-- /TMPL_IF --> />Name <input type="radio" name="searchby" value="Address +" <!-- TMPL_IF NAME=ADDRESS -->checked="checked"<!-- /TMPL_IF --> />A +ddress </td> </tr> <tr> <td>Enter Search Value</td> <td><input type="text" name="searchkey" value=<!-- TMP +L_VAR NAME=DEFAULT --> maxlength="255" length="50" /></td> </tr> </table> <input type="submit" name="action" value="Search" /> <input type="submit" name="action" value="Verify" /> <input type="submit" name=".defaults" value="Defaults" /> </center> <input type="hidden" name=".cgifields" value="searchby" /> </form>
Our Perl transforms into something vastly less elegant:
$tmpl_form->param( ACTION => "/path/to/my/script.cgi", DEFAULT => $request->param("searchkey"), PARCEL => $request->param("searchby") eq "Parcel" ? "true" : "" +, NAME => $request->param("searchby") eq "Name" ? "true" : "" +, ADDRESS => $request->param("searchby") eq "Address" ? "true" : "" +, );
What a lot of work to do when we can simply:
$tmpl_form->param( ACTION => "/path/to/my/script.cgi" ); my $html = $tmpl_form->output; my $form = new HTML::FillInForm; $html = $form->fill(scalarref => \$html, fobject => $request);
and be done with it :) And this is just a simple example. Add more complexity to the form and your Perl will grow more complex to account for it. With HTML::FillInForm, you can add complexity to the above form and not have to add any additional code to handle it.

For sake of brevity, I did not include code to validate or detaint parameters here. It goes without saying that you should always be doing those things when processing user input.

One potential downside (note that I don't have benchmarks to back me up) is that it relies upon HTML::Parser to perform its magic. While there's nothing wrong with that, there may be some overhead associated with creating an HTML::Parser object, especially on a high-traffic site (see this node from Ovid). I would expect this to be a rather moot issue on a site running mod_perl.

All in all, an excellent module, and a worthwhile addition to any Perl programmer's bag-of-tricks.

MrCromeDome


In reply to HTML::FillInForm by MrCromeDome

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



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (None)
    As of 2024-04-18 23:40 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found