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

cgi: Grabbing Multiple input values

by new_2_perl (Acolyte)
on Jul 03, 2001 at 18:54 UTC ( [id://93526]=perlquestion: print w/replies, xml ) Need Help??

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

Hi guys, I've been looking around and I can't seem to find anything to answer question. I have a perl/cgi script that dynamically generates a web page. In the web page there a a multi selection list box. When the user submits the form my $input will only give me the last value from the list box they selected. What is the best way to grab each value that they selected from the list box? Thanks for your help

Replies are listed 'Best First'.
(Ovid) Re: cgi: Grabbing Multiple input values
by Ovid (Cardinal) on Jul 03, 2001 at 19:22 UTC

    new_2_perl wrote:

    When the user submits the form my $input will only give me the last value from the list box they selected.

    I see this all the time and it's invariably from someone who is using a broken "hand-rolled" alternative to CGI.pm. CGI.pm, if you ask for the form's value in scalar context, will return the first value for the form element in question. Alternatives to CGI.pm, however, often have code like the following:

    foreach $pair (@pairs){ ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%0D%0A/\n/g; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; }

    There are a variety of problems with this, but the line that usually causes problems like what you are experiencing is the $FORM{$name} = $value; line. This one will simply overwrite the last value of $FORM{$name} rather than adding a new value.

    See "use CGI or die;" for more complete information as to why using alternatives to CGI.pm are usually a poor idea.

    Cheers,
    Ovid

    Vote for paco!

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      Thanks guys. I'm using CGI.pm now and making it just return me an array of the values is very easy. Thanks again
Re: cgi: Grabbing Multiple input values
by bikeNomad (Priest) on Jul 03, 2001 at 18:58 UTC
    Assuming you're using the CGI module (and you should probably be; search here for why), you can get an array with the selected values. From the CGI manpage:

    FETCHING THE VALUE OR VALUES OF A SINGLE NAMED PARAMETER: @values = $query->param('foo'); -or- $value = $query->param('foo'); Pass the param() method a single argument to fetch the value of the na +med parameter. If the parameter is multivalued (e.g. from multiple selecti +ons in a scrolling list), you can ask to receive an array. Otherwise the meth +od will return a single value.

      Update, since this was the first in a search for "perl cgi param multiple values."

      Newer versions of CGI.pm will generate a warning if you use

      my @vals = $q->param('input');
      Better to use
      my @vals = $q->multi_param('input');

      From man CGI: "Warning - calling param() in list context can lead to vulnerabilities if you do not sanitise user input as it is possible to inject other param keys and values into your code. This is why the multi_param() method exists, to make it clear that a list is being returned, note that param() can still be called in list context and will return a list for back compatibility."

      And "If you call param() in list context with an argument a warning will be raised by CGI.pm, you can disable this warning by setting $CGI::LIST_CONTEXT_WARN to 0 or by using the multi_param() method instead"

Re: cgi: Grabbing Multiple input values
by andreychek (Parson) on Jul 03, 2001 at 19:04 UTC
    I think the problem may be with your naming scheme. As opposed to naming the select box something like "input", try naming it:
    input[]; For the full example: <form> <select NAME="input[]" SIZE=3 MULTIPLE> <option VALUE="opt1">option1 <option VALUE="opt2">option2 <option SELECTED VALUE="opt3">option3 </select> </form>
    And then when it gets to your Perl script, you can treat it as an array. Otherwise, your Perl script really does only see it as one value.
    -Eric

    UPDATE Okay, maybe it's time to kick myself for having a PHP background before I came around to the Perl world :-)

    However, what would the proper method be in this scenerio -- If I used HTML::Template to build my template, and CGI.pm to process them.. in that case, what would be the proper thing to name the SELECT element?
    a. <select name="myname" multiple> b. <select name="myname[]" multiple>
    Thanks! :-)
      You would name it whatever you want. You would then access multiple valuse by assigning to an array when requesting the values:
      my @selected = $query->param("my_multiple_select");
      Or just use it in a list context:
      foreach my $sel ( @{$query->param("select")} ){ ... }
      You might also want to name it myname[] just to remind yourself that multiple values are allowed.

      Have a look at CGI::State. If you follow a naming convention it sets out it will take a CGI.pm query object and turn it into a multidimensional data structure.

      The name is off and it wouldn't be the best thing for maintainability but I can see how it could be handy.

      Clayton aka "tex"

Log In?
Username:
Password:

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

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

    No recent polls found