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

I appologize for my ignorance, but I'm still new at this! I'm trying to write a multiple form survey but am running into 2 problem with my code. I most like have some wrong ideas about how certain things work. For any clarification I'll be most thankfull. Problem 1.) The script proceeds to the 2nd form without me completeing the 1st. Problem 2.) The 2nd form is upended at the bottom of the 1st, not in its own window.
#!/usr/bin/perl for ( $i=1 ; $i<=2 ; $i++ ) {#loop over # of forms &display_file ($i); %box = &read_query_string; # Read keys and values open(OFILE,">> temp.dat") || die "can't open output file:\n$!"; print OFILE "$box{'age'} \n"; close OFILE; }; sub read_query_string { local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value;} %FORM; }; sub display_file { ($nummer) = @_; open (FILE, "< ../FPR/$nummer.htm" ) || die "can't read input file +:\n$!"; print "Content-type: text/html", "\n\n"; while (<FILE>) {print;} close (FILE); };

Replies are listed 'Best First'.
Re: Multiple form survey
by matthewb (Curate) on Nov 09, 2003 at 20:27 UTC
    I appologize for my ignorance, but I'm still new at this!
    If you are asking for help, you are not ignorant. You appear to be attempting to write a multi-form CGI application based upon a bunch of predetermined templates.

    The difference between you and the people who are really good at this is that they know what not to do!

    The parsing of HTTP query strings in your own code is considered a no-no in professional circles since it is handled by the CGI module, which comes as standard in your Perl installation. Look up the details for the param function and you can do away with your read_query_string() function altogether.

    While it is difficult to give concrete advice on the architecture of your whole application, I can heartily recommend CGI::Application as being an excellent way to generalise its different stages into functions.

    You are also well-advised to consider some kind of templating solution for organising the HTML pages you have prepared. I have had a great deal of success with Template Toolkit but a number of other solutions exist.

    Your script shows all three forms at the same time because the first two lines tell it to do so - you need some stuff in between them to stop this happening ;) You need to do a little bit of reading through some examples, I reckon, but what you are doing - trying to get something working by trial and error - is definitely a step in the right direction and you have found the right place to ask more specific questions.

    MB
Re: Multiple form survey
by jonadab (Parson) on Nov 10, 2003 at 01:34 UTC
    1.) The script proceeds to the 2nd form without me completeing the 1st. Problem 2.) The 2nd form is upended at the bottom of the 1st, not in its own window.

    Sounds to me like you're operating under the assumption that your script will run once. CGI doesn't work that way. Your script will run each time the user loads the page, whether they do it by hitting reload, by clicking submit, or whatever. Each time it runs, it should only print the one page that is wanted under the circumstances. For example, if the user hasn't submitted any form yet, you want to print the blank first form. If they are just now sumbitting the first form, you want to print the second one (assuming that their answers to the first are okay). If they're submitting the second form, you want to print some kind of confirmation. So you want to do something along these lines...

    %input = getforminput(); # That's another thread... if ($input{formsubmitted}==2) { # user submitted form2. Process it and print a # "form sumbitted" advisory page. } elsif ($input{formsubmitted==1) { # user submitted form1. Process it and print form2. } else { # User didn't submit anything yet. Print form1. }

    This is just a basic structure. You may alter it an any number of ways. For example, you may wish to validate the forms the user has submitted and make the user correct any mistakes, only giving them the next form (or results) if they've given satisfactory answers to all required fields. Also note that the formsubmitted input is not magic; your form has to supply it. One way to do it is to put hidden fields in your forms, for example:

    <input type="hidden" name="formsubmitted" value="2"></input>

    $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/
Re: Multiple form survey
by pg (Canon) on Nov 09, 2003 at 19:40 UTC

    Your question is a little bit vague, but I do have a suggestion. You don't need to parse the query yourself, try to use HTTP::Daemon, and do something like:

    my $d = HTTP::Daemon->new(LocalAddr => "localhost", LocalPort => 80, Listen => 20) || die; my $c = $d->accept my $r = $c->get_request; if ($r) { my %query = $r->uri->query_form(); #.... }

    The query would be parsed and stored in %query. Also the "+" sign has been taken care of.

    BTW, the query string is not always delimited by "&", a different style uses ";", if you do it by yourself, you have to take this into consideration.

      What leads you to believe the supplicant lacks a web server?