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

I'm drawing XX amount of entries from my database and I need to output them into two HTML cells, like so
() apple () pear () orange () berry
Essentially I'd like them to be alphabetical from top to bottom and left to right but I want it split up half way so each side has the same number of entires (there could be an extra, of course).

To make it harder (not necessary), I'd like to have to option to break it into 3 sections if my number of items is greater than a certain number, say: 0-50 will have two columns, 50+ will have 3 columns.

print qq~ <form action="" method="post"> <table width="400" border="1" cellspacing="0" cellpadding="1"> <tr> <td colspan="2"><div align="center">Select search engines you wish + to submit to </div></td> </tr> <tr> ~; # break up data into 2 or three columns here #<td width="195">&nbsp;</td> #<td width="195">&nbsp;</td> my $data = qq(SELECT id, name FROM engine WHERE status="1"); my $sth = $dbh->prepare($data); $sth->prepare() or die $dbh->errstr; my ($id, $name); $sth->bind_columns(\$id, \$name); #i while($sth->fetch) { print qq(<input type="checkbox" name="choice" value="$id" /> - +$name); } print qq~ </tr> <tr> <td colspan="2">&nbsp;</td> </tr> <tr> <td colspan="2"><input type="submit" name="Submit" value="Page3" / +></td> </tr> </table> ~;

Replies are listed 'Best First'.
Re: how to split html printout into two table cells
by grep (Monsignor) on Dec 10, 2006 at 21:30 UTC

    I would definately use a Templating solution. It's easier to maintain when you move your presentation out of your code.

    Do the sort in the database using ORDER BY.

    Here is some code to get you started

    use strict; use warnings; use Template; my %vars; $vars{list} = [ qw/apple pear cherry orange kiwi banana lemon lime /]; $vars{cols} = 3; $vars{end} = $#{$vars{list}}; print "$vars{end}\n"; #### TEMPLATE INLINE FOR EXAMPLE my $template = qq| <table> [% cnt = 0 %] [% FOREACH item = list %] [% IF !(cnt % cols) %]<tr>[% END %] <td>[% item %]</td> [% IF ((cnt % cols) == (cols - 1) or (cnt == end)) %]</tr +>[% END %] [% cnt = cnt + 1 %] [% END %] </table> |; my $tt = Template->new(); $tt->process(\$template,\%vars) || die "Template process failed: ", $t +t->error(), "\n";

    grep
    XP matters not. Look at me. Judge me by my XP, do you?

Re: how to split html printout into two table cells
by sgifford (Prior) on Dec 11, 2006 at 01:03 UTC
    One useful trick for this sort of problem is using the modulus operator, %:
    use constant MAX_ITEMS_PER_COLUMN => 25; my @list = (1..50); my $numcols = int(@list / MAX_ITEMS_PER_COLUMN); print "<table><tr>\n"; for(my $i=0;$i<@list;$i++) { print "<td>$list[$i]</td>"; if ($i % $numcols == ($numcols - 1)) { # Start a new row print "</tr><tr>\n"; } } print "</tr></table>\n";
Re: how to split html printout into two table cells
by Melly (Chaplain) on Dec 10, 2006 at 21:44 UTC

    In terms of the basic arrangement, I'd approach it like this:

    #some values to use my @items = qw(oranges apples pears lemons kumquats); #sort 'em @items = sort @items; # we want to output, e.g. # A | D # B | E # C | # so we need the offset for D, #and a kludge to avoid warning on non-existent array elem. when printi +ng odd num of items my $item_count = @items; my $offset = int(($item_count+1)/2); push @items, ''; map{ print "$items[$_] | $items[$_ + $offset]\n"; }0..($offset-1);
    map{$a=1-$_/10;map{$d=$a;$e=$b=$_/20-2;map{($d,$e)=(2*$d*$e+$a,$e**2 -$d**2+$b);$c=$d**2+$e**2>4?$d=8:_}1..50;print$c}0..59;print$/}0..20
    Tom Melly, pm@tomandlu.co.uk
Re: how to split html printout into two table cells
by Cody Pendant (Prior) on Dec 11, 2006 at 06:58 UTC
    Here's the way I've always done it in order to get totally flexible tables using HTML::Template -- the entire table is an AoHoAoH and you set the number of columns and rows in the code, not the HTML.

    It feels a bit kludgy but I'd love monks to help me clean it up if they have any ideas:

    #!/usr/bin/perl use warnings; use strict; use HTML::Template; my $template = HTML::Template->new( filehandle => \*DATA ); my $total_cells = 101; my $max_column_height = 25; my $row_width = int( $total_cells / $max_column_height ); my @table = (); my @row_array = (); my %row_hash = (); for ( 1 .. $total_cells ) { push( @row_array, { content => $_ } ); if ( scalar(@row_array) == $row_width ) { my @array = @row_array; push( @table, { columns => \@array } ); @row_array = (); } } if ( @row_array ) { # if there's a row that's incomplete while ( scalar(@row_array) != $row_width ) { push( @row_array, { content => '&nbsp;' } ); } push( @table, { columns => \@row_array } ); } $template->param( table => \@table ); open( TABLE, '>table.html' ) || die($!); print TABLE $template->output(); __DATA__ <table border="1"> <tmpl_loop name="table"> <tr> <tmpl_loop name="columns"> <td><tmpl_var name="content"></td> </tmpl_loop> </tr> </tmpl_loop> </table>


    ($_='kkvvttuu bbooppuuiiffss qqffssmm iibbddllffss')
    =~y~b-v~a-z~s; print