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

I'm trying to learn how to use CGI.pm, HTML::Template (and will be using DBI and DBD::Sybase). Right now, I'm trying to figure out why the following won't launch a new program (nc1_rpt1_summary.pl) when the Submit button is clicked. Both .pl files render the HTML from the templates individually, but I can't seem to pass the $CGI variables. I've pared this down some, and there is a LOT that is still hard-coded for now. I looked at jeffa's HTML::Template tutorial and inserted the stuff about 'associate' but the CGI params rept_id, rpt_asofdt and proj_id still aren't being passed. If I put "method=get" in the form, it shows in the URL that I actually have those params and they are populated with the values I expect.

My goal is to present the user with a main menu. That main menu has a few objects that help limit the query to the database, plus helps determine which report is run. Once the initial summary report is run (whether Report 1 Summary, Report 2 Summary, etc.), the user should be able to click on any data cell in the Summary report and drilldown to further details. (And then from the interim drilldown, they want to drilldown to journal line detail).

My question at the moment is: How can I get it to recognize that I've selected Report 1 (rept_id=1), so it knows to launch nc1_rpt1_summary.pl (eventually, I'd like the thing to replace the rept_id digit in the .pl automagically so it launches the right report, but that's another hair-pulling day down the road).

Here's what I have:

Initial program being launched from URL

#!/usr/local/bin/perl5_8 #Start program for Campus Financial Reports use strict; use CGI; use CGI::Carp qw(fatalsToBrowser); #remove for PRD else security hole use HTML::Template; my $CGI = CGI->new; # Clear the buffers & print the html headers to avoid problems $|=1; print "content-type: text/html\n\n"; my $template = HTML::Template->new( filename => 'nc1_mainmenu.tmpl', associate => $CGI, ); print $template->output(); print "<p>"; print "Good-bye Cruel World<br>\n";
nc1_mainmenu.tmpl being called by initial program above
<TMPL_INCLUDE NAME='nc1_start.tmpl'> <TMPL_INCLUDE NAME='nc1_style.tmpl'> <TMPL_INCLUDE NAME='nc1_titlebarmain.tmpl'> <body> <form name=frm_mainmenu> <table border=0 width="100%" summary="Welcome Paragraph"> <tr><td class=welc><br>Welcome!<br><br></td></tr> </table> <table border="0" width="100%" summary="Input Form"> <tr> <td class=welc width="10%" rowspan="7" valign="top">Step 1:</td> <td class=welc width="20%" rowspan="7" valign="top">Select a Report</t +d> <td class=welc width="70%" id="rpt1form"> <input type="RADIO" name="rept_id" value="1" onclick="highlight();" C +HECKED> <span style="cursor:pointer;cursor:hand" onmouseover="style.color='#BF0000';window.status='Report Descr +iptions';" onmouseout="style.color='black';window.status='';" onclick='window.open("../../campus/nc_pf_rpt_descrs.html#Rpt1D +escr", "myWindow", "width=650,height=600,top=10,left=10,scrol +lbars=yes");'> &nbsp;&nbsp;Report 1 - Fiscal Year-to-Date Financial Informati +on </span></td> <tr> <td class=welc id="rpt2form"> <input type="RADIO" name="rept_id" value="2" onclick='highlight();'> <span style="cursor:pointer;cursor:hand" onmouseover="style.color='#BF0000';" onmouseout="style.color='black';" onclick='window.open("../../campus/nc_pf_rpt_descrs.html#Rpt2D +escr", "myWindow", "width=650,height=600,top=10,left=10,scrol +lbars=yes");'> &nbsp;&nbsp;Report 2 - Quarter/Project-to-Date Financial Statu +s </span></td> <!-- a bunch of code here for remaining reports removed for this examp +le --> <tr> <td class=welc width="10%">Step 2:</td> <td class=welc width="20%">Select a Period</td> <td class=welc width="70%"><select name="rpt_asofdt"> <option value="Project To Date">Project To Date <option value="Month Ending OCT 2003">Month Ending OCT 2003 <option value="Month Ending SEP 2003">Month Ending SEP 2003 <option value="Month Ending AUG 2003">Month Ending AUG 2003 <option value="Month Ending JUL 2003">Month Ending JUL 2003 <option value="Month Ending JUN 2003">Month Ending JUN 2003 <option value="Month Ending MAY 2003">Month Ending MAY 2003 <option value="Month Ending APR 2003">Month Ending APR 2003 <option value="Month Ending MAR 2003">Month Ending MAR 2003 <option value="Month Ending FEB 2003">Month Ending FEB 2003 <option value="Month Ending JAN 2003">Month Ending JAN 2003 <option value="Month Ending DEC 2002">Month Ending DEC 2002 <option value="Month Ending NOV 2002">Month Ending NOV 2002 <option value="Month Ending OCT 2002">Month Ending OCT 2002 </SELECT></td> </tr> <tr><td class=welc>&nbsp;</td></tr> <tr> <td class=welc width="10%">Step 3:</td> <td class=welc width="20%">Enter a Project ID</td> <td class=welc width="70%" colspan="2"><input name="proj_id" size="14" +></td> </tr> <tr><td class=welc>&nbsp;</td></tr> <tr> <td class=welc width="10%">Step 4:</td> <td class=welc width="20%">Submit the Report</td> <td class=welc width="70%" colspan="2"><input type="SUBMIT" name="submit_rpt" value="SUBMIT" style="cursor:pointer;c +ursor:hand;" onclick='window.locatio +n="nc1_rpt1_summary.pl"'></td> </tr> <tr><td class=welc>&nbsp;</td></tr> </table> </form> <TMPL_INCLUDE "nc1_end.tmpl">
The nc1_rpt1_summary.pl that's supposed to be called when the user clicks on Submit (right now hard-coded for Report 1).
#!/usr/local/bin/perl5_8 #Start program for Report 1 Summary use strict; use CGI; use CGI::Carp qw(fatalsToBrowser); #remove for PRD else security hole use HTML::Template; # Clear the buffers & print the html headers to avoid problems $|=1; print "content-type: text/html\n\n"; my $CGI = CGI->new; #not sure I need this here but I've tried it wit +h and without &get_parms; #go get the $CGI parameters my $template = HTML::Template->new( filename => 'nc1_rpt1_summary.tmpl +', associate => $CGI, ); #futzed params to pass to nc_rpt1_summary.tmpl $template->param(hdr_title=>"Report 1 - Summary"); $template->param(hdr_descr=>"Fiscal YTD Financial Information"); $template->param(hdr_asofdate=>"As of June 30, 2003"); $template->param(hdr_project=>"Project/Proj Ref: 533694-033694"); $template->param(attr_dept=>"183901"); $template->param(attr_descr=>"Nonwovens Center"); $template->param(attr_award=>"Placeholder"); $template->param(attr_prog=>"110"); $template->param(attr_projpd=>"09-01-1991 to 12-31-2099"); $template->param(attr_budgpd=>"09-01-1991 to 12-31-2099"); $template->param(attr_fund=>"91000"); $template->param(attr_fyr=>"2003"); $template->param(attr_rate=>"Placeholder"); $template->param(attr_sub=>"563"); $template->param(attr_stat=>"Active"); $template->param(attr_spec=>"Placeholder"); $template->param(attr_equip=>"Placeholder"); $template->param(attr_resp=>"Various Industries"); $template->param(attr_pi=>"Placeholder"); #more futzed params to pass to nc_rpt1_summary.tmpl for main body data +/dollars $template->param(rpt_data => [{ acct=>'11100', descr=>'Cash', cfte=>'-&nbsp;&nbsp;&nbsp;', cbud=>'0.00', cmo=>'11,845.51', fytd=>'57,788.43', pre=>'0.00', enc=>'0.00', bba=>'(57,788.43)', ffte=>'-&nbsp;&nbsp;&nbsp;', fbud=>'0.00', bgcol=>'#FFFFFF'}, { acct=>'10000-19999', descr=>'Total Assets', cfte=>'-&nbsp;&nbsp;&nbsp;', cbud=>'$0.00', cmo=>'($2,367.49)', fytd=>'$430.27', pre=>'$0.00', enc=>'$0.00', bba=>'($430.27)', ffte=>'-&nbsp;&nbsp;&nbsp;', fbud=>'$0.00', bgcol=>'#D3D3D3'}, { acct=>'&nbsp;', descr=>'&nbsp;', cfte=>'&nbsp;', cbud=>'&nbsp;', cmo=>'&nbsp;', fytd=>'&nbsp;', pre=>'&nbsp;', enc=>'&nbsp;', bba=>'&nbsp;', ffte=>'&nbsp;', fbud=>'&nbsp;', bgcol=>'#99CC99'}, ] ); print $template->output(); print "<p>"; print "Good-bye Cruel World<br>\n"; sub get_parms { my ($CGI) = @_; my @parameters_to_find = qw( rept_id proj_id rpt_asofdt ); my %parameters; foreach my $parm ( @parameters_to_find ) { my $val = $CGI->param($parm); $parameters{$parm} = $val; } return %parameters; }
And finally, the template nc1_rpt1_summary.tmpl:
<TMPL_INCLUDE "nc1_start.tmpl"> <TMPL_INCLUDE "nc1_style.tmpl"> <TMPL_INCLUDE "nc1_titlebarrpt.tmpl"> <TMPL_INCLUDE "nc1_header.tmpl"> <form name=frm_summ_rept method=POST action="http://www.ncsu.edu"> <table border=1 cellspacing=0 cellpadding=1 width="100%" summary="Colu +mn Headings and Data Cells"> <tr valign="bottom"> <th width="9%">Account Summary</th> <th width="18%">Description</th> <th width="4%">Current FTE</th> <th width="9%">Current Budget</th> <th width="9%">Current Month Activity</th> <th width="9%">FYTD Activity</th> <th width="9%">Pre-Encumbrances</th> <th width="9%">Encumbrances</th> <th width="11%">Budget Balance Available</th> <th width="4%">Future FTE</th> <th width="9%">Future Budget</th> </tr> <TMPL_LOOP NAME=rpt_data> <tr bgcolor=<TMPL_VAR NAME=bgcol>> <td class=rowhdr><TMPL_VAR NAME=acct></td> <td class=rowhdr style="cursor:pointer;cursor:hand;" title="Account 11100" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='<TMPL_VAR NAME=b +gcol>';" onclick="frm_summ_rept.drill_detail.value='REF +'; frm_summ_rept.submit();"><font color= +"#000000"><TMPL_VAR NAME=descr></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Current FTE Period Drilldo +wn" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='<TMPL_VAR NAME=b +gcol>';" onclick="frm_summ_rept.drill_detail.value='REF +'; frm_summ_rept.submit();"><font color= +"#000000"><TMPL_VAR NAME=cfte></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Current Budget Period Dril +ldown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='<TMPL_VAR NAME=b +gcol>';" onclick="frm_summ_rept.drill_detail.value='REF +'; frm_summ_rept.submit();"><font color= +"#000000"><TMPL_VAR NAME=cbud></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Current Month Activity Per +iod Drilldown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='<TMPL_VAR NAME=b +gcol>';" onclick="frm_summ_rept.drill_detail.value='REF +'; frm_summ_rept.submit();"><font color= +"#000000"><TMPL_VAR NAME=cmo></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see FYTD Activity Period Drill +down" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='<TMPL_VAR NAME=b +gcol>';" onclick="frm_summ_rept.drill_detail.value='REF +'; frm_summ_rept.submit();"><font color= +"#000000"><TMPL_VAR NAME=fytd></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Pre-Encumbrances Period Dr +illdown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='<TMPL_VAR NAME=b +gcol>';" onclick="frm_summ_rept.drill_detail.value='REF +'; frm_summ_rept.submit();"><font color= +"#000000"><TMPL_VAR NAME=pre></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Encumbrances Period Drilld +own" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='<TMPL_VAR NAME=b +gcol>';" onclick="frm_summ_rept.drill_detail.value='REF +'; frm_summ_rept.submit();"><font color= +"#000000"><TMPL_VAR NAME=enc></td> <td class=rowdat><font color="#000000"><TMPL_VAR NAME=bba></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Future FTE Period Drilldow +n" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='<TMPL_VAR NAME=b +gcol>';" onclick="frm_summ_rept.drill_detail.value='REF +'; frm_summ_rept.submit();"><font color= +"#000000"><TMPL_VAR NAME=ffte></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Future Budget Period Drill +down" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='<TMPL_VAR NAME=b +gcol>';" onclick="frm_summ_rept.drill_detail.value='REF +'; frm_summ_rept.submit();"><font color= +"#000000"><TMPL_VAR NAME=fbud></td> </tr> </TMPL_LOOP> <tr bgcolor="#CCCCFF"> <td>should look like:</td> </tr> <tr bgcolor="#FFFFFF"> <td class=rowhdr>&nbsp;11100</td> <td class=rowhdr style="cursor:pointer;cursor:hand;" title="Account 11100" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='#FFFFFF';" onclick="frm_summ_rept.drill_detail.value='REF'; frm_summ_rept.submit();">&nbsp;Cash</td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Cash Period Drilldown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='#FFFFFF';" onclick="frm_summ_rept.drill_detail.value='REF'; frm_summ_rept.submit();"><font color="#00 +0000">-&nbsp;&nbsp;&nbsp;</font></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Cash Period Drilldown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='#FFFFFF';" onclick="frm_summ_rept.drill_detail.value='REF'; frm_summ_rept.submit();"><font color="#00 +0000">0.00</font></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Cash Period Drilldown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='#FFFFFF';" onclick="frm_summ_rept.drill_detail.value='REF'; frm_summ_rept.submit();"><font color="#00 +0000">11,845.51</font></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Cash Period Drilldown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='#FFFFFF';" onclick="frm_summ_rept.drill_detail.value='REF'; frm_summ_rept.submit();"><font color="#00 +0000">57,788.43</font></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Cash Period Drilldown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='#FFFFFF';" onclick="frm_summ_rept.drill_detail.value='REF'; frm_summ_rept.submit();"><font color="#00 +0000">0.00</font></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Cash Period Drilldown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='#FFFFFF';" onclick="frm_summ_rept.drill_detail.value='REF'; frm_summ_rept.submit();"><font color="#00 +0000">0.00</font></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Cash Period Drilldown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='#FFFFFF';" onclick="frm_summ_rept.drill_detail.value='REF'; frm_summ_rept.submit();"><font color="#BF +0000">(57,788.43)</font></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Cash Period Drilldown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='#FFFFFF';" onclick="frm_summ_rept.drill_detail.value='REF'; frm_summ_rept.submit();"><font color="#00 +0000">-&nbsp;&nbsp;&nbsp;</font></td> <td class=rowdat style="cursor:pointer;cursor:hand;" title="Click to see Cash Period Drilldown" onmouseover="style.background='#CCCCFF';" onmouseout="style.background='#FFFFFF';" onclick="frm_summ_rept.drill_detail.value='REF'; frm_summ_rept.submit();"><font color="#00 +0000">0.00</font></td> </tr> </table> <TMPL_INCLUDE "nc1_footer.tmpl"> <TMPL_INCLUDE "nc1_end.tmpl">
I would appreciate any suggestions on how best to set this up. If you'd like to see all the gory details (all the templates, all the code, just let me know and I'll put it on my scratch pad). Thanks! P.S. I put "readmore" tags in here, but I can't tell if they're working when I preview this...

Lori

Replies are listed 'Best First'.
Re: HTML::Template, CGI, passing variables, launching new script
by freddo411 (Chaplain) on Nov 12, 2003 at 23:42 UTC
    Hi, welcome to the world of perl CGI.

    First off, your initial script doesn't need to use CGI. It just throws up a template, which is just a bunch of print statements mostly. Assuming your template is nicely formated HTML (it should be) you should not have the extra print statements at the end of your script:

    print "<p>"; print "Good-bye Cruel World<br>\n";

    Second, as the previous poster said, you have to make sure that your template has correct HTML in its form tag to point to your processing script. (I'm running with your idea to have seperate scripts, this is not a given, it can be all in one script...) A properly formated form tag might look like:

    <form name="form" method="post" action="process.cgi" >

    This script would grab your choice something like this:

    use CGI; use strict; my $CGI = CGI->new; # this assumes the creating HTML has a option list called # my_menu my $report_num = $CGI->param("my_menu"); # do some stuff to lookup the report based on $report_num ... # output print header; my $t = HTML::Template->new( filename => 'nc1_rpt1_summary.tmpl' ); $t->param( foo => 'FakeDomain.com', stuff => "blah", morestuff => "foobar", %hashofstufffromDB, ); print $t->output;
    That's the basic idea. There's a bit of work getting the details right (got to have the template var names match the key of the hash you pass into the HTML::Template object for example) you should do some sanity checking on the inputs, handle errors if things aren't as expected with the inputs and or the db access, etc.

    You might want to start with a very simple script and a very simple template and build from there.

    -------------------------------------
    Nothing is too wonderful to be true
    -- Michael Faraday

Re: HTML::Template, CGI, passing variables, launching new script
by mpeppler (Vicar) on Nov 12, 2003 at 22:31 UTC
    I think that this is an HTML problem. If you want the action of submitting the form to execute a particular script, then that action should be coded in the <FORM> tag. Otherwise you will just get the same script executed with the new parameters.

    Michael

Re: HTML::Template, CGI, passing variables, launching new script
by bradcathey (Prior) on Nov 13, 2003 at 13:03 UTC
    mpeppler nailed it. You must pass your variables from the HTML form to the Perl script using the conventional methods of coding this in the <form> tag:
    <form action="cgi-bin/nc1_rpt1_summary.pl" method="post">
    I know it's deceiving to see your values supposedly being passed in the URL, but it ain't happening. Your submit can simply be:
    <input type="SUBMIT" style="cursor:pointer;cursor:hand;">
    BTW, hang in there with HTML::Template, it's a powerful tool for building those dynamic pages.

    Good luck.

    —Brad
    "A little yeast leavens the whole dough."
      I was hoping the input type="SUBMIT" ... onclick stuff I had at the bottom of nc1_mainmenu.tmpl would allow me to pass the $CGI variables and launch the new .pl page. :-(

      So....

      I made the suggested changes, but I get the following error (which I've seen before but my previous code "seemed" to have eliminated it):

      Can't call method "param" on an undefined value at /local/www/htdocs/scripts/campus/nc1_rpt1_summary.pl line 97.

      Line 97 is about the fifth line up from the bottom of nc1_rpt1_summary.pl ({ my $val = $CGI->param($parm);). It seems to me I've declared my variables, but the program doesn't think so. The newly revised gory details are on my scratch pad since I didn't want to clutter up this post (after this is resolved, I'll post the answer so future super-searchers can find it).

      Is there a better way to do this? I have done some significant reading about recursive vs. iterative, and I think I'd like to go with the iterative variation of launching the new web pages (mostly because of how I'm planning to test this junk). I was trying to make this a small example of how to pass the $CGI variables (I've only got three that I'm trying to track), so I can learn how to use the CGI module along with HTML::Template (which I'm loving, by the way!). I've already got the DBI and DBD::Sybase code working in a separate tiny file.

      Thanks for any insights you can provide. If I can't (relatively) quickly resolve this particular issue, I'll backtrack and take freddo411's advice and using jeffa's example and build a tinier example from there. Thanks!

      Lori

        The error indicates that you are asking for a parameter name that doesn't exist.

        This is a good time/place to learn some basic debugging skills. Start with the line number given in the error. Then trace back to the cause of the problem. In your case you'll start with a var ($parm) that gets set in a loop, that comes from a hard coded array that has to match the text in the HTML. Fix one or the other.

        Other helpful advice: Limit the information in your posts. The long, long listing of the template doesn't really help. Don't include templates unless the problem directly relates to the template. Even if you had to ask for help with a template, don't show us all the HMTL blah,blah,blah. Make a simple version for posting/testing that include the absolute minimum needed stuff. Like this:

        <html> <body> <!-- my_var --> </html> </body>

        -------------------------------------
        Nothing is too wonderful to be true
        -- Michael Faraday