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

Hello Monks,

I have been stucked trying to align the rows in my
Perl-generated table for a few days now and can not seem
to find an appropriate solution so I am hoping you could
help me out. Since the number of columns and rows are
dynamically generated based on the user's input, it becomes
more apparent as more rows are created. Please take
a look and give me any suggestion that you may have.
Thanks.
This is my HTML code that call the perl script:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> </head> <body TEXT="#00325D"> <form method="post" action="/cgi-bin/test.cgi"> <br> <br> <b>Number of Tests to Run:</b><input type="text" name="Run" size="5" v +alue="3"><br> <b>Number of Enterprise User Groups:</b><input type="text" name="Group +s" size="5"i value="2"><br> <br><input type="Submit" name="Next" value="Next"></pre> </form> </body> </html>


This is the Perl script:

#!/usr/bin/perl use HTML::Template; use CGI qw(:standard); use CGI::Carp qw(warningsToBrowser fatalsToBrowser); my $run = param('Run'); my $group = param('Groups'); $| = 1; $data_path = "/var/www/html/cgi_data/"; $html_root = "/"; $cgi_root = "/cgi-bin"; @alpha = ('A' .. 'Z'); print "Content-type: text/html\n\n"; print "<html>"; print "<head>"; print "</head>"; print '<body TEXT="#00325D">'; print '<form method="post" action="/cgi-bin/test.cgi">'; print "<br>"; print '<FONT face="Courier New">'; print '<table border="1">'; print '<col width="430"></col>'; my $i = 0; while ($i < $run) { print '<col width="170"></col>'; $i++; } print '<tr><th align="left"><b>&nbsp Test file name:</b>&nbsp<input ty +pe="text" name="Name" size="25" value="H2.Test"></th>'; my $i = 0; while ($i < $run) { $i++; print qq{<th BGCOLOR="#FF0000"><FONT COLOR="FFFFFF">Test $i</font>< +/th>}; } print "</tr>"; print qq{<tr><td rowspan="3" valign="top" align="left"><b>&nbsp Vault +to Stress Test</b><br>&nbsp&nbsp&nbsp Name<br>&nbsp&nbsp&nbsp Max mem +ory for JVM</td>}; my $i = 0; while ($i < $run) { $i++; print '<td align="center"><br><input type="text" name="mem1" size="15 +"><br><input type="text" name="mem1" size="15"></td>'; } print "<tr></tr>"; print "<tr></tr>"; $rowsp = 1 + $group*4; my $i = 0; my $j = 0; print qq{<tr valign=top><td rowspan="$rowsp" align="left"><table borde +r="1"><col width="425"><tr><td><b>&nbsp Virtual User Analysis Engine< +/b> </td></tr><tr><td><br></td></tr>}; while ($j < $group) { my $temp = $alpha[$j]; $j++; print qq{<tr><td>&nbsp&nbsp&nbsp Enterprise Group $temp users</td> +</tr><tr><td>&nbsp&nbsp&nbsp&nbsp&nbsp Average requests/min</td></tr> +<tr ><td>&nbsp&nbsp&nbsp&nbsp&nbsp Average number fields/request</td></tr> +<tr><td>&nbsp&nbsp&nbsp&nbsp&nbsp % read/write/update</td></tr>}; print "<tr><td><br></td></tr>"; } print qq{<tr><td>&nbsp&nbsp&nbsp Excel Users</td></tr><tr><td>&nbsp +&nbsp&nbsp&nbsp&nbsp Excel files opened/hour</td></tr><tr><td>&nbsp&n +bsp &nbsp&nbsp&nbsp Protected cell: average number/file</td></tr><tr><td>& +nbsp&nbsp&nbsp&nbsp&nbsp % added/changed when saved</td></tr>}; #print "<tr><td><br></td></tr>"; #print "<tr><td><br></td></tr>"; print "</table>"; print "</td>"; while ($i < $run) { $i++; print qq{<td rowspan="$rowsp"><table border="1"><col width="165"> +<tr><td><br></td></tr>}; my $j = 0; while ($j <= $group) { $j++; print "<tr><td><br></td></tr>"; print "<tr><td><br></td></tr>"; print '<tr align="center"><td><input type="text" name="test1" + size="15"></td></tr><tr align="center"><td><input type="text" name=" +mem 1" size="15"></td></tr><tr align="center"><td><input type="text" name= +"mem1" size="15"></td></tr>'; } print "</table></td>"; } my $i = 0; while ($i < ($group * 4)) { $i++; print qq{<td rowspan="$rowsp"><table border="1"><col width="165"> +<tr><td><br></td></tr>}; my $j = 0; while ($j <= $group) { $j++; print "<tr><td><br></td></tr>"; print "<tr><td><br></td></tr>"; print '<tr align="center"><td><input type="text" name="test1" + size="15"></td></tr><tr align="center"><td><input type="text" name=" +mem 1" size="15"></td></tr><tr align="center"><td><input type="text" name= +"mem1" size="15"></td></tr>'; } print "</table></td>"; } my $i = 0; while ($i < ($group * 4)) { $i++; print "<tr></tr>"; } print '<tr><td align="left"><b>&nbsp Run TPD Stress Test For:</b></td> +'; my $i = 0; while ($i < $run) { $i++; print qq{<td><center><input type="text" name="mem1" size="15"></cen +ter></td>}; } print "</tr>"; print "</table>"; print "</font"; print "</form>"; print "</body>"; print "</html>";

Replies are listed 'Best First'.
Re: Perl/Html Question - rows are not aligned between different columns
by dpmott (Scribe) on Nov 02, 2007 at 17:49 UTC
    I haven't run your code, but a quick inspection shows me that you're trying to align things with ' '. Experience tells me that this is a poor way to do it. What you really want is a number of '<td>' per row, to form actual columns. If you need these columns to be a fixed width, you should make them look like '<td width="50">' (in pixels) or '<td width="10%">' (in percentage width of the screen). You can also specify how wide the whole table is by saying '<table width="numeric_percentage_or_pixels" ...>'

    Keep in mind that columns must be accounted for in each row, so if you want a row to have 5 columns, and then the next row to only have three, then you may need to use '<td colspan="2">' for a couple of the table data cells in the second row.

    I think that you may benefit from reading up on some HTML formatting guidlines, perhaps on w3schools.com.
Re: Perl/Html Question - rows are not aligned between different columns
by technojosh (Priest) on Nov 02, 2007 at 18:20 UTC
    In addition to the comments about html formatting, take a look at the docs for CGI.pm You are already using it, it appears, so you could be taking advantage of quite a few html shortcuts it provides.

    CGI.pm CPAN link

Re: Perl/Html Question - rows are not aligned between different columns
by jfluhmann (Scribe) on Nov 02, 2007 at 21:39 UTC
    You may also want to check out Template Toolkit. I've moved away from having HTML in my Perl (and Perl in my HTML).
Re: Perl/Html Question - rows are not aligned between different columns
by NetWallah (Canon) on Nov 03, 2007 at 01:20 UTC
    Without going into too much detail - I noticed you generate multiple "table" tags in the HTML.

    My experience with this is that, depending on the browser used, the HTML flow can get mucked-up.

    This is fixable by adding the following tag between tables:

    <BR CLEAR="LEFT">
    Detailed explanation at http://www.cs.tut.fi/~jkorpela/HTML3.2/tablealign.html.

         "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

Re: Perl/Html Question - rows are not aligned between different columns
by Anonymous Monk on Nov 03, 2007 at 03:48 UTC
    Thanks everyone for your suggestions. I finally got it fixed using a combination of fonts, cell paddings, and cell spacings between table rows. My next question is as I dynamically generate a new table rows and columns based on user's input, how do I keep track of their values using some dynamically generated variables as well? For example:
    while ($i < $run) { $i++; print qq{<td rowspan="$rowsp"><table border="1"><col width="165"> +<tr><td><br></td></tr>}; my $j = 0; while ($j <= $group) { $j++; print "<tr><td><br></td></tr>"; print "<tr><td><br></td></tr>"; print '<tr align="center"><td><input type="text" name="test1" + size="15"></td></tr><tr align="center"><td><input type="text" name=" +mem1" size="15"></td></tr><tr align="center"><td><input type="text" n +ame="mem2" size="15"></td></tr>'; } print "</table></td>"; }
    name=test1 above will be generated many times but it needs to have a different variable name everytime to store a different value associate with it. Any thought? Thanks.
      Why is it that people are willing to learn how to actually do the task at hand when it has to do with physical things (driving, power tools, etc), but have this INSANE notion that they can just sit down at a computer and whip out the next Facebook in a weekend?!

      Here is what you need to do, in this order:

      1. Stop working on your project. Now.
      2. Go out and buy a copy of Learning Perl.
      3. Read said copy of Learning Perl
  • Come back to your project and throw it all away.
  • Start again, this time actually thinking through what you're trying to do.

    I'm not "being mean." I'm trying to teach you how to fish.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
        Um, Learning Perl explicitly assumes that you know how to program and so doesn't try very hard to teach basic programming practice. At least that was the case with earlier editions.

        I'd suggest something aimed at beginning programmers like Beginning Perl. At least it is available for free, and it includes a chapter on how to write CGI programs. (Using CGI.pm's methods rather than a template system, but it is still likely to give some helpful ideas.)

        Of course if you wanted to be nasty, then you could recommend starting with Structure and Interpretation of Computer Programs. (For those who don't know it, this is an excellent book. It is available online but I recommend buying a copy, reading it, and re-reading it every few years. I'm getting due to re-read it again. That said, it is pitched at a fairly high level, and for most people will push them to completely rethink how they think about programming.)

        The book that I really wish I could get lots of people to read is Code Complete 2. Of course they never will since it is a big fat book with tons of important detail. But all of that detail is valuable knowledge that programmers really should know on some level. (Preferably you want it integrated into their bones so they just do it naturally. Hey, if I'm going to dream...)

      Learn to use different quoting styles and then you can easily interpolate in variables and have quotation marks.
      my $foo = "bar"; print qq{"$foo"}; # prints "bar" with the quotes
      and now you can replace things like test1 with variables and have your names be dynamic.

      BTW I'm going to second the previous suggestion to learn about the importance of dividing up content and presentation. While it is conceptually easy to just mix your code and gobs of HTML, the resulting code quickly becomes unmaintainable spaghetti.

      The easiest way to do that is to use a templating system. It is a little old, but this survey is still a decent introduction to the basic kinds of templating systems out there, and the ones that it mentions are still readily available. (Personally I like Template Toolkit.)