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

I have a cgi script that consists of a drop down box that lists a number of servers (pulled from a db) and a number of fields that describe various properies of said servers.

At the moment I have manually set -value=>'unknown' for each field but I would like the default values of each of the fields to be populated with values pulled from a db table (keyed on the server name) the moment a user selects a particular server from the drop down box in the form.

Is there a way to do this other than resorting to javascript?

Here's a snipit of the code as it stands now:

my $hostname_ref = $dbh->selectcol_arrayref("SELECT hostname FROM perm +_inventory ORDER BY hostname"); print $q->header ( "text/html" ), $q->start_html ( -title=>'Modify Server in inventory', -author=> 'devnull@devnull.com', -BGCOLOR=>'orange', -style=>{'src'=>'/form.css'} ), $q->h1 ( "Modify servers into USG inventory" ), $q->hr, $q->start_form( -method => "get", -action => "inv" ), $q->p( "Hostname", $q->popup_menu( -name => "host", -values => $hostname_ +ref) ), $q->p("Vendor", $q->textfield( -name => "vendor", -size => "40", -maxl +ength => "80",-value => "unknown") ), $q->p( "Serial No", $q->textfield( -name => "sn", -size => "40", -maxlengt +h => "80", -value => "unknown") ), $q->p( "Physical Location", $q->textfield( -name => "phy_loc", -size => "40", -max +length => "80", -value => "unknown") ), $q->p( "Raid Config", $q->textfield( -name=>'raid_conf', -size => "40", -max +length => "100", -value => "unknown") ), $q->p( "Function", $q->textfield( -name => "function", -size => "40", -ma +xlength => "60", -value => "unknown") ), $q->p( "Backup Locations", $q->textfield( -name => "bkup_loc", -size => "40", -ma +xlength => "80", -value => "unknown") ), $q->p( "Recovery Media", $q->textfield( -name => "recov_loc", -size => "40", -m +axlength => "80", -value => "unknown") ), $q->submit( -value => "Send to INV cgi"), $q->end_form, $q->end_html;

Replies are listed 'Best First'.
Re: cgi drop down boxes triggering form field population
by EvanK (Chaplain) on Jun 27, 2007 at 18:50 UTC
    If I properly understand what you're asking, you have one of two options:
    • You can break this form into two distinct pages, where the user is only prompted to select a form on the first page, and once that submits, they're presented with the further options on the second page (in such a case, CGI::Application might be useful)
    • Or you would have to use client-side scripting to make the page interactive.

    __________
    Systems development is like banging your head against a wall...
    It's usually very painful, but if you're persistent, you'll get through it.

Re: cgi drop down boxes triggering form field population
by blue_cowdawg (Monsignor) on Jun 27, 2007 at 19:19 UTC
        my $hostname_ref = $dbh->selectcol_arrayref("SELECT hostname FROM perm +_inventory ORDER BY hostname");

    Something's missing here... I can't put my finger on it.

    Let's take this one step at a time here. Here is a quick code sniglet that I threw together as "proof of concept" to what we're trying to accomplish:

    use CGI; my $array_ref=[ 'eenie','meenie', 'miney', 'mo' ]; my $cgi = new CGI; print $cgi->popup_menu(-name=>'my_popup',-values=>$array_ref);
    it very faithfully produced the HTML that I was expecting as such:
    <select name="my_popup" > <option value="eenie">eenie</option> <option value="meenie">meenie</option> <option value="miney">miney</option> <option value="mo">mo</option> </select>

    Now let's look at the other half of the equation. Your database query. You did not state which Perl database interface you were using. But for sake of argument I will use the pattern for DBI/DBD and I'll use a PostgreSQL database for my example.

    #!/usr/bin/perl -w use strict; use DBI; use CGI; my $dbh = DBI->connect('DBI:Pg:funkymonkey;host=some.host.com', 'user','password') or die $DBI::errstr; my $array_ref = $dbh->selectall_arrayref(qq( select * from person order by surname ) ) or die $dbh->errstr; my $cgi = new CGI; print $cgi->dropdown_menu(-name=>'myselect', -values=>$array_ref);
    Well... if we run that code we see something very strange:
    <select name="my_popup" > <option value="ARRAY(0x928fb1c)">ARRAY(0x928fb1c)</option> <option value="ARRAY(0x928fb40)">ARRAY(0x928fb40)</option> <option value="ARRAY(0x928fb64)">ARRAY(0x928fb64)</option> <option value="ARRAY(0x928fb88)">ARRAY(0x928fb88)</option> <option value="ARRAY(0x928fbac)">ARRAY(0x928fbac)</option> <option value="ARRAY(0x928fbd0)">ARRAY(0x928fbd0)</option> <option value="ARRAY(0x928fbf4)">ARRAY(0x928fbf4)</option> <option value="ARRAY(0x928fc18)">ARRAY(0x928fc18)</option> <option value="ARRAY(0x928fc3c)">ARRAY(0x928fc3c)</option> <option value="ARRAY(0x928fc60)">ARRAY(0x928fc60)</option> <option value="ARRAY(0x928fc84)">ARRAY(0x928fc84)</option> -- stuff deleted -- </select>

    So, what's happening? Here is where Data::Dumper is our friend. If we do a

    : use Data::Dumper : rest of our code print Dumper($array_ref);
    we see:
    $VAR1 = [ [ 'Berghold' ], [ 'Bach' ], [ 'Bailey' ], [ 'Battistoni' ], [ 'Battistoni' ], [ 'Becker' ], [ 'Belfer' ], [ 'Bennett' ], --- etc ---

    What's happening is each row being returned is an array reference and the entire return variable is an array reference to an array of array references.

    So, what you need to do is pull the desired elements out of the return to your query and put them in another array reference.

    This ought to do it:

    | stuff left out... | handwaving... print $cgi->popup_menu(-name=>'my_popup',-values=>[ map { $_ -> [0] } +@$array_ref ]); | |


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg