You are absolutely correct. I chose to rewrite the original
using nothing but CGI.pm to demonstrate that it can be done.
I do that from time to time just to keep my CGI.pm skills
sharp - while i rarely use CGI.pm in production, i use it
all the time here at the Monastery.
If you look carefully, you will see that checkboxes are
each embedded inside their own table cell ... this makes
using CGI.pm's checkbox_group() next to impossible.
I'll bet a dollar or two that this was the motivation for
checkbox(). This is so much easier to handle with
HTML::Template, IMHO:
use strict;
use warnings;
use CGI qw(param header);
use HTML::Template;
my @entry = (
[qw(one first)], [qw(two second)], [qw(three third)],
[qw(four fourth)], [qw(five fifth)],
[qw(six sixth)], [qw(seven seventh)], [qw(eight eighth)],
[qw(nine ninth)], [qw(ten tenth)],
);
my $tmpl = HTML::Template->new(filehandle => \*DATA);
$tmpl->param(
result => [map {which => $entry[$_][1]}, param 'sel'],
checkbox => [
{ row => [map {label => $entry[$_][0], value => $_}, 0..4] },
{ row => [map {label => $entry[$_][0], value => $_}, 5..9] },
],
);
print header,$tmpl->output;
__DATA__
<tmpl_loop result>
you checked the <tmpl_var which> box<br />
</tmpl_loop>
<form method="POST">
<table>
<tmpl_loop checkbox>
<tr>
<tmpl_loop row>
<td>
<tmpl_var label>
<input value="<tmpl_var value>" type="checkbox" name="sel"/>
</td>
</tmpl_loop>
</tr>
</tmpl_loop>
</table>
<input type="submit" name="go" value="showme" />
</form>
But now we lost form stickiness. Quite some time ago,
samtregar posted
this node that suggests
combining CGI.pm's HTML
form element generating
methods with HTML::Template. We can simplify the template
code even further by allowing CGI.pm's
td() method
to handle that 'loop'. Here goes:
use strict;
use warnings;
use CGI qw(param header checkbox td);
use HTML::Template;
my @entry = (
[qw(one first)], [qw(two second)], [qw(three third)],
[qw(four fourth)], [qw(five fifth)],
[qw(six sixth)], [qw(seven seventh)], [qw(eight eighth)],
[qw(nine ninth)], [qw(ten tenth)],
);
my $tmpl = HTML::Template->new(filehandle => \*DATA);
$tmpl->param(
result => [map {which => $entry[$_][1]}, param 'sel'],
checkbox => [
{ row => td[map checkbox('sel',undef,$_,$entry[$_][0]), 0..4] },
{ row => td[map checkbox('sel',undef,$_,$entry[$_][0]), 5..9] },
],
);
print header,$tmpl->output;
__DATA__
<tmpl_loop result>
you checked the <tmpl_var which> box<br />
</tmpl_loop>
<form method="POST">
<table>
<tmpl_loop checkbox>
<tr><tmpl_var row></tr>
</tmpl_loop>
</table>
<input type="submit" name="go" value="showme" />
</form>
Depending upon how much control your designers need, you
can swing the pendulum in either direction when you combine
HTML::Template with CGI.pm instead of using it as an
alternative/replacement. In the case of a checkbox, there
isn't much to change, and anything you can change should
probably be done via CSS. But in the case of the table
cells (
<td> tags), there could be a lot to
change and taking that away from the designers is probably
not good. However, one could argue that the programmer
should specify the CSS class of the
<td> tag
and allow the designers to define the CSS rules. In that
case, mixing CGI.pm may not be a bad idea.