1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
# frozen_string_literal: true
# Helpers to sort tables using clickable column headers.
#
# Author: Stuart Rackham <srackham@methods.co.nz>, March 2005.
# Jean-Philippe Lang, 2009
# 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.
# - CSS classes identify 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 %w(first_name last_name)
# @items = Contact.find_all nil, sort_clause
# end
#
# Controller (using Pagination module):
#
# helper :sort
# include SortHelper
#
# def list
# sort_init 'last_name'
# sort_update %w(first_name last_name)
# @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>
#
# - Introduces instance variables: @sort_default, @sort_criteria
# - Introduces param :sort
#
module SortHelper
def sort_name
controller_name + '_' + action_name + '_sort'
end
# Initializes the default sort.
# Examples:
#
# sort_init 'name'
# sort_init 'id', 'desc'
# sort_init ['name', ['id', 'desc']]
# sort_init [['name', 'desc'], ['id', 'desc']]
#
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
end
# Updates the sort state. Call this in the controller prior to calling
# sort_clause.
# - criteria can be either an array or a hash of allowed keys
#
def sort_update(criteria, sort_name=nil)
sort_name ||= self.sort_name
@sort_criteria = Redmine::SortCriteria.new(params[:sort] || session[sort_name] || @sort_default)
@sortable_columns = criteria
session[sort_name] = @sort_criteria.to_param
end
# Clears the sort criteria session data
#
def sort_clear
session[sort_name] = nil
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
@sort_criteria.sort_clause(@sortable_columns)
end
def sort_criteria
@sort_criteria
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.
# - 2 CSS classes reflect the state of the link: sort and asc or desc
#
def sort_link(column, caption, default_order)
css, order = nil, default_order
if column.to_s == @sort_criteria.first_key
if @sort_criteria.first_asc?
css = 'sort asc icon icon-sorted-desc'
icon = 'angle-up'
order = 'desc'
else
css = 'sort desc icon icon-sorted-asc'
icon = 'angle-down'
order = 'asc'
end
end
caption = column.to_s.humanize unless caption
sort_options = {:sort => @sort_criteria.add(column.to_s, order).to_param}
link_to(sprite_icon(icon, caption), { :params => request.query_parameters.merge(sort_options)}, :class => css)
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 = {})
caption = options.delete(:caption) || column.to_s.humanize
default_order = options.delete(:default_order) || 'asc'
options[:title] = l(:label_sort_by, "\"#{caption}\"") unless options[:title]
content_tag('th', sort_link(column, caption, default_order), options)
end
# Returns the css classes for the current sort order
#
# Example:
#
# sort_css_classes
# # => "sort-by-created-on sort-desc"
def sort_css_classes
if @sort_criteria.first_key
"sort-by-#{@sort_criteria.first_key.to_s.dasherize} sort-#{@sort_criteria.first_asc? ? 'asc' : 'desc'}"
end
end
end
|