##// END OF EJS Templates
Fixes Issue sorting in a project, broken by #2317...
Eric Davis -
r2322:2fc789704439
parent child
Show More
@@ -1,168 +1,171
1 1 # Helpers to sort tables using clickable column headers.
2 2 #
3 3 # Author: Stuart Rackham <srackham@methods.co.nz>, March 2005.
4 4 # License: This source code is released under the MIT license.
5 5 #
6 6 # - Consecutive clicks toggle the column's sort order.
7 7 # - Sort state is maintained by a session hash entry.
8 8 # - Icon image identifies sort column and state.
9 9 # - Typically used in conjunction with the Pagination module.
10 10 #
11 11 # Example code snippets:
12 12 #
13 13 # Controller:
14 14 #
15 15 # helper :sort
16 16 # include SortHelper
17 17 #
18 18 # def list
19 19 # sort_init 'last_name'
20 20 # sort_update
21 21 # @items = Contact.find_all nil, sort_clause
22 22 # end
23 23 #
24 24 # Controller (using Pagination module):
25 25 #
26 26 # helper :sort
27 27 # include SortHelper
28 28 #
29 29 # def list
30 30 # sort_init 'last_name'
31 31 # sort_update
32 32 # @contact_pages, @items = paginate :contacts,
33 33 # :order_by => sort_clause,
34 34 # :per_page => 10
35 35 # end
36 36 #
37 37 # View (table header in list.rhtml):
38 38 #
39 39 # <thead>
40 40 # <tr>
41 41 # <%= sort_header_tag('id', :title => 'Sort by contact ID') %>
42 42 # <%= sort_header_tag('last_name', :caption => 'Name') %>
43 43 # <%= sort_header_tag('phone') %>
44 44 # <%= sort_header_tag('address', :width => 200) %>
45 45 # </tr>
46 46 # </thead>
47 47 #
48 48 # - The ascending and descending sort icon images are sort_asc.png and
49 49 # sort_desc.png and reside in the application's images directory.
50 50 # - Introduces instance variables: @sort_name, @sort_default.
51 51 # - Introduces params :sort_key and :sort_order.
52 52 #
53 53 module SortHelper
54 54
55 55 # Initializes the default sort column (default_key) and sort order
56 56 # (default_order).
57 57 #
58 58 # - default_key is a column attribute name.
59 59 # - default_order is 'asc' or 'desc'.
60 60 # - name is the name of the session hash entry that stores the sort state,
61 61 # defaults to '<controller_name>_sort'.
62 62 #
63 63 def sort_init(default_key, default_order='asc', name=nil)
64 64 @sort_name = name || params[:controller] + params[:action] + '_sort'
65 65 @sort_default = {:key => default_key, :order => default_order}
66 66 end
67 67
68 68 # Updates the sort state. Call this in the controller prior to calling
69 69 # sort_clause.
70 70 # sort_keys can be either an array or a hash of allowed keys
71 71 def sort_update(sort_keys)
72 72 sort_key = params[:sort_key]
73 73 sort_key = nil unless (sort_keys.is_a?(Array) ? sort_keys.include?(sort_key) : sort_keys[sort_key])
74 74
75 75 sort_order = (params[:sort_order] == 'desc' ? 'DESC' : 'ASC')
76 76
77 77 if sort_key
78 78 sort = {:key => sort_key, :order => sort_order}
79 79 elsif session[@sort_name]
80 80 sort = session[@sort_name] # Previous sort.
81 81 else
82 82 sort = @sort_default
83 83 end
84 84 session[@sort_name] = sort
85 85
86 86 sort_column = (sort_keys.is_a?(Hash) ? sort_keys[sort[:key]] : sort[:key])
87 87 @sort_clause = (sort_column.blank? ? nil : "#{sort_column} #{sort[:order]}")
88 88 end
89 89
90 90 # Returns an SQL sort clause corresponding to the current sort state.
91 91 # Use this to sort the controller's table items collection.
92 92 #
93 93 def sort_clause()
94 94 @sort_clause
95 95 end
96 96
97 97 # Returns a link which sorts by the named column.
98 98 #
99 99 # - column is the name of an attribute in the sorted record collection.
100 100 # - The optional caption explicitly specifies the displayed link text.
101 101 # - A sort icon image is positioned to the right of the sort link.
102 102 #
103 103 def sort_link(column, caption, default_order)
104 104 key, order = session[@sort_name][:key], session[@sort_name][:order]
105 105 if key == column
106 106 if order.downcase == 'asc'
107 107 icon = 'sort_asc.png'
108 108 order = 'desc'
109 109 else
110 110 icon = 'sort_desc.png'
111 111 order = 'asc'
112 112 end
113 113 else
114 114 icon = nil
115 115 order = default_order
116 116 end
117 117 caption = titleize(Inflector::humanize(column)) unless caption
118 118
119 119 sort_options = { :sort_key => column, :sort_order => order }
120 120 # don't reuse params if filters are present
121 121 url_options = params.has_key?(:set_filter) ? sort_options : params.merge(sort_options)
122 122
123 # Add project_id to url_options
124 url_options = url_options.merge(:project_id => params[:project_id]) if params.has_key?(:project_id)
125
123 126 link_to_remote(caption,
124 127 {:update => "content", :url => url_options, :method => :get},
125 128 {:href => url_for(url_options)}) +
126 129 (icon ? nbsp(2) + image_tag(icon) : '')
127 130 end
128 131
129 132 # Returns a table header <th> tag with a sort link for the named column
130 133 # attribute.
131 134 #
132 135 # Options:
133 136 # :caption The displayed link name (defaults to titleized column name).
134 137 # :title The tag's 'title' attribute (defaults to 'Sort by :caption').
135 138 #
136 139 # Other options hash entries generate additional table header tag attributes.
137 140 #
138 141 # Example:
139 142 #
140 143 # <%= sort_header_tag('id', :title => 'Sort by contact ID', :width => 40) %>
141 144 #
142 145 # Renders:
143 146 #
144 147 # <th title="Sort by contact ID" width="40">
145 148 # <a href="/contact/list?sort_order=desc&amp;sort_key=id">Id</a>
146 149 # &nbsp;&nbsp;<img alt="Sort_asc" src="/images/sort_asc.png" />
147 150 # </th>
148 151 #
149 152 def sort_header_tag(column, options = {})
150 153 caption = options.delete(:caption) || titleize(Inflector::humanize(column))
151 154 default_order = options.delete(:default_order) || 'asc'
152 155 options[:title]= l(:label_sort_by, "\"#{caption}\"") unless options[:title]
153 156 content_tag('th', sort_link(column, caption, default_order), options)
154 157 end
155 158
156 159 private
157 160
158 161 # Return n non-breaking spaces.
159 162 def nbsp(n)
160 163 '&nbsp;' * n
161 164 end
162 165
163 166 # Return capitalized title.
164 167 def titleize(title)
165 168 title.split.map {|w| w.capitalize }.join(' ')
166 169 end
167 170
168 171 end
General Comments 0
You need to be logged in to leave comments. Login now