Re: making the keys of a hash from parameters collected from a form



On Nov 29, 12:23 am, "A. Sinan Unur" <1...@xxxxxxxxxxxxxxxxxxx> wrote:
mike <rall...@xxxxxxxxxxxx> wrote in news:35f36fbc-c724-4df0-a418-
840e48f98...@xxxxxxxxxxxxxxxxxxxxxxxxxxxx:

Hello everyone:
I have the need to prioritize a number of items from a list and then
print them out in the order in which they were chosen. To be more
specific, I have a list of 12 items and I would like to have the users
indicate which is their first choice, which is their second, etc. up
to 8. I must put the items into a file in the order which has been
prioritized by the user.

...

print $q->h3(textfield(-name=>'app', -size=>1),"apple");

A textfield in h3? We're straying off-topic here but that is awful HTML.

my %hashfruit=(
"param('app')"=>'app',
"param('lem')"=>'lem',
"param('ora')"=>'ora',
"param('lem')"=>'lem',
"param('lim')"=>'lim',

...

instead of getting the values (1
and 2), I get as keys the strings 'param(app)'

You are specifying the keys as strings in the form "param('app')"
yourself. That's what you told your program to do. How do you expect
anything else to happen?

If, instead, you had used

my %hashfruit=(
param('app') =>'app',
param('lem') =>'lem',
param('ora') =>'ora',
param('lem') =>'lem',
param('lim') =>'lim',
);

the results of the param calls would be stringified.

Of course, you are not performing any sanity checks on the inputs so
this has the potential of becoming problematic. By giving each textfield
a different name, you are making life unnecessarily hard.

Instead, use the same name, say 'rank', for all the textfields. That
way, things like checking that all the ranks are distinct, all the ranks
are numbers etc becomes a much easier operation and you don't have to
make a whole bunch of changes every time you change the list of fruits.

As your scripts are too messy to modify, here is an alternative:

#!perl

use strict;
use warnings;

use CGI qw( -no_xhtml );

my @FRUITS = qw( apple orange lemon lime banana );

my $cgi = CGI->new;
print $cgi->header( 'text/html' );

unless ( $cgi->param ) {
show_form( $cgi );}

else {
process_form( $cgi );

}

sub show_form {
my $cgi = shift;
my ( $msg ) = @_;

print $cgi->start_html;

if ( $msg ) {
print $cgi->p( $cgi->em( $msg ) );
}

print $cgi->start_form( -method => 'GET' );

for my $fruit ( @FRUITS ) {
print $cgi->p(
$cgi->textfield( -name => 'rank', -size => 1 ), $fruit
);
}

print $cgi->p( $cgi->submit, $cgi->reset ),
$cgi->end_form,
$cgi->end_html;
return;

}

sub process_form {
my $cgi = shift;
my @ranks = $cgi->param( 'rank' );

for my $rank ( @ranks ) {
$rank =~ s/^\s+//;
$rank =~ s/\s+$//;

unless ( $rank =~ /^(\d+)$/
and $rank => 1
and $rank <= @FRUITS
) {
return show_form(
$cgi,
sprintf(
'Ranks must be integers between %d and %d.',
1, scalar @FRUITS
)
);
}
}

my %ranked;
@ranked{ @ranks } = @FRUITS;

unless ( keys %ranked == @FRUITS ) {
return show_form(
$cgi,
'Please fill in all spaces with distinct ranks.'
);
}

print $cgi->start_html,
$cgi->ol(
$cgi->li(
[ map { $ranked{ $_ } } sort keys %ranked ]
)
),
$cgi->end_html;
return;

}

__END__

--
A. Sinan Unur <1...@xxxxxxxxxxxxxxxxxxx>
(remove .invalid and reverse each component for email address)
clpmisc guidelines: <URL:http://www.augustmail.com/~tadmc/clpmisc.shtml>

Dr. A. Sinan Unur: Thank you very much for both these approaches and
their explanations. This may have been too elementary a question for
this newsgroup, but I got a lot of bad advice from the beginners'
group. Thanks again.
.