Item Description: Automagically populate HTML forms with CGI parameters
Review Synopsis:
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!
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:
$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:my $form = new HTML::FillInForm; my $page = $form->fill(scalarref => \$html, fobject => $request);
The Perl to populate this looks something like:<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>
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:$tmpl_form->param( ACTION => "/path/to/my/script.cgi", DEFAULT => $request->param("searchkey"), );
Our Perl transforms into something vastly less elegant:<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>
What a lot of work to do when we can simply:$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" : "" +, );
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.$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);
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
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: HTML::FillInForm
by knowmad (Monk) on Aug 14, 2003 at 12:00 UTC | |
Re: HTML::FillInForm
by bradcathey (Prior) on May 18, 2005 at 13:19 UTC |