Mercurial > hg > soundsoftware-site
comparison lib/redmine/pagination.rb @ 1295:622f24f53b42 redmine-2.3
Update to Redmine SVN revision 11972 on 2.3-stable branch
author | Chris Cannam |
---|---|
date | Fri, 14 Jun 2013 09:02:21 +0100 |
parents | |
children | e248c7af89ec |
comparison
equal
deleted
inserted
replaced
1294:3e4c3460b6ca | 1295:622f24f53b42 |
---|---|
1 # encoding: utf-8 | |
2 # | |
3 # Redmine - project management software | |
4 # Copyright (C) 2006-2013 Jean-Philippe Lang | |
5 # | |
6 # This program is free software; you can redistribute it and/or | |
7 # modify it under the terms of the GNU General Public License | |
8 # as published by the Free Software Foundation; either version 2 | |
9 # of the License, or (at your option) any later version. | |
10 # | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU General Public License for more details. | |
15 # | |
16 # You should have received a copy of the GNU General Public License | |
17 # along with this program; if not, write to the Free Software | |
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 | |
20 module Redmine | |
21 module Pagination | |
22 class Paginator | |
23 attr_reader :item_count, :per_page, :page, :page_param | |
24 | |
25 def initialize(*args) | |
26 if args.first.is_a?(ActionController::Base) | |
27 args.shift | |
28 ActiveSupport::Deprecation.warn "Paginator no longer takes a controller instance as the first argument. Remove it from #new arguments." | |
29 end | |
30 item_count, per_page, page, page_param = *args | |
31 | |
32 @item_count = item_count | |
33 @per_page = per_page | |
34 page = (page || 1).to_i | |
35 if page < 1 | |
36 page = 1 | |
37 end | |
38 @page = page | |
39 @page_param = page_param || :page | |
40 end | |
41 | |
42 def offset | |
43 (page - 1) * per_page | |
44 end | |
45 | |
46 def first_page | |
47 if item_count > 0 | |
48 1 | |
49 end | |
50 end | |
51 | |
52 def previous_page | |
53 if page > 1 | |
54 page - 1 | |
55 end | |
56 end | |
57 | |
58 def next_page | |
59 if last_item < item_count | |
60 page + 1 | |
61 end | |
62 end | |
63 | |
64 def last_page | |
65 if item_count > 0 | |
66 (item_count - 1) / per_page + 1 | |
67 end | |
68 end | |
69 | |
70 def first_item | |
71 item_count == 0 ? 0 : (offset + 1) | |
72 end | |
73 | |
74 def last_item | |
75 l = first_item + per_page - 1 | |
76 l > item_count ? item_count : l | |
77 end | |
78 | |
79 def linked_pages | |
80 pages = [] | |
81 if item_count > 0 | |
82 pages += [first_page, page, last_page] | |
83 pages += ((page-2)..(page+2)).to_a.select {|p| p > first_page && p < last_page} | |
84 end | |
85 pages = pages.compact.uniq.sort | |
86 if pages.size > 1 | |
87 pages | |
88 else | |
89 [] | |
90 end | |
91 end | |
92 | |
93 def items_per_page | |
94 ActiveSupport::Deprecation.warn "Paginator#items_per_page will be removed. Use #per_page instead." | |
95 per_page | |
96 end | |
97 | |
98 def current | |
99 ActiveSupport::Deprecation.warn "Paginator#current will be removed. Use .offset instead of .current.offset." | |
100 self | |
101 end | |
102 end | |
103 | |
104 # Paginates the given scope or model. Returns a Paginator instance and | |
105 # the collection of objects for the current page. | |
106 # | |
107 # Options: | |
108 # :parameter name of the page parameter | |
109 # | |
110 # Examples: | |
111 # @user_pages, @users = paginate User.where(:status => 1) | |
112 # | |
113 def paginate(scope, options={}) | |
114 options = options.dup | |
115 finder_options = options.extract!( | |
116 :conditions, | |
117 :order, | |
118 :joins, | |
119 :include, | |
120 :select | |
121 ) | |
122 if scope.is_a?(Symbol) || finder_options.values.compact.any? | |
123 return deprecated_paginate(scope, finder_options, options) | |
124 end | |
125 | |
126 paginator = paginator(scope.count, options) | |
127 collection = scope.limit(paginator.per_page).offset(paginator.offset).to_a | |
128 | |
129 return paginator, collection | |
130 end | |
131 | |
132 def deprecated_paginate(arg, finder_options, options={}) | |
133 ActiveSupport::Deprecation.warn "#paginate with a Symbol and/or find options is depreceted and will be removed. Use a scope instead." | |
134 klass = arg.is_a?(Symbol) ? arg.to_s.classify.constantize : arg | |
135 scope = klass.scoped(finder_options) | |
136 paginate(scope, options) | |
137 end | |
138 | |
139 def paginator(item_count, options={}) | |
140 options.assert_valid_keys :parameter, :per_page | |
141 | |
142 page_param = options[:parameter] || :page | |
143 page = (params[page_param] || 1).to_i | |
144 per_page = options[:per_page] || per_page_option | |
145 Paginator.new(item_count, per_page, page, page_param) | |
146 end | |
147 | |
148 module Helper | |
149 include Redmine::I18n | |
150 | |
151 # Renders the pagination links for the given paginator. | |
152 # | |
153 # Options: | |
154 # :per_page_links if set to false, the "Per page" links are not rendered | |
155 # | |
156 def pagination_links_full(*args) | |
157 pagination_links_each(*args) do |text, parameters, options| | |
158 if block_given? | |
159 yield text, parameters, options | |
160 else | |
161 link_to text, params.merge(parameters), options | |
162 end | |
163 end | |
164 end | |
165 | |
166 # Yields the given block with the text and parameters | |
167 # for each pagination link and returns a string that represents the links | |
168 def pagination_links_each(paginator, count=nil, options={}, &block) | |
169 options.assert_valid_keys :per_page_links | |
170 | |
171 per_page_links = options.delete(:per_page_links) | |
172 per_page_links = false if count.nil? | |
173 page_param = paginator.page_param | |
174 | |
175 html = '' | |
176 if paginator.previous_page | |
177 # \xc2\xab(utf-8) = « | |
178 text = "\xc2\xab " + l(:label_previous) | |
179 html << yield(text, {page_param => paginator.previous_page}, :class => 'previous') + ' ' | |
180 end | |
181 | |
182 previous = nil | |
183 paginator.linked_pages.each do |page| | |
184 if previous && previous != page - 1 | |
185 html << content_tag('span', '...', :class => 'spacer') + ' ' | |
186 end | |
187 if page == paginator.page | |
188 html << content_tag('span', page.to_s, :class => 'current page') | |
189 else | |
190 html << yield(page.to_s, {page_param => page}, :class => 'page') | |
191 end | |
192 html << ' ' | |
193 previous = page | |
194 end | |
195 | |
196 if paginator.next_page | |
197 # \xc2\xbb(utf-8) = » | |
198 text = l(:label_next) + " \xc2\xbb" | |
199 html << yield(text, {page_param => paginator.next_page}, :class => 'next') + ' ' | |
200 end | |
201 | |
202 html << content_tag('span', "(#{paginator.first_item}-#{paginator.last_item}/#{paginator.item_count})", :class => 'items') + ' ' | |
203 | |
204 if per_page_links != false && links = per_page_links(paginator, &block) | |
205 html << content_tag('span', links.to_s, :class => 'per-page') | |
206 end | |
207 | |
208 html.html_safe | |
209 end | |
210 | |
211 # Renders the "Per page" links. | |
212 def per_page_links(paginator, &block) | |
213 values = per_page_options(paginator.per_page, paginator.item_count) | |
214 if values.any? | |
215 links = values.collect do |n| | |
216 if n == paginator.per_page | |
217 content_tag('span', n.to_s) | |
218 else | |
219 yield(n, :per_page => n, paginator.page_param => nil) | |
220 end | |
221 end | |
222 l(:label_display_per_page, links.join(', ')).html_safe | |
223 end | |
224 end | |
225 | |
226 def per_page_options(selected=nil, item_count=nil) | |
227 options = Setting.per_page_options_array | |
228 if item_count && options.any? | |
229 if item_count > options.first | |
230 max = options.detect {|value| value >= item_count} || item_count | |
231 else | |
232 max = item_count | |
233 end | |
234 options = options.select {|value| value <= max || value == selected} | |
235 end | |
236 if options.empty? || (options.size == 1 && options.first == selected) | |
237 [] | |
238 else | |
239 options | |
240 end | |
241 end | |
242 end | |
243 end | |
244 end |