Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
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":



  • 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, 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, 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.
  • 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 perusing the Monastery: (2)
    As of 2024-09-10 23:44 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?
      The PerlMonks site front end has:





      Results (10 votes). Check out past polls.

      Notices?
      erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.