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

I have a list of files/directories. I want to display this list in an HTML table having 'n' columns and an arbitrary number of rows. My script will either determine 'n' on it's own or have it passed in as a parameter, but my trouble lies with using the Table object in CGI.pm. I have mastered the part where I turn my list of files into an array (@fil_tbl) of anonymous arrays each of length 'n'. Here's the code I have been trying to make work with the Table object (actually this is the function-based method ... don't flog me):
print table ({width => 200}, (map { $my @t = @$_; Tr ({bgcolor => "#dddddd"}, foreach $fil (@t) { td ("$fil") }) } @fil_tbl ));
I'm getting a syntax error around the foreach statment. I am not sure if I need to enclose the foreach in (), in {}, make it a subroutine call instead, or perhaps I'm not on the right track at all.

Replies are listed 'Best First'.
RE: Creating an HTML table with 'n' rows
by merlyn (Sage) on May 17, 2000 at 19:42 UTC
    foreach is a statement, not an expression, so it can't fit inside another expression (unless you wrapped it in a do block, but that's another set of problems).

    what you want is a map operator. I show many uses of such in my WebTechniques columns. Go there, and cut-n-paste at will.

    -- Randal L. Schwartz, Perl hacker

      You don't have to do this inside the table call. If you initialize your cgi object like this: use CGI qw(*table); then you can use the start_table and end_table with a loop (or anything you want) between them:
      use CGI qw(*table); print start_table({-border=>0, -cellspacing=>0, -width=>'100%'}), "\n" +; for $data (@list) { print "row data loop\n"; } print end_table;
Re: Creating an HTML table with 'n' rows
by athomason (Curate) on May 17, 2000 at 19:53 UTC
    First, both Tr and td expect an array reference as their second argument, not a list. Aesthetically, I'd also suggest using map instead of foreach in the loop. Put together,
    #!/usr/local/bin/perl use CGI qw/:standard/; my @data = ([qw/x y z/], [qw/a b c/], [qw/1 2 3/]); print header, table({-width=>200}, [join '', (map Tr(map td($_), @$_), @data)]);
    will give you what you want, I believe.

    UPDATE

    Whoops! I ignored my own advice. The above should work, but isn't too clear logically. This is what I was trying to do:

    #!/usr/local/bin/perl use CGI qw/:standard/; my @data = ([qw/x y z/], [qw/a b c/], [qw/1 2 3/]); print header, table({-width=>200, -border=>1}, [Tr([map (td([map $_, @$_]), @data)])]);
    Hope that helps.
Re: Creating an HTML table with 'n' rows
by mikfire (Deacon) on May 17, 2000 at 18:32 UTC
    As a hint, I will tell you in vi ( maybe an emacs user could also give the equivalent key ), if you place your cursor on an opening ( or closing ) paren, brace or bracket ( ie (, { or [ ) and hit the % key, it will show you the corresponding closing ( or opening ) symbol.

    Perhaps if you used a bit more whitespace, it would also help.

    Mik
    Mik Firestone ( perlus bigotus maximus )

Re: Creating an HTML table with 'n' rows
by turnstep (Parson) on May 17, 2000 at 19:45 UTC
    Yikes! "Not on the right track at all" gets my vote. Try to at least have the code compile before posting here. Some hints:
    • It's "my", not $my
    • Perl statements should end with semicolons
    • A consistent indenting scheme is a Good Thing - 4 spaces in at the start of a new loop is a popular one

    Arbitrary rows are fairly easy, it's arbitrary columns that are tricky. Just go through your array and add the rows as you go.

      Woops on the $my ... I was developing on UNIX but posting on a PC, and when I transcribed that $ on the my snuck in. :)