Sort within a Search 2 comments

Posted by robon May 29, 2007

Check out the following screen shot of a queue view from a project I'm working on:

What this is showing is that sorting by a column is preserved across the pages of a result set (the screen shot shows the third page). In other words, if I sort by a column and there is pagination, I want that sort preserved as I flip through the pages of the result. It's just about what you would expect to happen, but often this feature is neglected.

The way I chose to do this was to pass information about the current sort (direction, column) along with the pagination links. (Conversely, I was passing the pagination page information along to the search before I realize that made no sense! :) Anyway, here's the view helper that piggie-backs sort information along with each of the pagination links:

app/helpers/review_helper.rb:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  def review_log_pagination

    search_opts = { :search_str => params[:search_str],
                    :search_field => params[:search_field],
                    :search_method => params[:search_method],
                    :sort_order => @sort_order,
                    :sort_col => params[:sort_col],
                    :old_sort_col => params[:sort_col] }


    string = <<END_OF_STRING

      #{ ( link_to '[previous]', { :page => @review_log_pages.current.previous }.merge(search_opts) ) if @review_log_pages.current.previous }

      #{ pagination_links( @review_log_pages, { :params => search_opts }, { :window_size => 10 } ) }

      #{ ( link_to '[next]', { :page => @review_log_pages.current.next }.merge(search_opts) ) if @review_log_pages.current.next }

END_OF_STRING

  end

There are two views that use this helper. If it was to be used anywhere else, I could make it an application level helper but for now, this works. I believe there are also JavaScript/CSS column sorting solutions, but some of the sorting logic that's involved was a lot easier in Ruby.

I'm open to any ideas about how to make this smoother. Even though it works pretty well, there are references to a lot of outerscope variables which could make changes down the line more work.

As an aside, here's how Hash#merge works:

orsini@MacOrsini:~
$ irb
irb(main):001:0> { :one => 1, :two => 2 }
=> {:one=>1, :two=>2}
irb(main):002:0> third = { :three => 3 }
=> {:three=>3}
irb(main):003:0> { :one => 1, :two => 2 }.merge(third)
=> {:one=>1, :two=>2, :three=>3}