Gossamer Forum
Home : Products : DBMan : Customization :

Re: Sort on.......

Quote Reply
Re: Sort on....... In reply to
Hi Don:

I just finished a mod that allows you to sort on any number of fields. Realistically though it is setup for a maximum of 3 fields. I can outline the changes below ...

In html.cgi add your Select boxes for the Sort and Order fields naming them sb1, so1, sb2, so2, sb3, so3 as in ...
Code:
Sort By (1):
<SELECT NAME="sb1">
<OPTION>---
~; for (my $i =0; $i <= $#db_cols; $i++) { print qq~<OPTION VALUE="$i">$db_cols[$i]</OPTION>\n~ if ($db_form_len{$db_cols[$i]} >= 0); } print qq~
</SELECT>
Sort Order:
<SELECT NAME="so1">
<OPTION VALUE="ascend">Ascending
<OPTION VALUE="descend">Descending
</SELECT><br><br>
Sort By (2):
<SELECT NAME="sb2">
<OPTION>---
~; for (my $i =0; $i <= $#db_cols; $i++) { print qq~<OPTION VALUE="$i">$db_cols[$i]</OPTION>\n~ if ($db_form_len{$db_cols[$i]} >= 0); } print qq~
</SELECT>
Sort Order:
<SELECT NAME="so2">
<OPTION VALUE="ascend">Ascending
<OPTION VALUE="descend">Descending
</SELECT><br><br>
Sort By (3):
<SELECT NAME="sb3">
<OPTION>---
~; for (my $i =0; $i <= $#db_cols; $i++) { print qq~<OPTION VALUE="$i">$db_cols[$i]</OPTION>\n~ if ($db_form_len{$db_cols[$i]} >= 0); } print qq~
</SELECT>
Sort Order:
<SELECT NAME="so3">
<OPTION VALUE="ascend">Ascending
<OPTION VALUE="descend">Descending
</SELECT><br><br>

Changes to db.cgi are in the query sub
1. At the top change the local() definition to be
Code:
local (%sortby1);
local (%sortby2);
local (%sortby3);
2. Replace the code starting with
Code:
if ($key_match &#0124; &#0124; (!($in{'keyword'}) && !($in{'ma'}))) {
if (exists $in{'sb1'} && exists $in{'sb2'} && exists $in{'sb3'}) {
$sortby1{(($#hits+1) / ($#db_cols+1))} = $values[$in{'sb1'}];
$sortby2{(($#hits+1) / ($#db_cols+1))} = $values[$in{'sb2'}];
$sortby3{(($#hits+1) / ($#db_cols+1))} = $values[$in{'sb3'}];
push (@hits, @values);
}
elsif (exists $in{'sb1'} && exists $in{'sb2'}) {
$sortby1{(($#hits+1) / ($#db_cols+1))} = $values[$in{'sb1'}];
$sortby2{(($#hits+1) / ($#db_cols+1))} = $values[$in{'sb2'}];
push (@hits, @values);
}
elsif (exists $in{'sb1'}) {
$sortby1{(($#hits+1) / ($#db_cols+1))} = $values[$in{'sb1'}];
push (@hits, @values);
}
else {
(($numhits >= $first) and ($numhits <= $last)) and push (@hits, @values);
}
$numhits++; # But we always count it!
}
}
close DB;

# Now we've stored all our hits in @hits, and we've got a sorting values stored
# in %sortby indexed by their position in @hits.
$numhits ? ($db_total_hits = $numhits) : ($db_total_hits = 0);
($db_total_hits == 0) and return ("no matching records.");

# Sort the array @hits in order if we are meant to sort.
if (exists $in{'sb1'}) { # Sort hits on first field.
my ($sort_func, $tmp_func);

$sort_func = "";
$sort_pos = 1;
$sb_num = "sb" . "$sort_pos";

while (exists ($in{$sb_num})) {
$tmp_func = $sort_func eq "" ? "" : "$sort_func" . " &#0124; &#0124; ";
$sort_func = $tmp_func . &build_sort_func;
$sort_pos += 1;
$sb_num = "sb" . "$sort_pos";
}

$sort_func =~ tr/!/$/; # Replace temporary characters with $
foreach $hit (sort { eval($sort_func); } (keys %sortby1)) {
$first = ($hit * $#db_cols) + $hit; $last = ($hit * $#db_cols) + $#db_cols + $hit;
push (@sortedhits, @hits[$first .. $last]);
}
@hits = @sortedhits;
}

At the end of the file add the subroutine that builds the sort function on the fly...
Code:
sub build_sort_func {
my ($var1, $var2, $preprocess_func, $output, $sort_order,
$sort_order_var, $sort_type, $sort_var, $sort_comp);

$sort_order_var = "so" . "$sort_pos";
$sort_order = "$in{$sort_order_var}";

$sort_type = $db_sort{$db_cols[$in{$sb_num}]};
$sort_var = "!sortby" . "$sort_pos";

if ($sort_type eq "alpha") {
$sort_comp = ") cmp ";
$preprocess_func = "lc(";
}
elsif ($sort_type eq "date") {
$sort_comp = ") <=> ";
$preprocess_func = "&date_to_unix(";
}
else {
$sort_comp = ") <=> ";
$preprocess_func = "(";
}

if ($sort_order eq "ascend") {
$var1 = "!a";
$var2 = "!b";
}
else {
$var1 = "!b";
$var2 = "!a";
}

$output = "$preprocess_func" . "$sort_var" . "{$var1}$sort_comp" .
"$preprocess_func" . "$sort_var" . "{$var2})";

return $output;
}

Example code at oilandgasreserves.com/cgi-bin/dbman/db.pl

Excuse my beginner Perl. Hope it helps.

------------------
Don Mitchinson
Subject Author Views Date
Thread Sort on....... donm 6036 Sep 26, 1999, 2:13 AM
Post Re: Sort on.......
Eliot 5954 Sep 26, 1999, 8:14 AM
Post Re: Sort on.......
mitch 5958 Sep 27, 1999, 1:01 PM
Post Re: Sort on.......
mitch 5961 Sep 27, 1999, 1:44 PM
Post Re: Sort on.......
Eliot 5953 Sep 27, 1999, 1:50 PM
Post Re: Sort on.......
donm 5963 Sep 27, 1999, 3:48 PM
Post Re: Sort on.......
mitch 5974 Sep 28, 1999, 11:56 AM
Post Re: Sort on.......
mart 5977 Jan 19, 2000, 7:09 AM
Post Re: Sort on.......
mart 5985 Jan 22, 2000, 6:41 AM
Post Re: Sort on.......
mitch 5964 Jan 22, 2000, 8:31 AM
Post Re: Sort on.......
mitch 5963 Jan 22, 2000, 4:06 PM
Post Re: Sort on.......
mart 5955 Jan 22, 2000, 8:54 PM
Post Re: Sort on.......
mart 5974 Feb 7, 2000, 7:53 AM
Post Re: Sort on.......
mart 6031 Feb 7, 2000, 10:57 AM
Post Re: Sort on.......
mitch 5982 Feb 7, 2000, 4:31 PM
Post Re: Sort on.......
keienb 5963 Mar 29, 2000, 11:34 AM
Post Re: Sort on.......
anr 5966 Apr 2, 2000, 11:23 AM
Post Re: Sort on.......
anr 5965 Apr 2, 2000, 11:34 AM
Post Re: Sort on.......
anr 5969 Apr 2, 2000, 4:32 PM
Post Re: Sort on.......
JPDeni 5964 Apr 2, 2000, 7:36 PM
Thread Re: Sort on.......
anr 5948 Apr 2, 2000, 8:08 PM
Thread Re: Sort on....... still not searching accross
clive1 5893 Sep 21, 2000, 9:11 AM
Thread Re: Sort on....... still not searching accross
anr 5881 Sep 21, 2000, 6:36 PM
Thread Re: Sort on....... still not searching accross
anr 5886 Sep 21, 2000, 9:02 PM
Post Re: Sort on....... still not searching accross
clive1 5873 Sep 21, 2000, 11:44 PM