I am trying to create a table using CGI.pm. The table would contain results from
querying a database. The array final contains record numbers on which the queries will
be executed. The results for each record should be in a separate row. The result
of each query on the record should form a column in the row. Using some code I found
here, I wrote the following
(which may not be he best way of doing it):
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use DBI;
...
my @rows;
my $rec;
foreach my $el (@final) {
@rows = ();
foreach my $query (@queries) {
my $query_handle = $connxn->prepare($query);
$query_handle->execute($el);
$query_handle->bind_columns(undef, \$rec);
while($query_handle->fetch()) {
push(@rows,td($rec));
}
}
print $q->table({-border=>undef,-width=>'25%'},
Tr(\@rows)
);
}
When I run this, I get a blank page and an error “Undefined subroutine &main::td”
in the error log. Why do I get this error and I how do I get rid of it? Is there any
other way to create a table the table I want using CGI.pm?
Any help would be appreciated. Thanks!
EDIT: Using Sinan’s suggestion, I modified my code as follows:
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use Carp;
use HTML::Template;
...
my @rows;
my $rec;
foreach my $el (@final) {
foreach my $query (@queries) {
my $query_handle = $connxn->prepare($query);
$query_handle->execute($el);
$query_handle->bind_columns(undef, \$rec);
while($query_handle->fetch()) {
push(@rows, { CELLS => [ map { CELL => $_ }, $rec ] });
}
}
}
my $tmpl = HTML::Template->new(filehandle => \*DATA);
$tmpl->param(ROWS => \@rows);
print $tmpl->output;
__DATA__
<table>
<TMPL_LOOP ROWS>
<tr>
<TMPL_LOOP CELLS>
<td><TMPL_VAR CELL></td>
</TMPL_LOOP>
</tr>
</TMPL_LOOP>
</table>
But now I am getting the result of each query in a separate row, instead of the same one
(see original question above). I can’t seem to fix it on my own. Any ideas?
EDIT2: Though I am accepting Sinan’s answer, meanwhile I developed my own solution (in case anyone is interested):
my @rows;
my @rows1;
foreach my $el (@final) {
@rows = ();
foreach my $query1 (@queries) {
my $query_handle = $connxn->prepare($query1);
$query_handle->execute($el);
$query_handle->bind_columns(undef, \$rec);
while($query_handle->fetch()) {
push(@rows, $rec);
}
}
push(@rows1, { CELLS => [ map { CELL => $_ }, @rows ] });
}
I know you think you want to use CGI.pm to generate the tables, but you shouldn’t. The code will be ugly and it will hurt.
Instead, separate presentation from logic. Avoid the HTML generation functions of
CGI.pm. Use a simple templating module such as HTML::Template. Customize the HTML to your heart’s content without messing with your code.Given the update to your question, I think what you need is this: