http://qs321.pair.com?node_id=10989

scratch has asked for the wisdom of the Perl Monks concerning the following question: (cgi programming)

Howdy,

I'm working on what's going to grow to be a decent sized (100+) script in which I want to carry all the vars from page to page. I'm using CGI.pm and hidden(), but right now I'm naming all the vars individually on each page.

Every sort of loop that I've tried to read through param() only carries the vars from page 1 to page 2, from page 2 to page 3, etc. It doesn't carry vars from page 1 to page 3.

Is there a better way to do this (make page 1 vars available on page 5, say) than the brute force method of naming them all, over and over on each page?

Here's the code I'm working with:

#!c:\perl\bin\perl.exe -w # Script: p9258.pl use CGI ':all'; use warnings; $action=param('action'); (%allvars); #foreach $name ( param() ) { # $value = param($name); # print "The value of $name is $value\n"; #} #each time we invoke this script we need to test #the value of $action so we know which page to #display next #execute the correct subroutine if ($action eq "Onto page 2") { sub_2(); } elsif ($action eq "Onto page 3") { sub_3(); }else { sub_1(); } #print the right page if ($action eq "Onto page 2") { print_form2(); } elsif ($action eq "Onto page 3") { print_form3(); } else { print_form1(); } #here we've got the subroutines that print the pages. #there's one for each page sub print_form1 { print header, start_html('p9258 Page 1 - Demographics'), h1('Demographic Information'); print start_form, "Please enter your ID: ", textfield(-name=>'ID', -maxlength=>10, ), p, p, "If you've answered the demographic questions on an earlier vi +st please", " press the 'Onto page 2' button at the bottom of this page.", p, p, hr, "Some demog info", p, p, strong("1. "), "What is your sex? ", radio_group(-name=>'sex', -values=>['1', '2'], -labels=>{'1'=> +'male', '2'=>'female'}), p(), strong("2. "), "What is your highest level of education? ", p, popup_menu(-name=>'education', -values=>['1', '2', '3', '4', ' +5', '6', '7'], -labels=>{'1'=>'Less than bachelors', '2'=>'Bachelors in SW', '3'=>'Bachelors in other field', '4'=>'Masters in SW', '5'=>'Masters in other field', '6'=>'PhD or Professional Doctorate', '7'=>'Other'}), p(), hidden(-name=>'sex'), hidden(-name=>'education'), submit(-name=>'action', -value=>'Onto page 2'), end_form; } sub print_form2 { print header, start_html('p9258 Page 2 - Household Member Information'), h1('Household Member Information'); #foreach $name ( param() ) { # $value = param($name); # print "The value of $name is $value\n"; #} foreach $key (keys %allvars) { print "For $key we have a value of $allvars{$key}\n"; } print start_form, "Please tell us who's living in the household:", p, p, strong("10. "), "Is the biological mother in the household now?", p, radio_group(-name=>'bioMom', -values=>['1', '2'], -labels=>{ +'1'=>'Yes', '2'=>'No'}), p(), # hidden(-name=>'ID'), # hidden(-name=>'sex'), # hidden(-name=>'education'), # hidden(-name=>'bioMom'), submit(-name=>'action', -value=>'Onto page 3'), end_form; } sub print_form3 { print header, start_html('Page 3'), h1('THIS IS PAGE 3'); foreach $key (keys %allvars) { print "For $key we have a value of $allvars{$key}\n"; } #foreach $name ( param() ) { # $value = param($name); # print "The value of $name is $value\n"; #} print start_form, "This is page 3: ", p(), submit(-name=>'action', -value=>'Submit completed form'), end_form; } #here we've got the subroutines that are run after #each page is submitted. sub sub_1 { } sub sub_2 { foreach $name ( param() ) { $value=param($name); $allvars{$name} = $value; } # foreach $name ( param() ) { # hidden(-name=>$name); # } } sub sub_3 { # foreach $name ( param() ) { # hidden(-name=>$name); # } foreach $name ( param() ) { $value=param($name); $allvars{$name} = $value; } }

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: carrying a lot of vars from page to page with hidden()
by infoninja (Friar) on May 11, 2000 at 01:07 UTC
    AFAIK, there are really only two ways to accomplish this task:
    • Carry the hidden variables through on each page (what you're currently trying to avoid)
    • Implement some other method of preserving state (i.e., cookies, etc)
    This is due to the fact that the web browser/server connection is stateless, so you have to do one of the above in order to preserve the state of the variables.
Re: carrying a lot of vars from page to page with hidden()
by merlyn (Sage) on May 11, 2000 at 01:16 UTC
Re: carrying a lot of vars from page to page with hidden()
by chromatic (Archbishop) on May 11, 2000 at 01:11 UTC
    Another option is to maintain the state via some method on the server, and only pass a session ID to and from the client. You could use a hash key (and implement some caching mechanism so that they expire after so many minutes) to an internal memory structure (if you use a persistent CGI application), or a unique ID into a database table or a temporary file.

    You could store this session ID in a cookie or as a hidden field.

Re: carrying a lot of vars from page to page with hidden()
by ducky (Scribe) on Sep 20, 2001 at 10:23 UTC

    I would use Apache::Session (which doesn't really need Apache) and pretty much follow the example in the docs. The constraint is that it'll be stuffed into a hash. But do what you wish to the hash... when the next process picks up the session you'll have your data back for that session id.

    -Ducky

Re: carrying a lot of vars from page to page with hidden()
by mezhaka (Initiate) on Oct 28, 2005 at 10:31 UTC
Re: carrying a lot of vars from page to page with hidden()
by solri (Initiate) on Feb 01, 2003 at 01:31 UTC
    A question that might be related. If I run a CGI program using a subroutine for each page, normally variables from one subroutine/page will not be available to the other subroutines, which is the way Perl works, of course. However, if I access these variables by using something like print somesubroutine($variable) it doesn't play nice with CGI.pm - instead of returning post data, pages after the second just print the submit button again. (current state of the program is lists.bilkent.edu.tr/~robin/cgibin/tester.cgi.)

    Originally posted as a Categorized Answer.

      This is not really the way perl works as such, but more along the lines of the stateless nature of HTTP.

      There are numerous ways to maintain state that include:

      1. Tied hash
      2. A database
      3. regular old file
      4. hidden fields in the page...
      In fact any method of retrieving the data can be used. The interesting part of maintaining state come along when you want to retrieve the data associated with a particular "session". You have to work out a method of branding the browser, then retrieving that branding and associating it with the data you've stored server side.

      There are three main methods of branding a browser, cookies, in the URL and using hidden variables in your pages...

      I wont go into detail, however, there is a wealth of information available all over the web, and here on perl monks.

Re: carrying a lot of vars from page to page with hidden()
by Anonymous Monk on Aug 08, 2001 at 02:50 UTC
    working with cgi.pm i`ve got exactly the opposite as my problem, i.e. i can`t get rid of the "sticky" hidden values creating the distinct page from the same pl script and using the same names for the hidden fields... use cgi; my $q=new cgi; sub page1{ print $q->textfield(-name=>'bla'); } sub page2{ print $q->hidden(-name=>'bla',-value=>'what ever i put will come out as value from form'); } etc... how can i get round this? oh, tried use cgi (-nosticky); as described by lincoln stein... too dumb tim looking for someone smart with a big heart?

    Originally posted as a Categorized Answer.

Re: carrying a lot of vars from page to page with hidden()
by crazyinsomniac (Prior) on Feb 02, 2003 at 09:52 UTC

    Re: carrying a lot of vars from page to page with hidden()

    Originally posted as a Categorized Answer.