Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Creating a table using cgi.pm - a unique problem

by sara2005 (Scribe)
on Oct 28, 2005 at 21:50 UTC ( [id://503784] : perlquestion . print w/replies, xml ) Need Help??

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

Dear Monks I am having a unique problem creating a table using cgi.pm

Below is the part of the code that creates the table:- I create several columns in the table and my requirement is that a javascript should be triggered when I click on any column except the first one.

$cgi->Tr({ -align=>LEFT, -valign=>TOP}, [ td( { -OnClick=>"javascript:dothis()" }, [ $cgi->a( {-href=>"..", -target=>"_new"}, $cgi->img(..)), $cgi->a( {..}, $value1 ), $cgi->hidden( -name=>'name2', -value=>'$value2' ). $cgi->a( $value2), $cgi->hidden( -name=>'name3', -value=>'$value3' ). $cgi->a( $value2) ]), ]); which creates the html code as follows:- <tr valign="TOP" align="LEFT"> <td onclick="javascript:dothis()"> <a target="_new" href=".."><img src=.../></a></td> <td onclick="javascript:dothis()"> <a>VARIABLE</a></td> <td onclick="javascript:dothis()"> <input type="hidden" name=".."value=".."/><a>..</a></td> <td onclick="javascript:dothis()"> <input type="hidden" name=".."value=".."/><a>..</a></td> </tr>
Everything is fine except that I don't need "javascript:dothis()" in the first column. I am not able to get rid of that in the first column bcoz the format , td( { -OnClick=>"javascript:dothis()" }, ensures that the javascript is added to each and every column in the table row

Is there a way to overcome this problem or I should create the html tags manually rather than using cgi.pm? I would appreciate any help in this regard.

Replies are listed 'Best First'.
Re: Creating a table using cgi.pm - a unique problem
by Zed_Lopez (Chaplain) on Oct 28, 2005 at 23:00 UTC

    Y'know, it's really, really nice to post actually parsable example code.

    You could just seperate the first td call.

    # corrected original my ($value1, $value2, $value3) = (1..3); print $cgi->Tr({ -align=>'LEFT', -valign=>'TOP'}, [ td( { -OnClick=>"javascript:dothis()" }, [ $cgi->a( {-href=>"http://example.com", -target=>"_new"}, $cg +i->img('blah.gif')) . $cgi->a( {-href => 'http://example.com' }, $value1 ). +"\n", $cgi->hidden( -name=>'name2', -value=>"$value2" ). $cgi->a( {-href => 'http://example.com' }, $value2 ) . + "\n", $cgi->hidden( -name=>'name3', -value=>"$value3" ). $cgi->a( {-href => 'http://example.com' }, $value3 ) . + "\n", ]), ]); print "\n"; # td call separated print $cgi->Tr({ -align=>'LEFT', -valign=>'TOP'}, td($cgi->a( {-href=>"http://example.com", -target=>"_new"}, $cgi-> +img('blah.gif')) . $cgi->a( {-href => 'http://example.com' }, $value1 )) +. "\n" . td( { -OnClick=>"javascript:dothis()" }, [ $cgi->hidden( -name=>'name2', -value=>"$value2" ). $cgi->a( {-href => 'http://example.com' }, $value2 ) . + "\n", $cgi->hidden( -name=>'name3', -value=>"$value3" ). $cgi->a( {-href => 'http://example.com' }, $value3 ) . + "\n", ]), );

    But since this isn't obviously in a loop, you've got no reason to print your hidden fields within the table; that's just making the code messy. To make things a little saner, store things in advance in a list (for order) and a hash (for name-value association) and built it with a loop.

    my @names = (qw(name1 name2 name3)); my %cells = (name1 => {href => 'http://example.com/1', value => $value +1}, name2 => {href => 'http://example.com/2', value => $value +2}, name3 => {href => 'http://example.com/3', value => $value +3}); sub row { my ($names, $cells) = @_; my $first = shift @$names; my @result; push @result, CGI::td(CGI::a({-href=> $cells->{$first}{href}, -targe +t => "_new"}, CGI::img('blah.gif')) . CGI::a({-href=> $cells->{$first}{href}}, $cel +ls->{$first}{value})); for my $name (@$names) { push @result, CGI::td({ -OnClick=>"javascript:dothis()" }, CGI::hidden(-name => '$name', -value => $cel +ls->{$name}{value}) . CGI::a({-href => $cells->{$name}{href}}, $ce +lls->{$name}{value})); } return join '', @result; } print $cgi->Tr({ -align=>'LEFT', -valign=>'TOP'}, row(\@names, \%cells +));

    Then chuck that too and start using a template module.

      Definitely agree on the templating thing. There are several more powerful methods out there in CPAN, but what I tend to like using for it's power and flexibility when constructing custom frameworks is a combination of CGI::Simple and HTML::Template
Re: Creating a table using cgi.pm - a unique problem
by ph713 (Pilgrim) on Oct 28, 2005 at 22:37 UTC

    I haven't used cgi.pm in a long time, and I don't even remember using syntax like that (and come to think of it, the syntax as shown doesn't even make much sense in nesting terms, I think there's some typos in there), but I would have to guess that this sort of structural change would do it:

    $cgi->Tr({ -align=>LEFT, -valign=>TOP}, [ td( { }, [ $cgi->a( {-href=>"..", -target=>"_new"} ) . $cgi->img(..) ] ), td( { -OnClick=>"javascript:dothis()" }, [ $cgi->a( {..}, $value1 ), $cgi->hidden( -name=>'name2', -value=>'$value2' ). $cgi->a( $value2), $cgi->hidden( -name=>'name3', -value=>'$value3' ). $cgi->a( $value2) ]), ]);

    Basically, split that td clause into two seperate ones, one without the javascript attribute containing the first td, and one with it containing the other three.

Re: Creating a table using cgi.pm - a unique problem
by pg (Canon) on Oct 29, 2005 at 00:47 UTC

    What we see here is the distributive property of HTML shortcuts. if you don't want a tg be part of the dirtibution list, then just take it out:

    use CGI; my $cgi = CGI->new(); print $cgi->Tr( {-align=>LEFT, -valign=>TOP}, [ $cgi->td( [ $cgi->a({-href=>"..", -target=>"_new"}, $c +gi->img("blah.gif")), ] ) . $cgi->td( {-OnClick=>"javascript:dothis()" }, [ $cgi->a({}, "a"), $cgi->hidden(-name=>'name2', -value=>'b') +. $cgi->a("b"), $cgi->hidden(-name=>'name3', -value=>'c') +. $cgi->a("c") ] ) ] );

    This gives:

    <tr align="LEFT" valign="TOP"> <td><a target="_new" href=".."><img>blah.gif</img></a></td> <td onclick="javascript:dothis()"><a>a</a></td> <td onclick="javascript:dothis()"><input type="hidden" name="name2" va +lue="b" /><a>b</a></td> <td onclick="javascript:dothis()"><input type="hidden" name="name3" va +lue="c" /><a>c</a></td> </tr>

      Thanks PG

      You exactly got what my requirement is.. This is exactly what I wanted.

      You are the best..

Re: Creating a table using cgi.pm - a unique problem
by kwaping (Priest) on Oct 28, 2005 at 22:46 UTC
    I saw [id://ph713]'s reply as I finished typing mine. Basically the same thing, but I don't want to waste the time I spent figuring it out, so here it goes...
    $cgi->Tr({ -align=>'LEFT', -valign=>'TOP'}, td( [ $cgi->a( {-href=>"..", -target=>"_new"}, $cgi->img('asdf')) +, $cgi->a( $value1 ) ]), td( { -OnClick=>"javascript:dothis()" }, [ $cgi->hidden( -name=>'name2', -value=>'$value2' ). $cgi->a( $value2) ]), td( { -OnClick=>"javascript:dothis()" }, [ $cgi->hidden( -name=>'name3', -value=>'$value3' ). $cgi->a( $value2) ]), );

    Update: Fixed (hopefully) as per [id://pg]'s post.

      Your script does not produce one table row as the original script does/requires, as a matter of fact, it produces three rows:

      <tr align="LEFT" valign="TOP"> <td><a target="_new" href=".."><img>asdf</img></a></td> <td><a>A</a></td> </tr> <tr align="LEFT" valign="TOP"> <td onclick="javascript:dothis()"><input type="hidden" name="name2 +" value="b" /><a>b</a></td> </tr> <tr align="LEFT" valign="TOP"> <td onclick="javascript:dothis()"><input type="hidden" name="name3 +" value="c" /><a>c</a></td> </tr>