##// END OF EJS Templates
Allow referencing issue numbers in brackets. This style is used by other...
Allow referencing issue numbers in brackets. This style is used by other bug trackers. Examples: * "[#nnn] Worked on this issue" * "[#nnn, #mmm] Worked on these" * "[#nnn #mmm] Working some more" git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2854 e93f8b46-1217-0410-a6f0-8f06a7374b81

File last commit:

r2508:1852d907ba5f
r2749:609faba6a3d3
Show More
sort_helper.rb
226 lines | 6.1 KiB | text/x-ruby | RubyLexer
Jean-Philippe Lang
Initial commit...
r2 # Helpers to sort tables using clickable column headers.
#
# Author: Stuart Rackham <srackham@methods.co.nz>, March 2005.
Jean-Philippe Lang
SortHelper refactoring:...
r2503 # Jean-Philippe Lang, 2009
Jean-Philippe Lang
Initial commit...
r2 # 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.
Jean-Philippe Lang
SortHelper refactoring:...
r2503 # - CSS classes identify sort column and state.
Jean-Philippe Lang
Initial commit...
r2 # - Typically used in conjunction with the Pagination module.
#
# Example code snippets:
#
# Controller:
#
# helper :sort
# include SortHelper
#
# def list
# sort_init 'last_name'
Jean-Philippe Lang
Fixes SortHelper examples (#2950)....
r2508 # sort_update %w(first_name last_name)
Jean-Philippe Lang
Initial commit...
r2 # @items = Contact.find_all nil, sort_clause
# end
#
# Controller (using Pagination module):
#
# helper :sort
# include SortHelper
#
# def list
# sort_init 'last_name'
Jean-Philippe Lang
Fixes SortHelper examples (#2950)....
r2508 # sort_update %w(first_name last_name)
Jean-Philippe Lang
Initial commit...
r2 # @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>
#
Jean-Philippe Lang
SortHelper refactoring:...
r2503 # - Introduces instance variables: @sort_default, @sort_criteria
# - Introduces param :sort
Jean-Philippe Lang
Initial commit...
r2 #
Jean-Philippe Lang
SortHelper refactoring:...
r2503
Jean-Philippe Lang
Initial commit...
r2 module SortHelper
Jean-Philippe Lang
SortHelper refactoring:...
r2503 class SortCriteria
def initialize
@criteria = []
end
def available_criteria=(criteria)
unless criteria.is_a?(Hash)
criteria = criteria.inject({}) {|h,k| h[k] = k; h}
end
@available_criteria = criteria
end
def from_param(param)
@criteria = param.to_s.split(',').collect {|s| s.split(':')[0..1]}
normalize!
end
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 def criteria=(arg)
@criteria = arg
normalize!
end
Jean-Philippe Lang
SortHelper refactoring:...
r2503 def to_param
@criteria.collect {|k,o| k + (o ? '' : ':desc')}.join(',')
end
def to_sql
sql = @criteria.collect do |k,o|
if s = @available_criteria[k]
(o ? s.to_a : s.to_a.collect {|c| "#{c} DESC"}).join(', ')
end
end.compact.join(', ')
sql.blank? ? nil : sql
end
def add!(key, asc)
@criteria.delete_if {|k,o| k == key}
@criteria = [[key, asc]] + @criteria
normalize!
end
def add(*args)
r = self.class.new.from_param(to_param)
r.add!(*args)
r
end
def first_key
@criteria.first && @criteria.first.first
end
def first_asc?
@criteria.first && @criteria.first.last
end
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 def empty?
@criteria.empty?
end
Jean-Philippe Lang
SortHelper refactoring:...
r2503 private
def normalize!
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 @criteria ||= []
@criteria = @criteria.collect {|s| s = s.to_a; [s.first, (s.last == false || s.last == 'desc') ? false : true]}
Jean-Philippe Lang
SortHelper refactoring:...
r2503 @criteria = @criteria.select {|k,o| @available_criteria.has_key?(k)} if @available_criteria
@criteria.slice!(3)
self
end
end
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504
def sort_name
controller_name + '_' + action_name + '_sort'
end
Jean-Philippe Lang
Initial commit...
r2
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 # Initializes the default sort.
# Examples:
#
# sort_init 'name'
# sort_init 'id', 'desc'
# sort_init ['name', ['id', 'desc']]
# sort_init [['name', 'desc'], ['id', 'desc']]
Jean-Philippe Lang
Initial commit...
r2 #
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 def sort_init(*args)
case args.size
when 1
@sort_default = args.first.is_a?(Array) ? args.first : [[args.first]]
when 2
@sort_default = [[args.first, args.last]]
else
raise ArgumentError
end
Jean-Philippe Lang
Initial commit...
r2 end
# Updates the sort state. Call this in the controller prior to calling
# sort_clause.
Jean-Philippe Lang
SortHelper refactoring:...
r2503 # - criteria can be either an array or a hash of allowed keys
#
def sort_update(criteria)
@sort_criteria = SortCriteria.new
@sort_criteria.available_criteria = criteria
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 @sort_criteria.from_param(params[:sort] || session[sort_name])
@sort_criteria.criteria = @sort_default if @sort_criteria.empty?
Jean-Philippe Lang
SortHelper refactoring:...
r2503 session[sort_name] = @sort_criteria.to_param
Jean-Philippe Lang
Initial commit...
r2 end
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504
# Clears the sort criteria session data
#
def sort_clear
session[sort_name] = nil
end
Jean-Philippe Lang
Initial commit...
r2
# Returns an SQL sort clause corresponding to the current sort state.
# Use this to sort the controller's table items collection.
#
def sort_clause()
Jean-Philippe Lang
SortHelper refactoring:...
r2503 @sort_criteria.to_sql
Jean-Philippe Lang
Initial commit...
r2 end
# Returns a link which sorts by the named column.
#
# - column is the name of an attribute in the sorted record collection.
Jean-Philippe Lang
SortHelper refactoring:...
r2503 # - the optional caption explicitly specifies the displayed link text.
# - 2 CSS classes reflect the state of the link: sort and asc or desc
Jean-Philippe Lang
Initial commit...
r2 #
Jean-Philippe Lang
More appropriate default sort order on sortable columns....
r1107 def sort_link(column, caption, default_order)
Jean-Philippe Lang
SortHelper refactoring:...
r2503 css, order = nil, default_order
if column.to_s == @sort_criteria.first_key
if @sort_criteria.first_asc?
css = 'sort asc'
Jean-Philippe Lang
Initial commit...
r2 order = 'desc'
else
Jean-Philippe Lang
SortHelper refactoring:...
r2503 css = 'sort desc'
Jean-Philippe Lang
Initial commit...
r2 order = 'asc'
end
end
Jean-Philippe Lang
SortHelper refactoring:...
r2503 caption = column.to_s.humanize unless caption
Jean-Philippe Lang
Quick fix for:...
r403
Jean-Philippe Lang
SortHelper refactoring:...
r2503 sort_options = { :sort => @sort_criteria.add(column.to_s, order).to_param }
Jean-Philippe Lang
Adds date range filter and pagination on time entries detail view (closes #434)....
r1159 # don't reuse params if filters are present
url_options = params.has_key?(:set_filter) ? sort_options : params.merge(sort_options)
Jean-Philippe Lang
Quick fix for:...
r403
Jean-Philippe Lang
SortHelper refactoring:...
r2503 # Add project_id to url_options
Eric Davis
Fixes Issue sorting in a project, broken by #2317...
r2322 url_options = url_options.merge(:project_id => params[:project_id]) if params.has_key?(:project_id)
Jean-Philippe Lang
SortHelper refactoring:...
r2503
Jean-Philippe Lang
ajaxified paginators...
r31 link_to_remote(caption,
Eric Davis
Converted routing and urls to follow the Rails REST convention....
r2315 {:update => "content", :url => url_options, :method => :get},
Jean-Philippe Lang
SortHelper refactoring:...
r2503 {:href => url_for(url_options),
:class => css})
Jean-Philippe Lang
Initial commit...
r2 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) %>
#
def sort_header_tag(column, options = {})
Jean-Philippe Lang
SortHelper refactoring:...
r2503 caption = options.delete(:caption) || column.to_s.humanize
Jean-Philippe Lang
More appropriate default sort order on sortable columns....
r1107 default_order = options.delete(:default_order) || 'asc'
Jean-Philippe Lang
SortHelper refactoring:...
r2503 options[:title] = l(:label_sort_by, "\"#{caption}\"") unless options[:title]
Jean-Philippe Lang
More appropriate default sort order on sortable columns....
r1107 content_tag('th', sort_link(column, caption, default_order), options)
Jean-Philippe Lang
Initial commit...
r2 end
end
Jean-Philippe Lang
SortHelper refactoring:...
r2503