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

hi,

i'm working on a cgi script which is trying to implement a double drop down menu. basically, one drop down menu has an onChange event handler that populates the other drop down list with different things. i don't want to hardcode the options in the second menu, and i already have perl arrays that contain the options in the different menus. what i need is a way to pass the perl arrays into javascript - how would i do this? (short of trying to fool around with hidden fields)

thanks,
mina.

  • Comment on passing variables from cgi to javascript

Replies are listed 'Best First'.
Re: passing variables from cgi to javascript
by Ovid (Cardinal) on Sep 18, 2002 at 19:32 UTC

    Excellent question. Personally, this is exactly what I use templating for. Though it can be done with HTML embedded in the Perl, this is not an optimal solution. I would recommend checking out Template Toolkit or HTML::Template. Either of these can be good choices.

    Essentially, what's involved is creating a data structure that holds your data and pass it to the template for processing. You can read through the Template Toolkit docs and specifically read the dynamic content via CGI script section.

    If you don't need the full power of Template Toolkit, you can read my short tutorial on using HTML::Template.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: passing variables from cgi to javascript
by perrin (Chancellor) on Sep 18, 2002 at 20:14 UTC
      Thanks so much everyone - it was really helpful. And hey, I've already joined perlmonks - this website is a godsend.
Re: passing variables from cgi to javascript
by LTjake (Prior) on Sep 18, 2002 at 19:38 UTC
    @itemsarray = ('zero', 'one', 'two', 'three', 'four', 'five', 'six'); print "var items = new Array("; for $i (0 .. $#itemsarray) { print qq('$itemsarray[$i]', '$i'); print ", " unless $i == $#itemsarray; } print ");";
    which prints:
    var items = new Array('zero', '0', 'one', '1', 'two', '2', 'three', '3 +', 'four', '4', 'five', '5', 'six', '6');
    you can then populate a select box (via javascript) with:
    for(var i = 0; i < items.length; i += 2) { document.forms[0].selectbox.options[i/2] = new Option(items[i], it +ems[i+1]); }
    where document.forms[0].selectbox is the actual select box you want to modify.

    Update: I should mention that I'm assuming that the index in the (perl) array you're working with is the value to be used in the option tag. ie. <option value="0">zero</option>

    Update 2: oh yeah, like fruiture said, this will break if zero was in fact ze'ro -- extra escaping require so as not to break the JS array.
Re: passing variables from cgi to javascript
by fruiture (Curate) on Sep 18, 2002 at 19:09 UTC

    just create javascript arrays from the Perl arrays and then write a JS function that will do the neccessary onChange stuff. I can't actually see the (Perl-related) problem. You'll get in trouble if users switch Javascript off.

    //JS also supports multidimensional and associative arrays: foobar = new Array(); foobar['opt1'] = new Array( 'values','of','the second','select','list' +); //...
    --
    http://fruiture.de
      ah, okay - i don't think i phrased the question very well.

      the cgi script has to initialise the second list to empty values, so there's nothing to take from the second drop down menu. my question is really - how do i create a javascript array from a perl array?

      thanks

        That should be done like in the writeup of LTjake Re: passing variables from cgi to javascript with an additonal escaping of quotes.

        my %hash = ( opt1 => [qw/these are the options of the dynamic select box when opt1 in the first is selected/], #... ); my $js = 'var items = new Array();'. map { "items['$_'] = new Array('". join("','",map quotemeta => @{$hash{$_}}). "');" } keys %hash;
        --
        http://fruiture.de
Re: passing variables from cgi to javascript
by newrisedesigns (Curate) on Sep 18, 2002 at 19:25 UTC

    Hello Mina,

    You could always use javascript to capture the onChange of the first menu, and reload the page with the contents of the second menu.

    I've seen it implimented on other websites, and this would allow users with javascript turned off (me, for example) to still use the lists (put a submit button in a noscript tag to replace the onChange in the second menu).

    I'd also like to suggest picking up CGI Programming with Perl by Scott Guelich. It's a wonderful book that covers CGI, Perl, and javascript tricks.

    Also, why don't you join the Monastery? It's worth it.

    John J Reiser
    newrisedesigns.com