You will be afraid, very afraid, of this code I spent the last hour banging out and testing. It works, which is the most frightening thing.

I just wrote this because I had some once off drop down code that I wrote, and I just realised for this new project I'm starting, I'll need to use drop downs more regularly to customise the results of some screens.

Features: simplifies generation of drop downs, remembers past selections using cookies, code is fairly brief and should be easy to understand. Selecting a drop down option forces a page refresh under all the browsers I've tried. Also uses the CGI classes exclusively for HTML generation. MakeDropDowns::addDropDown takes four arguments.

  • A short, one word descriptive name which will name the form and the cookie.
  • A full, descriptive name used in the form.
  • An anon hash with key value pairs used as the selection options. The key can be used with CGI::getparam to fetch what the selection was.
  • Finally, a default value for the form.

    Example usage:

    my $dropDowns = new MakeDropDowns($cgi); $dropDowns->addDropDown("date", "Please Select Date", { today => 'Today', yesterday => 'Yesterday', everything => 'All Days', lastweek => 'Previous 7 Days', thismonth => 'This Month', }, 'today'); $dropDowns->addDropDown("type", "Please select display", { errors => "Errors", everything => "Everything", completed => "Completed", }, 'errors'); print " <html> <head> <script language='javascript'> " . $dropDowns->getJavascript . " </script> </head> "; # and then in the place you want them rendered: print $dropDowns->getHtml;
    Updated: s/$cgi/$self->{cgi}/g

  • package MakeDropDowns; use CGI qw/-nosticky *table :all start_Tr end_Tr start_table/; use CGI::Pretty qw/:html3/; use POSIX; sub new { my $class = shift; my $cgi = shift; my $self = { cgi => $cgi }; return bless($self, $class); } sub addDropDown { my $self = shift; my $shortname = shift; my $fullname = shift; my $options = shift; my $default = shift; $self->{dropDowns}->{$shortname} = $options; $self->{defaults}->{$shortname} = $default; $self->{fullname}->{$shortname} = $fullname; } sub getHtml { my $self = shift; my $htmlReturn = ""; foreach my $shortname (keys %{$self->{dropDowns}}) { my $cgiValue = $self->{cgi}->param($shortname); $cgiValue = $self->{defaults}->{$shortname} if defined $self-> +{defaults}->{$shortname}; my $cookie = $self->{cgi}->cookie({name=>$shortname}); $cgiValue = $cookie if $cookie; my %searchOptions = %{$self->{dropDowns}->{$shortname}}; my @keylist = keys %searchOptions; $htmlReturn .= start_form({name=>$shortname . 'Form', method=> +'post', action=>$self->{cgi}->url({path_info=>1})}) . start_table({align=>'center', cellspacing=>5, cellpadding= +>0, border=>0}) . Tr( td(span({style=>'font-weight: bold'}, $self->{fullname} +->{$shortname})), td(popup_menu({ name => $shortname,, values => \@keylist, labels => \%searchOptions, onChange => "searchChanged$shortname()" +})) ) . end_table() . end_form(); } return $htmlReturn; } sub getJavascript { my $self = shift; my $url = $self->{cgi}->url({absolute=>1}); my $fullurl = $self->{cgi}->url({path_info=>1, query=>1}); my @lt = localtime; my $time_t = POSIX::mktime(0, 0, -10, $lt[3]+1, $lt[4], $lt[5]); my $cookieExpiry = POSIX::strftime("%a, %d-%b-%Y %H:%M:%S GMT", lo +caltime($time_t)); my $output = "function setCookie(name, value, path, expires, domai +n, secure) \n{ var curCookie = name + \"=\" + escape(value) + \"; expires=$cookieExpiry\" + ((path) ? \"; path=\" + path : \"\") + ((domain) ? \"; domain=\" + domain : \"\") + ((secure) ? \"; secure\" : \"\"); document.cookie = curCookie;\n}\n\n"; foreach my $shortname (keys %{$self->{dropDowns}}) { my $tmpUrl = $fullurl; $tmpUrl =~ s/\&*$shortname=\w+(\&|$)//g; $tmpUrl .= "?" if ($tmpUrl !~ /[?]/); $output .= "function searchChanged$shortname() \n{ var Fong = document." . $shortname . "Form.$shortname" . "[documen +t." . $shortname . "Form.$shortname.selectedIndex].value; setCookie(\"$shortname\", Fong, \"$url\"); document.location.href = \"$tmpUrl&$shortname=\" + Fong; \n}\n"; } return $output; } 1;

    Replies are listed 'Best First'.
    Re: MakeDropDowns using CGI
    by Juerd (Abbot) on May 16, 2002 at 08:28 UTC

      An anon hash with key value pairs used as the selection options.

      Hashes are not sorted in an expectable way. You might want to add an option to supply ordered key/value pairs.

      - Yes, I reinvent wheels.
      - Spam: Visit eurotraQ.
      

        I did a quick hack for my personal version of this class which returns a hash, keyed by 'shortname', and the value is just the '<form><select>...</form>' stuff. So you're not locked into a particular table structure, and you can enforce arbitrary ordering.

        The 'setCookie' function piked my interest. It's really something rather generic, but it *is* actually required for the thing to work. So should I write a separate javascript class to contain all my js functions? How could I organise a single function call which guarantees all the necessary js stuff is outputted (even if some js is only contained in other classes). Hmm ...

        --
        Ash OS durbatulk, ash OS gimbatul,
        Ash OS thrakatulk, agh burzum-ishi krimpatul!
        Uzg-Microsoft-ishi amal fauthut burguuli.