[rt-devel] PATCH: sort by multiple columns

Grant DeGraw grant at wolfram.com
Wed Nov 12 12:21:02 EST 2003


Attached is a patch file against 3.0.6 to implement sorting by multiple
columns in the ticket search.

The patch modifies the following files:
share/html/Elements/SelectTicketSortBy
share/html/Search/Elements/TicketHeaderCell
share/html/Search/Elements/PickRestriction
share/html/Search/Listing.html
lib/RT/Interface/Web.pm

This isn't a terribly elegant implementation, but it works.  I'd like
for this functionality to be included in RT, so feedback is most welcome.

- Grant

-------------- next part --------------
--- ./share/html/Elements/SelectTicketSortBy.orig	2003-09-25 15:31:06.000000000 -0500
+++ ./share/html/Elements/SelectTicketSortBy	2003-11-11 14:17:29.000000000 -0600
@@ -22,6 +22,7 @@
 %# 
 %# END LICENSE BLOCK
 <SELECT NAME="<%$Name%>">
+<OPTION VALUE="">-</OPTION>
 % foreach my $field (@sortfields) {
 <OPTION VALUE="<%$field%>" <% $field eq $Default && 'SELECTED'%>><% loc($field) %></OPTION>
 % }
--- ./share/html/Search/Elements/TicketHeaderCell.orig	2003-09-25 15:31:06.000000000 -0500
+++ ./share/html/Search/Elements/TicketHeaderCell	2003-11-11 18:23:09.000000000 -0600
@@ -22,29 +22,50 @@
 %# 
 %# END LICENSE BLOCK
 <%INIT> 
-my ($order,$curorder);
  $Attribute =~ s/Obj->(Name|AsString|AgeAsString)//g;
-  if ($session{'tickets_sort_order'} =~ /^asc$/i) {
-   $order = 'DESC';
-   $curorder = 'ASC';
- } else {
-   $order = 'ASC';
-   $curorder = 'DESC';
- }
 $Header = $Attribute unless ($Header);
 
+my %ordered_fields;
+my $counter = 1;
+my @tickets_sort_by;
+my @tickets_sort_order;
+
+foreach my $index ( sort keys %{$session{'tickets_sort_by'}} ) {
+        my $row = $session{'tickets_sort_by'}{$index};
+        my $field = $row->{'FIELD'};
+        unless ($ordered_fields{$field}) {
+                $ordered_fields{$field} = { INDEX => $index, COUNT => $counter, ORDER => $row->{'ORDER'} };
+                push(@tickets_sort_by, $field);
+                push(@tickets_sort_order, $row->{'ORDER'});
+        }
+        $counter++;
+}
+
+foreach my $index ( keys %ordered_fields ) {
+        my @order_array = @tickets_sort_order;
+        my $invertorder = ( $ordered_fields{$index}->{'ORDER'} =~ /^asc/i ) ? 'DESC' : 'ASC';
+        $order_array[$ordered_fields{$index}->{'COUNT'} - 1] = $invertorder;
+        $ordered_fields{$index}->{'INVERT'} = 'TicketsSortBy=' . join(',', @tickets_sort_by) .
+                '&TicketsSortOrder=' . join(',', @order_array);
+}
+
+
 </%INIT>
 <th class="ticketheader">
 % if (grep (/^$Attribute$/i, $session{'tickets'}->SortFields)) {
 <A 
-% if ($Attribute eq $session{'tickets_sort_by'}) {
+% if ($ordered_fields{$Attribute}) {
+%    my $index = $ordered_fields{$Attribute}->{'INDEX'};
+%    $counter = $ordered_fields{$Attribute}->{'COUNT'};
+%    my $tag = "";
+%    if (($counter > 1) or ( (scalar keys(%ordered_fields)) > 1 ) ) {
+%      $tag = "($counter)";
+%    }
 class="currenttab"
-HREF="<% $RT::WebPath%>/Search/Listing.html?Bookmark=<%$session{'tickets'}->FreezeLimits()|u%>&TicketsSortBy=<%$Attribute%>&TicketsSortOrder=<%$order%>&RowsPerPage=<%$session{'tickets_rows_per_page'}%>">
+HREF="<% $RT::WebPath%>/Search/Listing.html?Bookmark=<%$session{'tickets'}->FreezeLimits()|u%>&<%$ordered_fields{$Attribute}->{'INVERT'}%>&RowsPerPage=<%$session{'tickets_rows_per_page'}%>"><% loc($Header) %><%$tag%></A>
 % } else {
-HREF="<% $RT::WebPath%>/Search/Listing.html?Bookmark=<%$session{'tickets'}->FreezeLimits()|u%>&TicketsSortBy=<%$Attribute%>&TicketsSortOrder=<%$curorder%>&RowsPerPage=<%$session{'tickets_rows_per_page'}%>">
+HREF="<% $RT::WebPath%>/Search/Listing.html?Bookmark=<%$session{'tickets'}->FreezeLimits()|u%>&TicketsSortBy=<%$Attribute%>&TicketsSortOrder=ASC&RowsPerPage=<%$session{'tickets_rows_per_page'}%>"><% loc($Header) %></A>
 % }
-<% loc($Header) %>
-</A>
 % } else {
 <% loc($Header) %>
 % }
--- ./share/html/Search/Elements/PickRestriction.orig	2003-09-25 15:31:06.000000000 -0500
+++ ./share/html/Search/Elements/PickRestriction	2003-11-11 14:05:42.000000000 -0600
@@ -105,10 +105,10 @@
 							Default => $session{'tickets_rows_per_page'} || '50'
 &>
 
-<li><&|/l&>Sort results by</&> <& /Elements/SelectTicketSortBy, Name => "TicketsSortBy", 
-						     Default => $session{'tickets_sort_by'} 
+<li><&|/l&>Add sorting by</&> <& /Elements/SelectTicketSortBy, Name => "AddSortBy", 
+						     Default => "" 
 &> 
-<& /Elements/SelectSortOrder, Name => 'TicketsSortOrder', Default => $session{'tickets_sort_order'} &>
+<& /Elements/SelectSortOrder, Name => 'AddSortOrder', Default => "ASC" &>
 
 <li><input type="checkbox" name="HideResults" <%$ARGS{'HideResults'} && 'CHECKED'%>> <&|/l&>Don't show search results</&>
 <li><& /Elements/Refresh, Name => 'RefreshSearchInterval' , Default => $session{'tickets_refresh_interval'} &>
--- ./share/html/Search/Listing.html.orig	2003-09-25 15:31:06.000000000 -0500
+++ ./share/html/Search/Listing.html	2003-11-11 15:10:23.000000000 -0600
@@ -75,7 +75,27 @@
 %}
 <BR>
 <BR>
-<A HREF="<% $RT::WebPath%>/Search/Listing.html?Bookmark=<%$session{'tickets'}->FreezeLimits()|u%>&TicketsSortBy=<%$session{'tickets_sort_by'}%>&TicketsSortOrder=<%$session{'tickets_sort_order'}%>&RowsPerPage=<%$session{'tickets_rows_per_page'}%>"><&|/l&>Bookmarkable URL for this search</&></a>
+% my $bookmark_order;
+% if (@tickets_sort_by) {
+%    $bookmark_order = 'TicketsSortBy=' . join(',', @tickets_sort_by) . '&TicketsSortOrder=' . join(',', @tickets_sort_order);
+% } else {
+%    $bookmark_order = 'ClearSortBy=1';
+% }
+<A HREF="<% $RT::WebPath%>/Search/Listing.html?Bookmark=<%$session{'tickets'}->FreezeLimits()|u%>&<%$bookmark_order%>&RowsPerPage=<%$session{'tickets_rows_per_page'}%>"><&|/l&>Bookmarkable URL for this search</&></a>
+<& /Elements/TitleBoxEnd&>
+<& /Elements/TitleBoxStart, title => 'Current sort order'&>
+<A HREF="<% $RT::WebPath%>/Search/Listing.html?ClearSortBy=1">Clear sort order</a>
+<BR>
+<BR>
+% foreach my $index ( sort keys %{$session{'tickets_sort_by'}} ) {
+%  my $row = $session{'tickets_sort_by'}{$index};
+%  my $field = $row->{'FIELD'};
+%  my $order = $row->{'ORDER'};
+%  $order = ( ( $order =~ /^asc/i ) ? 'ascending' : 'descending' );
+<nobr><%$field%>, <%$order%> 
+<A HREF="<% $RT::WebPath%>/Search/Listing.html?<%$ordered_fields{$field}->{'INVERT'}%>">[invert]</a>
+<A HREF="<% $RT::WebPath%>/Search/Listing.html?DeleteSortBy=<%$index%>">[delete]</a></nobr><br>
+% }
 <& /Elements/TitleBoxEnd&>
 </TD>
 <TD>
@@ -97,8 +117,41 @@
     if ( ($ARGS{'ClearRestrictions'}) || ($ARGS{'NewSearch'}) ) {
 	    $session{'tickets'}->ClearRestrictions;
 	}	
+    if ($ARGS{'NewSearch'}) {
+	    $session{'tickets'}->OrderBy();
+    }
 }
+
+if ($ARGS{'NewSearch'}) {
+    $session{'tickets_sort_by'} = undef;
+}
+
    ProcessSearchQuery(ARGS=>\%ARGS);
+
+my %ordered_fields;
+my $counter = 1;
+my @tickets_sort_by;
+my @tickets_sort_order;
+
+foreach my $index ( sort keys %{$session{'tickets_sort_by'}} ) {
+        my $row = $session{'tickets_sort_by'}{$index};
+        my $field = $row->{'FIELD'};
+        unless ($ordered_fields{$field}) {
+                $ordered_fields{$field} = { INDEX => $index, COUNT => $counter, ORDER => $row->{'ORDER'} };
+                push(@tickets_sort_by, $field);
+                push(@tickets_sort_order, $row->{'ORDER'});
+        }
+        $counter++;
+}
+
+foreach my $index ( keys %ordered_fields ) {
+        my @order_array = @tickets_sort_order;
+        my $invertorder = ( $ordered_fields{$index}->{'ORDER'} =~ /^asc/i ) ? 'DESC' : 'ASC';
+        $order_array[$ordered_fields{$index}->{'COUNT'} - 1] = $invertorder;
+        $ordered_fields{$index}->{'INVERT'} = 'TicketsSortBy=' . join(',', @tickets_sort_by) .
+                '&TicketsSortOrder=' . join(',', @order_array);
+}
+
    $session{'tickets'}->RedoSearch();
    if ( $session{'tickets'}->DescribeRestrictions()) {
        $ticketcount = $session{tickets}->CountAll();
--- ./lib/RT/Interface/Web.pm.orig	2003-09-25 15:31:07.000000000 -0500
+++ ./lib/RT/Interface/Web.pm	2003-11-11 15:01:12.000000000 -0600
@@ -616,13 +616,48 @@
           $args{ARGS}->{'RefreshSearchInterval'};
     }
 
+    my $redo_sort = 0;
+
+    if ( $args{ARGS}->{'TicketsSortBy'} or $args{ARGS}->{'ClearSortBy'}) {
+        $session{'tickets_sort_by'} = undef;
+        $redo_sort = 1;
+    }
+
     if ( $args{ARGS}->{'TicketsSortBy'} ) {
-        $session{'tickets_sort_by'}    = $args{ARGS}->{'TicketsSortBy'};
-        $session{'tickets_sort_order'} = $args{ARGS}->{'TicketsSortOrder'};
-        $session{'tickets'}->OrderBy(
-            FIELD => $args{ARGS}->{'TicketsSortBy'},
-            ORDER => $args{ARGS}->{'TicketsSortOrder'}
-        );
+        my $sort_by_arg = $args{ARGS}->{'TicketsSortBy'};
+        my $sort_order_arg = $args{ARGS}->{'TicketsSortOrder'};
+
+        $sort_by_arg =~ s/%2C/,/ig;
+        $sort_order_arg =~ s/%2C/,/ig;
+
+        my @sort_by = split(/,/, $sort_by_arg);
+        my @sort_order = split(/,/, $sort_order_arg);
+
+        for(my $count = 0; $count <= $#sort_by; $count++) {
+                $session{'tickets_sort_by_index'}++;
+                $session{'tickets_sort_by'}{$session{'tickets_sort_by_index'}} = { FIELD => $sort_by[$count],
+                        ORDER => ($sort_order[$count] ? $sort_order[$count] : 'ASC') };
+        }
+    }
+
+    if ( $args{ARGS}->{'AddSortBy'} ) {
+        $session{'tickets_sort_by_index'}++;
+        $session{'tickets_sort_by'}{$session{'tickets_sort_by_index'}} = { FIELD => $args{ARGS}->{'AddSortBy'},
+                ORDER => ( $args{ARGS}->{'AddSortOrder'} ? $args{ARGS}->{'AddSortOrder'} : "ASC" ) };
+        $redo_sort = 1;
+    }
+
+    if ( $args{ARGS}->{'DeleteSortBy'} ) {
+        delete $session{'tickets_sort_by'}{$args{ARGS}->{'DeleteSortBy'}};
+        $redo_sort = 1;
+    }
+
+    if ( $redo_sort ) {
+        my @order_array;
+        foreach my $key ( sort keys %{$session{'tickets_sort_by'}} ) {
+                push(@order_array, $session{'tickets_sort_by'}{$key});
+        }
+        $session{'tickets'}->OrderByCols( @order_array );
     }
 
     # }}}


More information about the Rt-devel mailing list