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

From CGI docs on how to make a scroll box:
print $query->scrolling_list(-name=>'list_name', -values=>['eenie','meenie','minie','mo +e'], -default=>['eenie','moe'], -size=>5, -multiple=>'true',
How in the world would you create one with dynamic content from a hash? I mean, let's say I have %names = ("Fred", "Wilma", "Dino", "Rock") , how would I set those as values? And does -size=>5 represent how many items are on the screen before the box scrolls?

Thanks for all your help.

Replies are listed 'Best First'.
Re: Dynamic values in scroll box?
by Aristotle (Chancellor) on Dec 26, 2003 at 05:18 UTC
    %names = ("Fred", "Wilma", "Dino", "Rock")
    That doesn't quite look like a hash - at least I'm not sure you really meant for "Fred" to be the key to the value "Wilma" and "Dino" the key to the value "Rock". Are you talking about an array. Assuming you want to have all of a hash's keys in the box, the syntax is something like
    [ keys %names ]

    which gives you a reference to an anonymous array, which gets filled with the list returned by the keys function. Read perlreftut, perllol, and perldsc for the full scoop.

    If you set size to 1, you'll get a dropdown box, otherwise you'll see a scrolling list with that many items shown at once. This is really an HTML question, not a Perl one.

    Makeshifts last the longest.

      I meant a hash, I have an SDBM_File full of names => email addresses and I want to get all the names to be put into a scroll box.
Re: Dynamic values in scroll box?
by jeffa (Bishop) on Dec 26, 2003 at 15:16 UTC

    CGI.pm's scrolling_list() and popup_menu() methods can be hard to get the hang of. Even though the others have answered your question, another question that you will likely ask is how do you now use different labels for your values -- that is, instead of:

    <option value="Fred">Fred</option> <option value="Wilma">Wilma</option> <option value="Dino">Dino</option>
    You now want:
    <option value="4">Fred</option> <option value="5">Wilma</option> <option value="9">Dino</option>
    Sometimes, you wonder why you can't just say:
    my %name = (Fred => 4, Wilma > 5, Dino => 9); print scrolling_list(-name => 'list_name', -values => \%name);
    And let it handle the mapping for you. There are reasons why you cannot do this:
    • the -values parameter accepts an array ref or single scalar only
    • hashes are not ordered
    • do we want the hash keys to be the labels or the hash values? CGI.pm doesn't know!
    and there may be other reasons. So, how to you achieve a select box that looks like:
    <option value="4">Fred</option> <option value="5">Wilma</option> <option value="9">Dino</option>
    First, we deiced what the values and labels are going to be. Originally, the values and the labels were the same, but now the values are [4,5,9] and the labels are [qw(Fred Wilma Dino)]. So the hash i provided above was backwards!
    my %name = (Fred => 4, Wilma > 5, Dino => 9);
    This is snag #1 ... make sure your hash keys are the values that will be passed to -values. Let's reverse the hash by hand:
    my %name = (4 => 'Fred', 5 => 'Wilma', 9 => 'Dino');
    Now we need to decide how to order. We'll pick alphabetical ordering by the labels. We achieve this when we specify the -values attribute. Since that attrib wants an array ref, we will need to construct one from our hash, %name. Here is one way to do that:
    my @value = sort { $name{$a} cmp $name{$b} } keys %name;
    A bit daunting for newbies, but rest assured that the results are (9,4,5) - that is, the numbers will be ordered by their respective labels, alphabetically.

    Since we have already done the work of 'lining up' our values to our labels, all we need do to specify the -labels attribute is pass a reference to the hash. Here goes:
    my %name = (4 => 'Fred', 5 => 'Wilma', 9 => 'Dino'); my @value = sort { $name{$a} cmp $name{$b} } keys %name; print scrolling_list( -name => 'list_name', -values => \@value, -labels => \%name, );
    And the result should be:
    <select name="list_name" size="3"> <option value="9">Dino</option> <option value="4">Fred</option> <option value="5">Wilma</option> </select>
    Hope this helps. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: Dynamic values in scroll box?
by pg (Canon) on Dec 26, 2003 at 07:37 UTC

    I have a cgi script for my internet chatroom, and I cut and paste several lines here:

    if ($peer) { $msg .= $cgi->scrolling_list(-name => 'peer', -value => \@chat +_user, default => $peer, size => 5, multiple => 'false'); } else { $msg .= $cgi->scrolling_list(-name => 'peer', -value => \@chat +_user, default => "All", size => 5, multiple => 'false'); }

    It basically creates a scrolling list and take values (chat room user names) from a list @chat_user. As size is 5, so the view of the list contains 5 elements.

    In your case, if you want the names to be showed in the scrolling list, just:

    print $query->scrolling_list(-name=>'list_name', -values=>keys %names, -default=>['eenie','moe'], -size=>5, -multiple=>'true');
      Thank you so much! That does work, but I have one last question. Is it possible to make the names into links in the scroll box?
        Not to my knowledge. But that's just because browsers don't support that (it's not part of the "HTML standard").

        Liz

        Depends on how much scroll box functionality you want. You could something ..interesting.. like sticking the values in a div tag and then using css to make it scroll..