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

Greetings Everyone,

I am a beginer with PERL and was wondering if anyone would be kind enough to help me learn the best way to fix my current sample view dir code that uses a simple drop down menu.

There is No 500 Error, just no change onclick with the listed folders at this time.

I only wish for the letter selected in my dropdown to be matched by this condition

if($_ =~ m/^[$FORM{'sortby'}]/){

By default i would like to display all folders and when selected [a] would only show [a] folders and so on... I am totally stumped on what I have done wrong?

I would be most greatful for your thoughts!

Thank you in advance~

Jim

note: The sortby_list.dat is simply a text file that contains a list of letters a thru z

############################################### #!/usr/bin/perl -w use CGI::Carp qw(fatalsToBrowser); $viewdirpath =""; # path $viewdirpath_only = ""; # url print "Content-type: text/html\n\n"; opendir DIR, "$viewdirpath"; @$_ = readdir DIR; closedir DIR; $count = 0; foreach $_ ( sort @$_ ) { $fitem_pathname = "$viewdirpath" . "/" . "$_"; if (-e $fitem_pathname) { if (-d $fitem_pathname) { unless ($_ eq "..") { unless ($_ eq ".") { $count++; } } } } } print "<body bgcolor=$bgcolor text=$text link=$link vlink=$vlink alink +=$alink>"; print "<b>Folders Listed In Directory - $count</b><br>"; print "sort by<br>"; print "<select name=\"sortby\" style=\"font-family: Arial; font-size: +10pt\" onChange=\"if(this.options[this.selectedIndex].value!=0) self. +location=this.options[this.selectedIndex].value\">"; open (INF,"sortby_list.dat"); @file=<INF>; close(INF); foreach $sortby (@file) { chomp($sortby); if ($FORM{'sortby'} eq $sortby) { print "<option value=\"$sortby\" SEL +ECTED>sortby</option>"; } else { print "<option value=\"$script?$sortby\">$sortby</option>"; } } print "</select>"; foreach $_ ( sort @$_ ) { $fitem_pathname = "$viewdirpath" . "/" . "$_"; if (-e $fitem_pathname) { if (-d $fitem_pathname) { unless ($_ eq "..") { unless ($_ eq ".") { if($_ =~ m/^[$FORM{'sortby'}]/){ @$_ = sort { $a cmp $b } @$_; print "<br><a href=$viewdirpath_only/$_>$_</a>"; } } } } } } #print "$footer"; }

Edit Petruchio Mon Jan 27 03:20:36 UTC 2003: Added markup

Replies are listed 'Best First'.
Re: sorting a text file in PERL using a dropdown form
by Cody Pendant (Prior) on Jan 27, 2003 at 05:19 UTC
    I don't know where to start with this one, but some things which are immediately obvious:
    • You haven't got a form. You've got a JavaScript onChange statement in a SELECT menu. That's not the same as submitting a form. In fact this menu wouldn't even appear in some browsers, because it's not surrounded by a set of FORM tags
    • Huge chunks of this script are missing. Where are your colours supposed to come from in the BODY tag? More importantly, where's the part of your script where the form, if you really had one, gets processed and the %FORM hash created? Where is $viewdirpath coming from? It's set to an empty string, then used a couple of lines later. It seems like it might come from a hidden field in the missing form, or some other form, which makes your script hideously insecure.
    • Your code doesn't even run, because there's an extra bracket at the end.

    So if you really want help, show us all the code -- this can't be it.

    As I can't help you with this, some very basic things:

    You don't need a file with every letter in the alphabet it it..

    open (INF,"sortby_list.dat"); @file=<INF>; close(INF);
    and the later chomp can be thrown away: just use @file = (a..z);

    also,

    if (-e $fitem_pathname) { if (-d $fitem_pathname) { unless ($_ eq "..") { unless ($_ eq ".") { $count++; } } } }
    can be replaced with
    if (-e $fitem_pathname && -d $fitem_pathname) { unless ($_ eq ".." || $_ eq ".") { $count++; } }
    that is, you don't need to nest two statements which both need to be true and so on. Though there are better ways of doing what that code does anyway.

    Your regex

    if($_ =~ m/^[$FORM{'sortby'}]/
    doesn't work. You don't need the brackets, plus, it should be case-insensitive, as we only have lowercase letters in our @file array.
    if($_ =~ m/^$FORM{'sortby'}/i)

    But I feel guilty even going this far into the Perl because it's pretty much meaningless without the rest of it, and pretty much broken in various other ways.

    One final thing? You're not sorting anything. You're filtering a list of directories by first letter.
    --
    “Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.” M-J D

      Hi Cody, (I have taken everything you stated and applied it to the code with the best of my abilities). If you should copy this code into a new cgi named viewdir.cgi & then fill in the 2 paths needed you could see it displays all folders in the specified dir and just fails to filter the seclected value"" when selected. I really like the things you've shown me thus far and I hope this complete code below will assist you better with answering my filtering question. Thank you so much for your valued time! Jim tf198@netzero.net
      ------------------------------------------------------------ #!/usr/bin/perl -w use CGI::Carp qw(fatalsToBrowser); $viewdirpath = "/home/your_site_id/www/folder_chosen_to_view"; $viewdirpath_only = "http://www.your_url.com/folder_chosen_to_view"; $script = "http://www.your_url.com/folder_chosen/viewdir.cgi"; print "Content-type: text/html\n\n"; &view_dir; sub view_dir { opendir DIR, "$viewdirpath"; @$_ = readdir DIR; closedir DIR; $count = 0; foreach $_ ( sort @$_ ) { $fitem_pathname = "$viewdirpath" . "/" . "$_"; if (-e $fitem_pathname && -d $fitem_pathname) { unless ($_ eq ".." || $_ eq ".") {$count++;}}} print "<body bgcolor=\"#ffffff\"text=\"#000000\" link=\"#000000\ vlink +=\"#000000\ alink=\"#000000\>"; print "<b>Folders Listed In Directory - $count</b><br>"; print "<form name=\"sortbyform\" action=\"viewdir.cgi\" method=\"GET\" +>"; print "sort by<br>"; print "<select name=\"sortby\" onChange=\"if (sortbyform.sortby != \'' +) { sortbyform.submit(); }\">"; print "<option value=\"\">Select</option><br><br>"; foreach $sortby (@file = (a..z)) { if ($FORM{'sortby'} eq $sortby) { print "<option value=\"$sortby\" SEL +ECTED>$sortby</option>";} else { print "<option value=\"$sortby\">$sortby</option>";} } print "</select>"; print "</form>"; foreach $_ ( sort @$_ ) { $fitem_pathname = "$viewdirpath" . "/" . "$_"; if (-e $fitem_pathname && -d $fitem_pathname) { unless ($_ eq ".." || $_ eq "." || $_ eq "admin") { if($_ =~ m/^$FORM{'sortbyform'}/i) { print "<br><a href=$viewdirpath_only/$_>$_</a>";}}} } } ------------------------------------------------------------

      edited: Mon Jan 27 15:13:20 2003 by jeffa - added code tags

        OK remember when I said "huge chunks of your code are missing"?

        One huge chunk is still missing. The bit that receives the results of the form and processes them. I'm guessing you're using something like the Visual QuickStart Guide subroutine Parse_Form, from the name of the hash it creates, %FORM? You should put it back in. But then you should take it out again and start using CGI.pm to handle your form input.

        But your HTML is so broken that I had to close a bunch of quotes and so on before I could even get a usable page out of this code. Check your BODY tag, it's a mess of unclosed quotes. You need to start using Here Documents, or maybe qq(), for printing out tons of HTML.

        And even when you've fixed all that, it still doesn't work, because you're doing this:

        if($_ =~ m/^$FORM{'sortbyform'}/i)
        and 'sortbyform' is just the name of the form.

        What you, or whoever wrote this, intended, is presumably

        if($_ =~ m/^$FORM{'sortby'}/i)
        which is the name of the select menu, where the form-processing code you don't have would put the result of that form being submitted.

        I don't feel up to it, but I really think someone should give Anonymous Monk a brief lecture on security at this point?
        --
        “Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.” M-J D