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

Hi Monks!
I am trying to build a dropdown menu with dynamic values, but I cant make this thing work, can any one show me if here is a better way to get this done? I do need to store the value in one variable to use it later, that's where my issue is, thanks for the help!
#!/usr/bin/perl use CGI::Carp qw(fatalsToBrowser set_message); use CGI qw(-oldstyle_urls :standard); print header(); my @acc = qw(12345 67895 123445 112288 3736666 445899); my $c=0; my $dmenu="<select name=dropdown>". foreach my $accs(@acc) { $c++; "<OPTION value=$c>$accs</OPTION>". } "</select>"; print $dmenu;

Replies are listed 'Best First'.
Re: Dynamic menu options
by Your Mother (Archbishop) on Jul 28, 2010 at 19:06 UTC

    I think this is a *much* better approach-

    use warnings; use strict; use CGI qw(:standard); my @acc = qw( 12345 67895 123445 112288 3736666 445899 ); print popup_menu({ -name => "account", -values => \@acc, });

    .= in HTML/string generation is a danger sign (in my book; it's on sale, 2¢ this week).

      What do you mean danger sign? Besides, that was a typo on OPs part, using . instead of ;

        ".=" wasn't a typo. Concatting strings like that has, to me at least, a huge code smell. It's a sign that you are doing things in a suboptimal, if not terrible, way.

Re: Dynamic menu options
by kennethk (Abbot) on Jul 28, 2010 at 17:51 UTC
    I suspect the issue is that you are not storing your strings in $dmenu as you go through. You seem to be using a foreach loop in place of map - Perl tells you this is a syntax error. Perhaps you mean:

    #!/usr/bin/perl use CGI::Carp qw(fatalsToBrowser set_message); use CGI qw(-oldstyle_urls :standard); print header(); my @acc = qw(12345 67895 123445 112288 3736666 445899); my $c=0; my $dmenu="<select name=dropdown>"; foreach my $accs(@acc) { $c++; $dmenu .= "<OPTION value=$c>$accs</OPTION>"; } $dmenu .= "</select>"; print $dmenu;

    Note I have used the concatenating assignment operator .= (see Assignment Operators, Additive Operators).

    Update: Copy paste fail fixed.

      Yes it makes sense, but it is needed to remove the "my" from $dmenu inside "foreach" and last line of the code.
      How could I delimit the values on the array to display only 4 numbers instead of all of them? Cause sometimes I will have years stored in there and I don't need to display more them 4 years starting from current year backwards, could I use "pull"?
        If "pull" corresponds to shift, then yes. You can swap your loop variable to $c (though the only single-letter variables that are generally considered good form are $i, $j, $x, $y and $z) and use a shift to get the array member, which would destroy the array in the process. You could also use indices on the array to the same end.

        #!/usr/bin/perl use CGI::Carp qw(fatalsToBrowser set_message); use CGI qw(-oldstyle_urls :standard); print header(); my @acc = qw(12345 67895 123445 112288 3736666 445899); my $dmenu="<select name=dropdown>"; my $count = 4; foreach my $c (1 .. $count) { my $accs = shift @acc; $dmenu .= "<OPTION value=$c>$accs</OPTION>"; } $dmenu .= "</select>"; print $dmenu;