Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sorting on two fields 2

Status
Not open for further replies.

DonP

IS-IT--Management
Jul 20, 2000
684
US
I have a small Perl script that presents the info from a flatfile database, but I would like it to sort on one field, then sub-sort on another. But I'm not sure how to do a sort at all! What I have so far, doesn't work but it is:

[tt]
while (($line = &amp;read_file(&quot;FILE1&quot;)) &amp;&amp; ($counter < 200)) {
# split the fields at the | character
@tabledata = split(/\s*\|\s*/,$line ,$fields);

my @tabledata;
my @sort_indexes;
my @sorted;
@sorted =
map {$_->[3]} (
sort {$a->[3] <=> $b->[3]} (
map {[$_, shift(@sort_indexes)]} @tabledata));
[/tt]

I'm trying to sort on the third field ($tabledata[3]) but would also like to sort on $tabledata[8]. I'm not a programmer so any help is appreciated. Thanks!

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
Okay, i'll solve this step by step, so you get a better understanding of how you can solve this sort of problem. i won't pick the fastest to code solution, i'll pick the easiest to understand.
First, the indexes of arrays start at '0', so the first element of an array is @arr[0], not @arr[1]. that's just a little thing to keep in mind.
Now, i'll make a few statements about your database file. each line is a row, of whom the entries are separated by
/\s*\|\s*/. You are trying to sort the rows of this database, based on the information contained in certain entries in these rows. (you mentioned something about sorting the rows based on another array, but for now, i'll assume you're just sorting on the entries of the database, which is probably what you're doing)
So, the data structure you'll want is an array of arrays; a two-dimentional, spreadsheet-like structure, with rows and columns. To do this, you'll read each line in, split it into the array of the entries, and assign a reference to that array as the element in another array, the top-level array:
[tt]
my @tabledata;
while (<FILE>) {
#You'll have more here, i know.
push @tabledata, [split (/\s*\|\s*/, $_) ];
}
[/tt]

The while loop causes each line of input to be turned into an array (inside the [] part). Push that onto the array for the entire file, and it'll end up being the entire database in one, easy-to-use structure.
Now that the data is structured correctly, the sort will be much easier. In fact, all that mapping won't even be necessary, just a sort. Since you do want to sort on two different entries in the database file, i'll slowly plan out the sort block of code to work just right.
How a sort works is this: you use $a and $b to represent two arbitrary elements of the array. then, you compare those to values to see which is greater. in a normal, smallest to biggest sort, your compare should give a value of '1' if the first is greater than the second, '0' if they are equal, and '-1' if the first is smaller. the easiest operator to do this is '<=>' for numbers, 'cmp' for letters(strings). the syntax for this is '{$a cmp $b}' or
'{$a <=> $b}'. Your search isn't quite as simple.
First, you're sorting primarily based on the third element of the rows, so this will be your outer condition. Then, if the elements match each other, you'll want to move down and search based on your second criteria, the eighth element.
What that means is this. first you'll compare the third elements of any given row. if they are greater than or less than each other, you'll return 1 or -1, respectively. if, however, they are equal, you'll then compare the eighth element of the two rows, and return whatever value is appropriate. you could even continue this for every element in the row.
Here's how to code this:
[tt]
my @sorted =
sort {&amp;sort_3rd_then_8th} @tabledata;


#here's the actual sorting algorithm.

sub sort_3rd_then_8th {
if ($a->[2] cmp $b->[2]) {

#that is, if it doesn't equal '0'

return $a->[2] cmp $b->[2];
} else {
return $a->[7] cmp $b->[7];
}
}
[/tt]

You can replace 'cmp' with '<=>' depending on the type of data you're dealing with.
If you do still need to do something in the sort like what your last question asked for, repost your question with a description of exactly what needs to happen with the data, and i'll figure it out.
Just in case you're wondering, to print out the new sorted array, even into a new database file, you'll have to de-reference in a fashion similar to the folowing:
[tt]
foreach (@sorted) {
print NEWFILE (join (&quot; | &quot;, $_));
print NEWFILE &quot;\n&quot;;
}
[/tt]

But this part is very subjective, based on how your information is to be handled next.
Hope this helps you understand a little more.
X-) &quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
Thanks for the wonderful description of how it works! It makes perfect sense. It would probably have been easier if I had started from scratch with my own script instead of trying to work with someone else's, since modifications are more difficult this way but think we're almost there. I am unsure of a couple things though. Is the variable name different now that it's sorted? Is it now $sorted? Also, my counter is showing &quot;0&quot;, which is triggering the error part of the script (not shown here) and gives no results, but neither does it crash. The while was also confusing. I tried a variation on my original, and also yours but neither work. I left the other in for this example.

What I've done below is to try to incorporate your code into my existing script but there was a lot of HTML in between. I removed most if it here. The first sort field is text; the other is numeric. Also, I am not printing all the fields, just selected ones as you can see.

[tt]
&amp;open_file(&quot;FILE1&quot;,&quot;&quot;,&quot;$basedir$filename&quot;);
$counter = 0;

# while (($line = &amp;read_file(&quot;FILE1&quot;)) &amp;&amp; ($counter < 200)) {
while (<FILE1>) {
# split the fields at the | character
push @tabledata, [split(/\s*\|\s*/, $_) ];
}

my @sorted =
sort {&amp;sort_3rd_then_8th} @tabledata;

sub sort_3rd_then_8th {
if ($a->[2] cmp $b->[2]) {
return $a->[2] cmp $b->[2];
} else {
return $a->[7] <=> $b->[7]
}
# }

foreach (@sorted) {

# see if SECOND field matches query
if ($tabledata[1] =~ /^$query$/i) {

# print the THIRD field
print &quot;$tabledata[2]&quot;;

# print the FOURTH field
print &quot;<i><b>$tabledata[3]</b></i>&quot;;

# print description
$listing = &quot;- $tabledata[4],
$tabledata[5],
$tabledata[6],
$tabledata[7],
$tabledata[8]&quot;;

print &quot;$listing&quot;;

print &quot; \($tabledata[1]\) &quot;;
$counter++;
}
}
}
close(FILE1);
[/tt]

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
Oh, one bad on my part, i meant for the &quot;while (<FILE>)&quot; to be replaced by your while loop, since it contained the counter variable you needed. I'm not sure what your routines &quot;&amp;open_file&quot; or &quot;&amp;read_file&quot; do, so you may even want to get rid of those alltogether. Opening and reading files are really easy to do in perl, and you could quickly figure out how to do it correctly. If you don't, you'll probly have to leave in the original code, so you can just take my &quot;while ...&quot; part out of your code.

Next, the &quot;my&quot; variable declaration limits the varible to only exist inside the innermost brakets that contain it (well, that's the simplest explaination), so in order for other routines to be able to use it, you can do a couple of different things.
1) You can declare the variable in the outermost part of your program, without any brackets around it, preferably at the beginning of your script for readability. Then, whenever something inside brackets does something to that variable, it affects the global instance, instead of just on inside of the brackets.
2) You could redesign your program with more modularity in mind, and have various subroutines created such that the value they return is what needs to be assigned to a variable, be it reference or whatever.
I'll pick the easier of the two i've mentioned, the first, and show you what i mean.
When your script declares &quot;my @sorted ...&quot; that variable is only visible inside of the brackets where it is declared. Later, when you run the &quot;foreach (@sorted)&quot;, there is no variable to access (and this would produce a warning of some sort if you have &quot;use strict;&quot; on.).
What you need to do is predeclare the variable on it's own line outside of any enclosing brackets. just &quot;my @sorted;&quot; on a line by itself is good enough. Then, remove the &quot;my&quot; in front of where i had it declared, so it just reads &quot;@sorted = ...&quot;. This way, the @sorted array will be modified on a (basically) global level, and when you access it later with the foreach, it'll have the correct values stored in it.

Next, you're right to see that the sorted table data is then stored in &quot;@sorted&quot;, so if you want access to that data, you'll use it, not &quot;@tabledata&quot;. So, for the next part, i'll use &quot;@sorted&quot; as you should.

Lastly, you need to dereference the two-dimentional array. This is a little strange bit of concept to new programmers, and is a bit of work to get used to. If, after reading what i write, you still don't get it, i'd suggest first &quot;perldoc perlrefs&quot; (i think that's correct), and second, the camel book (O'Reilly's &quot;Programming Perl&quot;), has a great chapter on referencing/dereferencing.
Basically, the data structure i had you make is graphically a two-dimentional array; a spreadsheet. It's coded by having one array as the parent array, and another array (in this case, an anonymous array, one without name) for every entry in the parent array. Arrays can actually only have scalar values as entries, not whole arrays, so this means that each entry in the parent is actual a reference to an array. Anyway, this translates easily to your file, where every line is an record, and each record has multiple entries. What the code does is it maps all the entries into an array, and then puts that array into place in the parent.
So, in the parent, the first record (the first line of your file) is &quot;$sorted[0]&quot;, the second record is &quot;$sorted[1]&quot; and so on. the first entry in the first record (that is, the first entry in the first line) is accessed as follows: first, identify the record it's in, then identify the entry you want. Here's how this looks:
[tt]$sorted[0]->[0][/tt]
The second entry in the first record is:
[tt]$sorted[0]->[1][/tt]
The third entry in the first record is:
[tt]$sorted[0]->[2][/tt]
and,
the first entry in the second
[tt]$sorted[1]->[0][/tt]
As you can see, the first number represents the record, the second represents the entry number.
Now, you'll be running a foreach loop around the sorted array. That means each time it runs through, it'll be dealing with the reference to the array that is each record. This means you'll need to dereference the entries on the fly.
Another thing you'll need to be aware of is that you won't be able to get the right results by accessing the actual data, as you had been doing. The foreach loop will set the variable &quot;$_&quot; to the element of the loop you'll be dealing with each pass.
[tt]
foreach (@sorted) {

# see if SECOND field matches query
if ($_->[1] =~ /^$query$/i) {

# print the THIRD field
print &quot;$_->[2]&quot;;

# print the FOURTH field
print &quot;<i><b>$_->[3]</b></i>&quot;;

# print description
$listing = &quot;- $_->[4],
$_->[5],
$_->[6],
$_->[7],
$_->[8]&quot;;

print &quot;$listing&quot;;

print &quot; \($_->[1]\) &quot;;
$counter++;
}
}
[/tt]

This code will correctly dereference things.
A couple of last notes. First: I'm not sure what your $counter is doing, so i'll let you figure out the logic of that. Second: If you need to know more about what's going on inside your program, but don't really want to learn the debugger, you put &quot;print $_;&quot;, or any variable name, for that matter, just to make sure it has a value. On that note, a reference will print out something like the following &quot;ARRAY (0x8b1d4)&quot; or something, which means you need to dereference something first. Third: If you do use &quot;use strict;&quot;, you'll need to explicitly declare all variables before you use them. while this is very good practice, your code doesn't do so already, so you would have to modify it some. This would, however, make for an easier time debugging it. Lastly: although not a quick weekend read, the camel book (O'Reilly's &quot;Programming Perl&quot;) would really help your programming efforts. go through chapters that seem to pertain to the problems your having, or just start with the first and move forward.

Okay, now i should get back to work. s-) Glad i've been of assistance. &quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
I'm not exctly sure what the &quot;&amp;open_file&quot; or &quot;&amp;read_file&quot; do either but there is a subroutine with them at the bottom of the script - I posted it below. To be honest, I thought they were just some sort of error correction and but wondered if they were what was causing the sort to not work.

Thanks for the latest lession, which I shall try to follow shortly.

[tt]
sub open_file {
local ($filevar, $filemode, $filename) = @_;
open ($filevar,$filemode . $filename) ||
die (&quot;Can't open $filename&quot;);
}
sub read_file {
local ($filevar) = @_;
<$filevar>;
}
sub write_file {
local ($filevar, $line) = @_;
print $filevar ($line);
}
[/tt]

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
P.S., I work with databases a lot so I understand the concept, including those for arrays, but only in VBscript and MS Access. The Web site referenced below in my signature tag is a very sophisticated relational database and is one that I created. This is my first attempt in using Perl though, for a personal site of music where there is a huge Discography that has gotten out of hand in plain HTML, even when using SSI. Perl though, is my programming language of choice and I have worked with it for many years by cutting and pasting existing scripts to do different things.

Still don't have it working but will read through carefully what was written to be sure I didn't miss anything. I believe I do have the Programming Perl book.

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
Cool. Sorry if i dummied it down too far.
the camel book, though, is invaluable. i wouldn't have been able to answer as succinctly as i have without it open next to me. i'm answering questions here more for the purpose of testing and refining my knowledge of perl than anything else.
Those routines are just the standard open, read, and write conventions. you could probly just ignore them and do it yourself to make sure, but they're simple enough that it shouldn't matter either way.
actually, though, now that i've seen it, you should probly use a hand-made while loop , like the one i had:
[tt]while (<FILENAME>) {...[/tt]
instead of the &amp;read_file. &amp;read_file would just return the data, and wouldn't do the extra magic things that the line above does.
however, i doubt this will be a hinderace to the success of the program at this stage. hope you can sort through it all and get it working. &quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
You didn't &quot;dummy it down&quot; at all! I found your details to be most informative and very well written. It was only the part about how arrays look that I already knew. The rest, including how Perl reads in the array, was new to me! Although I do not yet have it working, I appreciate all your help! I'm going to try a fresh script from scratch based on what you said, which should be easier than using an existing one and trying to incorporate new code into it. I use DzSoft Perl Editor which does have great debugging built in, and also frequently used snippets had be added for instant pasting in!

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
Great. Glad i've help, and good luck. &quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
Got it! I simply started over using the help you gave, along with the help of Perl 5 for Web Professionals which is easy to understand and is inexpensive. I didn't have the name of the one you recommended with me. This new script is very basic, presenting just the way the old one did and is half the size, though I have not yet added the search querystring that allows it to pull out particular items based on a querystring in the URL. But I decided that I wanted to sub-sort on one more field and, as you can see by the remarked out lines below, I couldn't get it to work. At this point, it must be just a very simple syntax error but I couldn't find it. Can you? Thanks!

[tt]
#!/usr/bin/perl

$database = &quot;database/table.db&quot;;

print &quot;Content-type: text/html\n\n&quot;;
print &quot;<html><head>\n&quot;;
print &quot;<title>Test Database Application for Perl</title>\n&quot;;
print &quot;</head>\n\n&quot;;
print &quot;<body bgcolor=\&quot;#FFFFFF\&quot;>\n\n&quot;;
print &quot;<table border=0>\n\n&quot;;

open(DBRECORDS, &quot;$database&quot;);
while (<DBRECORDS>){ #You'll have more here, i know.
push @database, [split (/\s*\|\s*/, $_) ];

}

my @sorted =
sort {&amp;sort_fields} @database;

# here's the actual sorting algorithm.
sub sort_fields {
if ($a->[2] cmp $b->[2]) {
return $a->[3] cmp $b->[3];
# } elsif {
} else {
return $a->[7] cmp $b->[7];
# } else {
# return $a->[1] cmp $b->[1];
}
}

foreach (@sorted) {
$listing = &quot;- $_->[4],
$_->[5],
$_->[6],
$_->[7],
$_->[8]&quot;;

print &quot;<tr><td width=\&quot;150\&quot; valign=\&quot;top\&quot;>\n&quot;;
print &quot;$_->[2]&quot;;
print &quot;</td>\n&quot;;
print &quot;<td>\n&quot;;
print &quot;<i><b>$_->[3]</b></i>&amp;nbsp\;&amp;nbsp\;&amp;nbsp\;&quot;;
print &quot;$listing&quot;;
print &quot; \($_->[1]\)\n&quot;;
print &quot;<br>&amp;nbsp;<br></tr></td>\n&quot;;

}

close (DBRECORDS);

print &quot;</table>\n\n&quot;;
print &quot;</body>\n</html>&quot;;
[/tt]

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
(i'm at a library and can't remember my password, it's always in the cookie on my computer...)

um, okay. all you messed up is the syntax for elsif's, they each need they're own conditional statement to test in parenthesis after it.

[tt]
if ($a->[2] cmp $b->[2]) {return $a->[2] cmp $b->[2]}
[/tt]

Note here that the numbers in both the if() and the actual block are the same. Once you know that they're not equal, you'll need to return the numeric value of their relationship. You had &quot;3&quot;'s in the block but &quot;2&quot;'s in the if(), and i'm not sure you wanted that... Now, each elsif is going to look exactly like the if, only with different numbers:[tt]
elsif
($a->[6] cmp $b->[6]) {return $a->[6] cmp $b->[6]}

else {return $a->[9] cmp $b->[9]}[/tt]


that should work. you can add as many new searches as you want, each with their own elsif, as long as you keep that syntax (and remember to use '<=>' if they're numeric values).
 
You are right that the values should be the same. It was probably a typo since I was anxious to post the working code. I didn't test it much, though it seems to be working that way! I don't have the script in front of me but will look at it tomorrow to try to figure out what I meant to do. Thanks very much for the additional tips too! I'll try that also tomorrow.

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
It works like a charm! Thanks again for all your help!

Here is the &quot;final&quot; code in case someone can make some other use of it, though it is designed primarily to list audio recordings. It takes its search criterea from the search form's hyperlink but can probably also use a text search form, which I will try next.

[tt]
#!/usr/bin/perl

$database = &quot;records.db&quot;;

$querystring = $ENV{'QUERY_STRING'};

# URL example: &quot;database.cgi?12+inch+LP,Recordings,10&quot;
# keywords,title,fields
# convert plus signs to spaces
$querystring =~ tr/+/ /;
($query,$title,$fields) = split(/\s*\,\s*/,$querystring,$fields);

if ( $query ne '*') {
$querytitle = $query
} else {
$querytitle = &quot;All Formats&quot;
}

print &quot;Content-type: text/html\n\n&quot;;
print &quot;<HTML><HEAD>\n&quot;;
print &quot;<link rel=stylesheet href=\&quot;../../html/style/style.css\&quot; type=\&quot;text/css\&quot;>\n&quot;;
print &quot;</HEAD>\n\n&quot;;
print &quot;<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#0000FF VLINK=#800040 ALINK=#800040>\n&quot;;
print &quot;<TITLE>Resordings</TITLE>\n&quot;;
print &quot;<CENTER>\n&quot;;

print &quot;<TABLE width=100\% border=0 cellpadding=0 cellspacing=5>\n&quot;;
print &quot;<CAPTION>Recordings / $querytitle<br>\&amp;nbsp\;<br></CAPTION>\n&quot;;
print &quot;<TR><TD Colspan=2>\n&quot;;
print &quot;<A HREF=\&quot;formats_experimental.html\&quot;>Return to the Experimental Database</A>\n&quot;;
print &quot;</TD></TR>\n&quot;;

open(DBRECORDS, &quot;$database&quot;);

while (<DBRECORDS>){
push @database, [split (/\s*\|\s*/, $_) ];
}

my @sorted =
sort {&amp;sort_fields} @database;

sub sort_fields {
if ($a->[3] cmp $b->[3]) {
return $a->[3] cmp $b->[3]}
elsif ($a->[1] cmp $b->[1]) {
return $a->[1] cmp $b->[1]}
else {
return $a->[7] cmp $b->[7]}
}

foreach (@sorted) {
$listing = &quot;- $_->[4],
$_->[5],
$_->[6],
$_->[7],
$_->[8]&quot;;

if ($_->[1] =~ /^$query$/i) {
print &quot;<tr><td width=\&quot;150\&quot; valign=\&quot;top\&quot;>\n&quot;;
print &quot;$_->[2]&quot;;
print &quot;</td>\n&quot;;
print &quot;<td>\n&quot;;
print &quot;<i><b>$_->[3]</b>&amp;nbsp\;</i>&quot;;
print &quot;$listing&quot;;
print &quot; \($_->[1]\)\n&quot;;
print &quot;<br>&amp;nbsp;<br></tr></td>\n&quot;;

}
}
close (DBRECORDS);

print &quot;</table>\n\n&quot;;
print &quot;</body>\n</html>&quot;;
[/tt]

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
The script above searches by queries appended to a text hyperlink, such as: database.cgi?record+format,1

The &quot;1&quot; tells it to search the second field in the database and &quot;record+format&quot; (that's just an example) needs to be exactly as it is in the database, which is fine. But I now want to also search the third field in all or partial keywords from a form, but can't seem to get it submitted in a format that it needs. I replaced the [1] with a variable called $searchfield so the value can be set to either [1] or [2] on the fly, but the best I get from a form using GET is a querystring like this: &quot;querystring=Record Title&searchfield=2&quot; POST gives no resoults.

It's somewhere in here, I think, but the entire script is posted above:

[tt]$querystring = $ENV{'QUERY_STRING'};

# URL example: &quot;discography.cgi?12+inch+LP,1&quot;
# keywords
# convert plus signs to spaces
$querystring =~ tr/+/ /;
($query,$searchfield) = split(/\s*\,\s*/,$querystring,$searchfield);[/tt]

Any ideas how to do it?

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
data that is in post form is alot different from that which is in get form.
the easy answer is to just use CGI::Lite (from CPAN) or CGI (standard dist.). for CGI::Lite, do the following:[tt]

my $cgi = new CGI::Lite;
my %form = $cgi->parse_form_data;
[/tt]

then %form will have and key for every <input ...> in the form that submitted to the cgi script.
to use plain CGI just:[tt]

my $cgi = new CGI;
[/tt]

and $cgi will be a reference to that same hash (which you'll access like: $cgi->{'NAME'} ). CGI::Lite is easier for your task and smaller than CGI. and, if you want to, the actual code involved isn't that hairy, and you could ask for that instead. (i would have actually included that code too, but i'm kinda sleepy right now, and can't seem to find it.)
either way, if you do have a string in your page you need passed, have the form say
<...METHOD=&quot;post&quot; ACTION=&quot;yourperl.cgi&quot;...>
and then every input must have a name, which will then be the key in the hash created by either CGI module. so with the form(in normal HTML):[tt]

<FORM METHOD=&quot;post&quot; ACTION=&quot;yourperl.cgi&quot; NAME=&quot;boring&quot;>

<INPUT TYPE=&quot;hidden&quot; NAME=&quot;one&quot; VALUE=&quot;foo&quot;>
<INPUT TYPE=&quot;hidden&quot; NAME=&quot;two&quot; VALUE=&quot;bar&quot;>
<INPUT TYPE=&quot;hidden&quot; NAME=&quot;three&quot; VALUE=&quot;baz&quot;>

<INPUT TYPE=&quot;submit&quot; NAME=&quot;test&quot;>
</FORM>
[/tt]

your %form hash will then have three (relevent) entries, 'one', 'two' and 'three', each assigned to the value it had written (this can, of course, be used with any type of input. i just had hidden left over from the file i swiped that code from.) .

this will require a little restructuring of the web page itself, as well as the cgi that will read this data, but it should allow you more freedom to pass in quality information.

i hope some of this made sense to you, cause it sure isn't making sense to me. s-)
&quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
I think CGI is already installed on the server, which is Linux via an ISP. How can I tell? Yes I know POST and GET are entirely different and I want to use POST, but could not get any value into the script unless I used GET. I'm not sure if I know how to impelment you suggestion but I'll try. Thanks!

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
I already have the two form fields needed, but it's getting the script to not use the field &quot;name=&quot; in addition to the &quot;value&quot; that is the problem. Based on your suggestion, I tried using the CGI that is already on the server but can't get it to work. Either I get nothing, or I get a server error so I'm sure I am doing something wrong. Also, don't I need a &quot;use CGI;&quot; line somewhere?

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
yeah, a cgi script using CGI.pm needs the line:[tt]
use CGI;[/tt]

you should then also use the lines:[tt]
my $query = new CGI;
my %form = %$query;[/tt]

this will then be the form hash i mentioned. you can verify this by having:[tt]
foreach (keys(%form))
{
print &quot;$_ = ${form{$_}}\n&quot;;
}[/tt]

after it.

from then on, you can get at all the values by using
'$form{NAME}'
substituting the name of any input field from the calling webpage for 'NAME'. in my previous example, '$form{one}' would be equal to 'foo', etc.

is this enough help? if not, you can read the CGI docs, which eventually have exactly how to use it (they're a thick read, and probably not worth your time at this point. well, actually, reading manuals is what programming is really all about, right?). i could probly dig up some suitable sample code i could give you to read over, maybe figure it out from example, if you want.

good luck. &quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
It makes perfectly good sense but try as I might, I just get a &quot;file not found&quot; error with the code above. A 500 error would make sense, but not a 404! My Perl editor shows that the syntax is correct and that it should run.

Actually I can get the information into the script easily by other means, but the values keep being preceeded by the name= and the script is not designed to work that way. All I need are the values separated by a comma since the script is designed to take the values from a hyperlink and that's the way it is there.

After trying everything else I could think of, I tred giving the form the same name for the two values since HTML will automatically separate them with a comma when it gets two form &quot;names&quot; that are the same. But POST does not seem to submit the information:

[tt] if ($FORM{'query'} ne &quot;&quot;) {
$querystring = &quot;($FORM{'query'})&quot;;
} else {

}[/tt]

Don
don@ctagroup.org
Experienced in HTML, Perl, VBScript, PWS, IIS and Apache. Run OS/2 Warp 4, BeOS v5 and Windows NT (only when I have to!)
 
hrm....
okay, i think i'll need to see your entire code as it is right now, HTML and perl, before i can give this a perfect answer. post it, and i'll be much better able to help.
(you may wanna start another thread, as i'm actually noticing the load time on this one, wishing i had broadband)
&quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top