diff options
author | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2006-12-05 20:45:04 +0000 |
---|---|---|
committer | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2006-12-05 20:45:04 +0000 |
commit | 96f83cc8f0f032554f771a59da22303cd473b878 (patch) | |
tree | 355a0d2ed653a5426c59ebf6a1fe65eba024b4d0 /app/helpers/sort_helper.rb | |
parent | eabc04d8368824965d3ac8de3fa84502e9c05d38 (diff) | |
download | redmine-96f83cc8f0f032554f771a59da22303cd473b878.tar.gz redmine-96f83cc8f0f032554f771a59da22303cd473b878.zip |
trunk moved from /trunk/redmine to /trunk
git-svn-id: http://redmine.rubyforge.org/svn/trunk@67 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app/helpers/sort_helper.rb')
-rw-r--r-- | app/helpers/sort_helper.rb | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/app/helpers/sort_helper.rb b/app/helpers/sort_helper.rb new file mode 100644 index 000000000..04a84c8e4 --- /dev/null +++ b/app/helpers/sort_helper.rb @@ -0,0 +1,160 @@ +# Helpers to sort tables using clickable column headers. +# +# Author: Stuart Rackham <srackham@methods.co.nz>, March 2005. +# License: This source code is released under the MIT license. +# +# - Consecutive clicks toggle the column's sort order. +# - Sort state is maintained by a session hash entry. +# - Icon image identifies sort column and state. +# - Typically used in conjunction with the Pagination module. +# +# Example code snippets: +# +# Controller: +# +# helper :sort +# include SortHelper +# +# def list +# sort_init 'last_name' +# sort_update +# @items = Contact.find_all nil, sort_clause +# end +# +# Controller (using Pagination module): +# +# helper :sort +# include SortHelper +# +# def list +# sort_init 'last_name' +# sort_update +# @contact_pages, @items = paginate :contacts, +# :order_by => sort_clause, +# :per_page => 10 +# end +# +# View (table header in list.rhtml): +# +# <thead> +# <tr> +# <%= sort_header_tag('id', :title => 'Sort by contact ID') %> +# <%= sort_header_tag('last_name', :caption => 'Name') %> +# <%= sort_header_tag('phone') %> +# <%= sort_header_tag('address', :width => 200) %> +# </tr> +# </thead> +# +# - The ascending and descending sort icon images are sort_asc.png and +# sort_desc.png and reside in the application's images directory. +# - Introduces instance variables: @sort_name, @sort_default. +# - Introduces params :sort_key and :sort_order. +# +module SortHelper + + # Initializes the default sort column (default_key) and sort order + # (default_order). + # + # - default_key is a column attribute name. + # - default_order is 'asc' or 'desc'. + # - name is the name of the session hash entry that stores the sort state, + # defaults to '<controller_name>_sort'. + # + def sort_init(default_key, default_order='asc', name=nil) + @sort_name = name || @params[:controller] + @params[:action] + '_sort' + @sort_default = {:key => default_key, :order => default_order} + end + + # Updates the sort state. Call this in the controller prior to calling + # sort_clause. + # + def sort_update() + if @params[:sort_key] + sort = {:key => @params[:sort_key], :order => @params[:sort_order]} + elsif @session[@sort_name] + sort = @session[@sort_name] # Previous sort. + else + sort = @sort_default + end + @session[@sort_name] = sort + end + + # Returns an SQL sort clause corresponding to the current sort state. + # Use this to sort the controller's table items collection. + # + def sort_clause() + @session[@sort_name][:key] + ' ' + @session[@sort_name][:order] + end + + # Returns a link which sorts by the named column. + # + # - column is the name of an attribute in the sorted record collection. + # - The optional caption explicitly specifies the displayed link text. + # - A sort icon image is positioned to the right of the sort link. + # + def sort_link(column, caption=nil) + key, order = @session[@sort_name][:key], @session[@sort_name][:order] + if key == column + if order.downcase == 'asc' + icon = 'sort_asc' + order = 'desc' + else + icon = 'sort_desc' + order = 'asc' + end + else + icon = nil + order = 'desc' # changed for desc order by default + end + caption = titleize(Inflector::humanize(column)) unless caption + params = {:params => {:sort_key => column, :sort_order => order}} + link_to_remote(caption, + {:update => "content", :url => { :sort_key => column, :sort_order => order}}, + {:href => url_for(:params => { :sort_key => column, :sort_order => order})}) + + (icon ? nbsp(2) + image_tag(icon) : '') + end + + # Returns a table header <th> tag with a sort link for the named column + # attribute. + # + # Options: + # :caption The displayed link name (defaults to titleized column name). + # :title The tag's 'title' attribute (defaults to 'Sort by :caption'). + # + # Other options hash entries generate additional table header tag attributes. + # + # Example: + # + # <%= sort_header_tag('id', :title => 'Sort by contact ID', :width => 40) %> + # + # Renders: + # + # <th title="Sort by contact ID" width="40"> + # <a href="/contact/list?sort_order=desc&sort_key=id">Id</a> + # <img alt="Sort_asc" src="/images/sort_asc.png" /> + # </th> + # + def sort_header_tag(column, options = {}) + if options[:caption] + caption = options[:caption] + options.delete(:caption) + else + caption = titleize(Inflector::humanize(column)) + end + options[:title]= "Sort by #{caption}" unless options[:title] + content_tag('th', sort_link(column, caption), options) + end + + private + + # Return n non-breaking spaces. + def nbsp(n) + ' ' * n + end + + # Return capitalized title. + def titleize(title) + title.split.map {|w| w.capitalize }.join(' ') + end + +end |