Forum: Ruby on Rails sorting tables by columns

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
69d524565ee927f209b5dcc04f313450?d=identicon&s=25 Chris Sepic (Guest)
on 2006-01-08 22:45
What I'm trying to do is have clickable column headers that will sort
the table by that column. What I have below works, except there is only
one variable storing the sort direction for all the columns, whereas I
need a separate one for each column name.

list view:
<th><%= link_to 'Category', :action => 'list', :order =>
'categories.category' %></th>
    <th><%= link_to 'Amount', :action => 'list', :order => 'amount'
%></th>
    <th><%= link_to 'Date', :action => 'list', :order => 'date' %></th>
    <th><%= link_to 'Location', :action => 'list', :order => 'location'
%></th>
    <th><%= link_to 'Note', :action => 'list', :order => 'note' %></th>

list:

order = @params[:order] ||= 'date'

unless session[:dir]
  session[:dir] = ' asc'
end

session[:dir] = (session[:dir] == ' desc') ? ' asc' : ' desc'

@all = Activity.find(:all, :order => order + session[:dir], :include =>
:category)

I'd like the session hash to be something like:

session = {
  :dir => {:date => ' asc', :location => ' desc', :amount => ' desc'}
#etc..
}

I need to do something like session[:dir][order] but I don't know the
proper syntax. Ideas?

Thanks,
Chris
58c44a4a506d878f9a112f1d7b7cb87e?d=identicon&s=25 Jeremy Evans (Guest)
on 2006-01-08 23:30
(Received via mailing list)
On 1/8/06, Chris Sepic <chris.sepic@gmail.com> wrote:
> What I'm trying to do is have clickable column headers that will sort
> the table by that column.

Do you have an aversion to doing this with Javascript?  See
http://www.kryogenix.org/code/browser/sorttable/ for an example.

If you want to do it on the server:

@all = Activity.find(:all, :order => "#{@order}
#{session[:dir][@order.to_sym]}", :include =>
:category)
C8a634a01a2c4508360874bff7fb1a7f?d=identicon&s=25 Kevin Olbrich (olbrich)
on 2006-01-09 06:18
Chris,

I've been patching something like this together recently for my own app.
I can describe it briefly for you.

== Templates ==

In the templates I put a link much like yours into the table header.  In
my case I created a helper function that generates the link based on the
column name.  The helper also applies a CSS class of "sorted" to the
link if the sorted column is the current one.

the helper looks something like this

== application_helper file or controller_helper

def sorted_column(name,ukey = nil)
  key = ukey || name  #allows the passed parameter name to be set
                      #otherwise it uses the column name
  link_to "#{name}", :sort=>key,
    {"class"=>(key == @sort)?"sorted":"unsorted"}
end

== Controller ==

def list
  @sort = params[:sort] || session[:sort] || "default"
  session[:sort] = @sort
  @person_pages, @people = paginate :people, :order => sorted_by(@sort)
end

def sorted_by(key)
  # This is important because it prevents SQL injection and provides
default
  # behavior if naughty users change the URL.  It also keeps the URLS
clean.
  case key
    when "lastname" : "lastname, firstname"
    else "firstname, lastname"
  end
end

It isn't too difficult to set this up in your application controller
with some default settings to give all controllers this action.

** reasons not to use javascript.
If you have a lot of records, you would need to pull them all and send
them to the client to get it to properly sort.  Otherwise you would only
be sorting the 10 records it pulled the first time.

I'm typing this from memory, so expect bugs.

This whole thing could be AJAX'd too, but I haven't gotten to that yet.
This topic is locked and can not be replied to.