# encoding: utf-8 # # = Pagination Helpers # # Two handy methods for rendering pagination links above and below a list of # results in a view. See also ApplicationController and MOPaginator. # # *NOTE*: These are all included in ApplicationHelper. # # == Methods # # paginate_block:: Wrap block in appropriate pagination links. # pagination_letters:: Render the set of letters for pagination. # pagination_numbers:: Render nearby page numbers for pagination. # pagination_link:: Render a single link in above methods. # ################################################################################ module ApplicationHelper::Paginator # Wrap a block in pagination links. Includes letters if appropriate. # # <% paginate_block(@pages) do %> # <% for object in @objects %> # <% object_link(object) %>
# <% end %> # <% end %> # def paginate_block(pages, args={}, &block) letters = pagination_letters(pages, args).to_s numbers = pagination_numbers(pages, args).to_s body = capture(&block).to_s str = letters + numbers + body + numbers + letters str = '
' + str + '
' concat(str, block.binding) end # Insert letterer pagination links. # # # In controller: # def action # query = create_query(:Name) # @pages = paginate_letters(:letter, :page, 50) # @names = query.paginate(@pages, :letter_field => 'names.text_name') # end # # # In view: # <%= pagination_letters(@pages) %> # <%= pagination_numbers(@pages) %> # def pagination_letters(pages, args={}) if pages and pages.letter_arg and (pages.letter || pages.num_total > pages.num_per_page) and (!pages.used_letters or pages.used_letters.length > 1) args = args.dup args[:params] = (args[:params] || {}).dup args[:params][pages.number_arg] = nil str = %w(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z).map do |letter| if !pages.used_letters || pages.used_letters.include?(letter) pagination_link(letter, letter, pages.letter_arg, args) else letter end end.join(' ') return %() else return '' end end # Insert numbered pagination links. I've thrown out the Rails plugin # pagination_letters because it is no longer giving us enough to be worth it. # (See also pagination_letters above.) # # # In controller: # def action # query = create_query(:Name) # @pages = paginate_numbers(:page, 50) # @names = query.paginate(@pages) # end # # # In view: (it is wrapped in 'pagination' div already) # <%= pagination_numbers(@pages) %> # def pagination_numbers(pages, args={}) result = '' if pages && pages.num_pages > 1 params = args[:params] ||= {} if pages.letter_arg && pages.letter params[pages.letter_arg] = pages.letter end num = pages.num_pages arg = pages.number_arg this = pages.number this = 1 if this < 1 this = num if this > num size = args[:window_size] || 5 from = this - size to = this + size result = [] pstr = "« #{:PREV.t}" nstr = "#{:NEXT.t} »" result << pagination_link(pstr, this-1, arg, args) if this > 1 result << '|' if this > 1 result << pagination_link(1, 1, arg, args) if from > 1 result << '...' if from > 2 for n in from..to if n == this result << n elsif n > 0 && n <= num result << pagination_link(n, n, arg, args) end end result << '...' if to < num - 1 result << pagination_link(num, num, arg, args) if to < num result << '|' if this < num result << pagination_link(nstr, this+1, arg, args) if this < num result = %() end end # Render a single pagination link for paginate_numbers above. def pagination_link(label, page, arg, args) params = args[:params] || {} params[arg] = page url = h(reload_with_args(params)) if args[:anchor] url.sub!(/#.*/, '') url += '#' + args[:anchor] end link_to(label, url) end end