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

Dear Monks,

I need to create a HTML table (within a CGI script) where I define a header fields and then read some variables from a file ("|" delimited) to populate it. I've done it in a following way :

my @Head = ("Anv. ID", "F\xF6r", "Efter", "Pref", "Bef", "Nytt", "Pr", + "F\xF6r", "Kap"); open (TEMP, "<$tempfil") or die "Kan inte \xF6ppna filen $tempfil"; print $qry->start_form(-action => "http://skinnmaskin/cgi-bin/kon.cgi" +); print $qry->table ({ Border => 1, Cellpadding => 5, bordercolor =>"#FF +FFFF"}, map {Tr(th($_) )} \@Head); while (<TEMP>) { my ($Uid, $Fn, $En, $Pr, $Ank, $Ext, $Or, $Adr) = split /\|/, $_ ; print $qry->table({ Border => 1, Cellpadding => 5, bordercolor =>" +#FFFFFF"}, Tr( td(textfield('UID', "$Uid",6)), td(textfield('FNA', "$Fn",20)), td(textfield('ENA', "$En",35)), td(textfield('PRE', "$Pr",10)), td(textfield('BEF', "$Ext",16)), td(textfield('NYTT', "$Ank",5)), td(checkbox('')), td(checkbox('')), td(checkbox('')) ) ) ; }
The problem is that I get a table with a header row which does not fit other columns. Now I've thought of using line counter for a file and unless or until or some other alternatives, but I can't get it work ! Can you please help ? Thanks in advance.

Replies are listed 'Best First'.
Re: HTML table creation
by davido (Cardinal) on Jul 27, 2012 at 19:24 UTC

    As I looked at how you might rework the existing code so that you're only generating one table (you could move a map inside of your print $qry->table(.....), and eliminate the while loop, while moving the preceding table where it belongs inside of the second table), I gained a whole new appreciation for how things like HTML::Template, HTML::Embperl (and Mojolicious's "embedded Perl" templates) are a lot easier to work with.

    The beauty of a nice templating system is that you can write your HTML, and wherever you need a loop and some variables, drop back into Perl (or some other quasi-language) for a moment. It's been years since I've worked with CGI, and I had forgotten how great templating systems can be by comparison to CGI.pm's native html functions.


    Dave

Re: HTML table creation
by CountZero (Bishop) on Jul 27, 2012 at 19:14 UTC
    Have a look at HTML::Table.

    And HTML::Table::FromDatabase allows you to easily populate your table with data from a database (or your delimited file).

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
Re: HTML table creation
by tobyink (Canon) on Jul 27, 2012 at 19:16 UTC

    The problem is that you're calling the $qry->table() method multiple times: once before the while loop, and then once more for each iteration of the loop. If you're only writing one table, then you should only be calling that method once.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      Thanks tobyink for your answer, I've tried to do that but obviously I couln't manage to do that. I've tried to make a sub routine for a WHILE loop and call it as a reference, but no success. Any suggestion of how to do it in one line ?

        This does it:

        my @Head = ("Anv. ID", "F\xF6r", "Efter", "Pref", "Bef", "Nytt", "Pr", + "F\xF6r", "Kap"); open my $temp, '<', $tempfil or die "Kan inte \xF6ppna filen $tempfil"; print $qry->start_form(-action => "http://skinnmaskin/cgi-bin/kon.cgi" +); print $qry->table( { Border => 1, Cellpadding => 5, bordercolor =>"#FFFFFF" }, Tr(map { th($_) } @Head), (map { my ($Uid, $Fn, $En, $Pr, $Ank, $Ext, $Or, $Adr) = split m{[|]} +; Tr( td(textfield('UID', $Uid, 6)), td(textfield('FNA', $Fn, 20)), td(textfield('ENA', $En, 35)), td(textfield('PRE', $Pr, 10)), td(textfield('BEF', $Ext, 16)), td(textfield('NYTT', $Ank, 5)), td(checkbox('')), td(checkbox('')), td(checkbox('')), ); } <$temp>), #/map ); #/table

        Untested of course, as I don't have a copy of your input data. There are certainly better ways to do it (the HTML generation functions of CGI.pm are not how I'd go about generating HTML at all) but it sticks pretty closely to your original code.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: HTML table creation
by Anonymous Monk on Jul 28, 2012 at 02:43 UTC