Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Multiple forms in one CGI file?

by lakeTrout (Scribe)
on Jan 30, 2007 at 06:39 UTC ( [id://597286]=perlquestion: print w/replies, xml ) Need Help??

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

Hello PMs,

I return for more quidance. I want to build a quick form to upload a file (and back up the file that was there before) and then go on to another form. Can I do this in one file? I just have the feeling I'm going down the wrong road. I will note that addind PMs or Mods is quite a process (I don't have control/access), so if you have a bare bones solution other than mine, I'm all keys. It will be ID/pass protected, but I'm all set there (didn't include it as it's not part of my question)

Here is what I have so far (psedo-ish) and I noted where I want the next from to be built, but I'm starting to get errors and feel the logic might be shaky. Thanks all!


-lT
#!/usr/bin/perl -w use CGI; use CGI::Carp qw(fatalsToBrowser); $upload_dir = "/foo/bar/upload"; $query = new CGI; $filename = $query->param("somexmlfile"); #pass_word = $query->param("password"); will add later $filename =~ s/.*[\/\\](.*)/$1/; $upload_filehandle = $query->upload("somexmlfile"); #cp here, probably will be mv exec "cp ../foo/bar/existing.xml existing.xml.BAK"; open UPLOADFILE, ">$upload_dir/$filename"; binmode UPLOADFILE; while(<$upload_filehandle>){ print UPLOADFILE; } close UPLOADFILE; print $query->header ( ); print <<END_HTML <html> <h2>File Received</h2> ###################################### #Can I build another HTML/CGI from from here? ###################################### </html> END_HTML
Update: When I say build another CGI, what I am eventually doing is operations on the uploaded file based on a few simple inputs from the second form. Hope that will clarify things some.

Replies are listed 'Best First'.
Re: Multiple forms in one CGI file?
by davorg (Chancellor) on Jan 30, 2007 at 09:29 UTC

    A CGI program accepts inputs from the browser, processes them in some way and then produces an output (which is usually an HTML page to be displayed by the browser).

    There is no reason why the HTML produced by the CGI program can't include another form which will then call another CGI program (or even the same CGI program again).

    If you're calling the same CGI program to handle different stages of a process, then you need to give it some way to distinguish which stage each call needs to process. The easiest way to do this is to have a hidden input (I usually call it 'mode') on the form.

    I often find myself writing CGI programs that look a bit like this:

    #!/usr/bin/perl use strict; use warnings; use CGI ':cgi'; use Template; # for producing output. # List of subroutines that handle the different modes my %modes = ( mode1 => \&process_mode1, mode2 => \&process_mode2, default => \&process_default, ); # Work out which mode we're in my $mode = param('mode'); # If we have a mode, then call that subroutine if ($mode && %modes{$mode}) { $modes{mode}->(); } else { # Otherwise call the default handler $modes{default}->(); } sub process_default { # no mode give, display the default form } sub process_mode1 { # process mode1 and display the next form } sub process_mode2 { # process mode2 and display the next form }

    The output templates are either stored in external files, or in the DATA section using Inline::Files.

    Of course, these days, you're probably better off using a framework like Catalyst.

    Update: Fixed problems noted by blazar below.

      If you're calling the same CGI program to handle different stages of a process, then you need to give it some way to distinguish which stage each call needs to process. The easiest way to do this is to have a hidden input (I usually call it 'mode') on the form.

      I often find myself writing CGI programs that look a bit like this:

      ++. But as a piece of advice given to a newbie, even if your code is meant to be a minimal example, there are some obvious errors that may not be just as obvious to him/her, and that make it fail to even compile:

      # Work out which mode we're in my $mode = param('mode'); # If we have a mode, then call that subroutine if ($mode && %modes{mode}) { $modes->{mode}->(); } else { # Otherwise call the default handler $modes->{default}->(); }

      Of course it must be $mode in both places above instead of mode, and not %modes{...} but $modes{...}. (Well, unless in Perl 6!) Oh, and %mode is a hash, not a hashref, so there's a superfluous dereferencing arrow too. Incidentally I would avoid the whole hassle of a full fledged if... else with a more concise (and not less clear)

      $modes{ param('mode') || 'default' }->();

      (But then I'm sure you knew and just wanted to single out the various steps for instructive purposes and the benefit of the OP in this sense...)

      if you want something more lightweight and minimalistic than Catalyst, I'm rather fond of CGI::Application. and there're also a good dozen others floating around the CPAN that fill the same need.

      And both packages mentioned are pure-perl if i'm not mistaken, which means nothing to compile so you can install them even if you're limited to FTP access.

      __________
      The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.
      - Terry Pratchett

      Seconded. This is very handy for data entry with validation (you can simply re-output the form with values & error messages filled in) or for multi-page query results.

      just another cpan module author
Re: Multiple forms in one CGI file?
by jesuashok (Curate) on Jan 30, 2007 at 06:59 UTC
      Thanks jesuashok for the thread that better explains the script by anirudh_sml. I'll dig deeper in there for a possible solution. Thanks!
        It is always better to do a Super Search before posting a node.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (6)
As of 2024-04-18 15:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found