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

I am trying to collect the values from the a cgi form and creating a file. Earlier I used to have only one text field, so using param I was collecting the params, but now I am adding one more and trying to collect the values from those 2 fields. Here is snippet from the cgi form.
print $q->start_table; &first_process; foreach (@comment) { #array starts here ($jobname, $element, $comment)= split /\|/; my $element_drop=$element . "_drp"; print $q->Tr( $q->td($jobname), $q->td( $q->textfield(-name => $element, -size => 50, -default=> $ +comment) ), $q->td( $q->popup_menu(-name => $element_drop, -values => ['N/A',' +Infra Issue','UpStream Delay','Teradata Issue', 'AbInitio Issue','Oth +ers'], -default => 'N/A', -labels => \%cause_opt ) ) );
In the action page, I am collecting the params like this"
my %params = $q->Vars; my @hash_array_keys=keys %params; my @hash_array_values=values %params; open FILEHANDLE, ">/tmp/hash.dat" or die "Can not open hash.dat"; $, = "\n"; for my $k (sort @hash_array_keys) { print FILEHANDLE $k, $params{$k}; } #print FILEHANDLE values %params; close FILEHANDLE;
But I need the file in the format
textfield1|popup_menu1 textfield2|popup_menu2 textfield3|popup_menu3
Is there any way to achieve this? I tried printing the hash values but they are not coming in order. Thanks In advance.

Replies are listed 'Best First'.
Re: Problems around Param
by ww (Archbishop) on Aug 25, 2015 at 13:05 UTC

    Some will suggest abandoning CGI.pm, in line with the reasons cited in connection with its removal from core. (I don't subscribe to that.) But a directly relevant suggestion would be to read the doc -- "perldoc cgi" as it discusses using hashes and hash references... and alternatives that would solve your problem.


    ++$anecdote ne $data

Re: Problems around Param
by QM (Parson) on Aug 25, 2015 at 13:46 UTC
    I'm not sure this is the help you need. But with that caveat, I'm diving in...

    You don't show an example of your output, nor of the data structures (try Data::Dumper).

    For a more mundane Perl question, you have:

    for my $k (sort @hash_array_keys) { print FILEHANDLE $k, $params{$k}; }

    which would print like so:

    key1value1 key2value2 key3value3

    To fix that -- adding a pipe separator -- try this:

    for my $k (sort @hash_array_keys) { print FILEHANDLE "$k|$params{$k}"; }

    And it seems you are working too hard to get the keys and values -- try this:

    my %params = $q->Var; for my $k (sort keys %params) { print FILEHANDLE "$k|$params{$k}"; }

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

Re: Problems around Param
by Anonymous Monk on Aug 25, 2015 at 13:31 UTC
    Are you aware CGI->Vars corrupts data? You should use param method

      Citings? I don't see anything about Vars corrupting data specifically. In perldoc CGI:

      "Note that you must use ->upload or ->param to get the file-handle to pass into uploadInfo as internally this is represented as a File::Temp object (which is what will be returned by ->upload or ->param). When using ->Vars you will get the literal filename rather than the File::Temp object, which will not return anything when passed to uploadInfo. So don't use ->Vars."
      "If you are using a machine that recognizes "text" and "binary" data modes, be sure to understand when and how to use them (see the Camel book). Otherwise you may find that binary files are corrupted during file uploads."

      When making blanket statements like "CGI->Vars corrupts data", please source it with authoritative material (where available), or at least explain some detail of the problem.

Re: Problems around Param (CGI->param or CGI->multi_param instead of CGI->Vars )
by Anonymous Monk on Aug 26, 2015 at 01:40 UTC

    param or multi_param is what you should use

    use CGI; my $q = CGI->new('1=1;8=8;9=1;9=2;9=3;9=4;9=5;9=6;9=7;9=8;9=9;99=99;a= +a;b=b;Z=Z;'); for my $k ( sort $q->param ) { print join'|', $k, $q->multi_param( $k ), "\n"; } print "##" x 3, "\n"; for my $k ( sort $q->param ) { my $v = $q->param( $k ); print join'|', $k, $v, "\n"; } __END__ 1|1| 8|8| 9|1|2|3|4|5|6|7|8|9| 99|99| Z|Z| a|a| b|b| ###### 1|1| 8|8| 9|1| 99|99| Z|Z| a|a| b|b|
      I am not looking in this format. For each row, I have two fields, comment(textfield) and cause(dropdown). So for each row I need like
      comment1|cause1 comment2|cause2 comment3|cause3
      In the above method you are printing Key/Value combination, but I need two values from foreach statement. Is is possible to do it using param function? or Any other way to achieve it ?

        I'm guessing from your script the parameters are paired by the names 'element' and 'element_drp'

        #!perl use warnings; use strict; use CGI; my $string = join ';',('elem1=comment1','elem1_drp=cause1', 'elem2=comment2','elem2_drp=cause2', 'elem3=comment3','elem3_drp=cause3'); my $q = CGI->new($string); for my $k ( sort $q->param ) { if ($k =~ /(.+)_drp$/){ print join'|', $q->param( $1 ),$q->param( $k )."\n"; } }
        poj

        In the above method you are printing Key/Value combination, but I need two values from foreach statement. Is is possible to do it using param function? or Any other way to achieve it ?

        Is answer by poj what you want?

        If it isn't, you're going to have to be more specific, for example, provide a CGI->new('stringhere') that accurately represents the input you have