It's easy enough to build sticky forms if you use the HTML-generation methods/functions in CGI.pm. But I'm a strong proponent of isolating presentation (HTML) from business logic, so I didn't want to create forms by writing a bunch of code. Instead I wanted a way to leverage the templating system I was already using -- HTML::Template.
I thought about using the logical constructs in HTML::Template to try to create sticky form widgets, but in addition to feeling clumsy, that seemed like an inordinate amount of work. I also looked at HTML::StickyForms, but it didn't seem to offer much that isn't already provided by CGI. HTML::FillInForms looked more promising but I wasn't thrilled by the fact that it relies on HTML::Parser, which seems like it would add a lot of overhead on complex pages. (I'm aware that I could be falling into the premature-optimization trap here, but I wanted to at least explore lighter-weight alternatives.)
The solution I eventually tried was to build a bridge between HTML::Template variables and the sticky form-generation capabilities of CGI. I defined a way to denote form elements using HTML::Template variables. Then my sub that instantiates and populates the template looks for all the template variable names that match a certain pattern, and calls the appropriate CGI element generator to set the value for that template variable. So my form templates now have sections that look something like this:
The basic attributes (field type and name) of the form elements are encoded in the name of the template variable. Field-specific parameters are stored in a hash keyed on the field name, which both allows me to generate items programmatically and avoids requiring some way to encode this information in the template variable name. It also means that if I'm careful about my field naming, multiple templates could refer to a field that will always have the same attributes (for example, a username might always be maxlength=15, size=15, regardless of which form it's on).Your name: <TMPL_VAR NAME="FORM_TEXTFIELD_NAME"><br> Your favorite pastimes: <TMPL_VAR NAME="FORM_LIST_PASTIMES">
This all seems to work fine. But I'd love to get feedback from the folks in this community and also to hear of any other approaches that monks have found fruitful.
$perlmonks{seattlejohn} = 'John Clyman';