Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: Yet Another Stupid CGI Question

by chaoticset (Chaplain)
on Oct 19, 2001 at 09:19 UTC ( [id://119884]=note: print w/replies, xml ) Need Help??


in reply to Yet Another Stupid CGI Question

Sorry - I should have been more specific about what I'm doing. This should address the questions.

When the user first clicks on the page, it will dump a text box in front of them, saying 'Enter the first few letters.' Based on that, the program will load and weed out all the entries in the 1000+ array that have those first few letters. Then, it returns a page with the text box at the top(so they know what they typed in) and *just* the matching entries.

Based on the distribution of beginning letters, I'd say they'd never get a return page with more than 100 entries on it. (At most, maybe 200.) I realize those are stretching, but I honestly don't think they'd happen often. (If they did during testing, I could build a page-breaker and make it return two pages.)

Now, I realize all this is *way* too much to ask for. I'm not asking for it. All I'd like is a little advice on how to handle turning this data into a web page.

It's going to be:

name=cost=number

And it will come out in a table with a few other things: (chk = checkbox, txt = textfield)

--------------------------------
|chk|name|cost|number|txt|
--------------------------------

Now, as I understand Perl, it doesn't interpolate while or for loops. So if I make the statement

print table(...
...
foreach ... {
...
...
}
...
)

then my code won't work, because the for hasn't been dealt with before the print tries to print.

Am I wrong? Are these things dealt with automagically, and Perl is just all the more amazing? I'm thinking it's not. Does this mean I have to do the table tags by hand?

Replies are listed 'Best First'.
Re: Re: Yet Another Stupid CGI Question
by davorg (Chancellor) on Oct 19, 2001 at 13:30 UTC

    A couple of things that might make your life a bit easier:

    1. The map function can often be used as an "inline foreach".
    2. In CGI.pm, the Tr and td functions (amongst others) have a neat feature whereby if you pass them a reference to an array, then they return a <tr> or <td> tag for each element in the array.

    I don't know what your data structure looks like, but this sample code might help:

    my @list = ('chk1|name1|cost1|number1|txt1', 'chk2|name2|cost2|number2|txt2', 'chk3|name3|cost3|number3|txt3'); print table(Tr([map { td([split /\|/, $_])."\n" } @list ]));
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you don't talk about Perl club."

Re: Re: Yet Another Stupid CGI Question
by George_Sherston (Vicar) on Oct 19, 2001 at 11:59 UTC
    My £/50 is to second the monk who said HTML::Template. In fact I don't think it's terribly difficult to learn, certainly not to get it to do what you want. You'd make a template file, say you call it results.tmpl which wd look something like:
    <table bgcolor=#66aaff border=2 bordercolor=#ffffff cellspacing=0 cell +padding=6> <TMPL_LOOP RESULTS> <tr> <td> <TMPL_VAR CHK> </td> <td> <TMPL_VAR NAME> </td> <td> <TMPL_VAR COST> </td> <td> <TMPL_VAR NUMBER> </td> <td> <TMPL_VAR TXT> </td> </tr> </TMPL_LOOP> </table>
    (I like writing my TMPLs in upper case and my HTML in lower case to tell them apart visually - no other reason).

    Then in your perl you need a bit that looks like this
    #!/usr/bin/perl -w use strict; use CGI qw(:standard); use HTML::Template; # my guess about what your data structure might be: my %information = ( txt_foo => ['chk_foo','name_foo','cost_foo','number_foo'], txt_bar => ['chk_bar','name_bar','cost_bar','number_bar'], txt_baz => ['chk_baz','name_baz','cost_baz','number_baz'], ); # initialise the template and other vars: my $results_tmpl = HTML::Template->new(filename => 'results.tmpl'); my @results; # populate @results with the data from %information: for (keys %information) { my %row_data; $row_data{'txt'} = $_; $row_data{'chk'} = $information{$_}[0]; $row_data{'name'} = $information{$_}[1]; $row_data{'cost'} = $information{$_}[2]; $row_data{'number'} = $information{$_}[3]; push @results, \%row_data; } # drop the info into the template: $results_tmpl->param(results => \@results); # print the page: print header, start_html, $results_tmpl->output(), end_html;
    Simple, really. The marginally tricky bit is getting the data into the right form to go into the template. The single line $results_tmpl->param(results => \@results); is doing duty for a lot of lines like
    $results_tmpl->param( results => ( txt => 'txt_foo', chk => 'chk_foo', ......
    But obviously if you had to write it all out by hand, you might as well not be using the template at all. What I'm saying is that the code for populating the template will work, but it may take a bit of effort to get your head around it (it did mine). But you said you wanted to get it on your hands...

    The only other problem I can foresee is that for some reason HTML::Template doesn't seem to be part of the standard issue. If you're using an ISP that doesn't offer it, you may want to refer to these threads.

    update :Reflectingthat this is a problem I quite often come up against, and for which I wd like a simple solution, I had a sudden rush of blood to the head and wrote a module that makes it easier to do printing out lists of info in CGI, so now there's yet One More Way To Do It. Now you can do this, which I think you'll agree has a certain classical simplicity:
    #!/usr/bin/perl -w use strict; module library use CGI qw(:standard); use CGI::tab; my %information = ( txt_foo => ['chk_foo','name_foo','cost_foo','number_foo'], txt_bar => ['chk_bar','name_bar','cost_bar','number_bar'], txt_baz => ['chk_baz','name_baz','cost_baz','number_baz'], ); print header, start_html, start_tabs(75,150,225,300); for my $key (keys %information) { print $key,t; print $_,t for @{ $information{$key} }; } print end_tabs, end_html;


    § George Sherston
Re: Re: Yet Another Stupid CGI Question
by shotgunefx (Parson) on Oct 19, 2001 at 14:21 UTC
    There's a bunch of ways to do this. Here's two.
    # One Way my $table_dat = undef; foreach my $ell (@elements){ $table_dat.=Tr(td(b("Label")),td($ell)); # Whatever you need to ou +tput. } print table($table_dat); # Second way use CGI qw/:standard *table/; # Import start_table and end_table print start_table # Data processing here to spit out rows and cells... foreach my $ell (@elements){ print Tr(td(b("Label")),td($ell)); } print end_table


    -Lee

    "To be civilized is to deny one's nature."

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://119884]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2024-03-28 20:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found