grinder has asked for the wisdom of the Perl Monks concerning the following question:

Monks, I have a bit of a problem with CGI generating tables with rowspanned cells. I've come up with a ugly solution, but for all I know I could be missing something obvious.

I have an array with an arbitrary number of elements, so I use map to iterate over them and pass the nicely formatted HTML result as an anonymous array to TR, to create the appropriate number of lines. Let's assume, for the sake of the argument, that the values I want to plot are defined as follows:

my %tab = ( abc => [4, 20], def => [9, 20000], ghi => [16, 200000] );

I want to display them like this:

abc4
20
def9
20000
ghi16
200000

If we don't want to bother with the problem of rowspanning for the moment, a simple solution is as follows:

#! /usr/bin/perl -w use strict; use CGI; my $q = new CGI; my %tab = ( abc => [4, 20], def => [9, 20000], ghi => [16, 200000] ); print $q->table( {-border=>"1"}, $q->TR([ map { $q->td( $_ ) . $q->td( $tab{$_}->[0] ) } sort keys %tab ]) );

But to introduce the second rowspanned cell into the picture had me scratching my head. How to you get the second TR element emitted? Looking at the HTML behind the target output, if we remove the table and TR elements, the contents of each row look something like:

<td rowspan="2">abc</td><td>4</td> <td>20</td> <td rowspan="2">def</td><td>9</td> <td>20000</td> <td rowspan="2">ghi</td><td>16</td> <td>200000</td>

I see one possible solution, make the map emit the hash key twice, and use a flip-flop to emit upper row followed by the lower row

my $flipflop = 0; print $q->table( {-border=>"1"}, $q->TR([ map { ++$flipflop % 2 ? $q->td( {-rowspan=>"2"}, $_ ) . $q->td( $tab{$_}->[0 +] ) : $q->td( $tab{$_}->[1] ) } map { $_, $_ } sort keys %tab ]) );

That does the job, but it doesn't strike me as being particularly crystal clear for someone else to understand. Is there some other technique that monks have come up with for dealing with this problem?


print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'

Replies are listed 'Best First'.
(jeffa) Re: Getting CGI to emit table cells with rowspan attribute
by jeffa (Bishop) on May 21, 2002 at 17:46 UTC
    You don't need the flip flop or the other map if you use two separate Tr()'s:
    print $q->table( {-border=>"1"}, map { $q->Tr([ $q->td( {-rowspan=>'2'},$_ ) . $q->td( $tab{$_}->[0] ) ]) . $q ->Tr([$q->td( $tab{$_}->[1] )]) } sort keys %tab );

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)