pagination_helper.rb
135 lines
| 5.9 KiB
| text/x-ruby
|
RubyLexer
|
r962 | module ActionView | ||
module Helpers | ||||
# Provides methods for linking to ActionController::Pagination objects using a simple generator API. You can optionally | ||||
# also build your links manually using ActionView::Helpers::AssetHelper#link_to like so: | ||||
# | ||||
# <%= link_to "Previous page", { :page => paginator.current.previous } if paginator.current.previous %> | ||||
# <%= link_to "Next page", { :page => paginator.current.next } if paginator.current.next %> | ||||
module PaginationHelper | ||||
unless const_defined?(:DEFAULT_OPTIONS) | ||||
DEFAULT_OPTIONS = { | ||||
:name => :page, | ||||
:window_size => 2, | ||||
:always_show_anchors => true, | ||||
:link_to_current_page => false, | ||||
:params => {} | ||||
} | ||||
end | ||||
# Creates a basic HTML link bar for the given +paginator+. Links will be created | ||||
# for the next and/or previous page and for a number of other pages around the current | ||||
# pages position. The +html_options+ hash is passed to +link_to+ when the links are created. | ||||
# | ||||
# ==== Options | ||||
# <tt>:name</tt>:: the routing name for this paginator | ||||
# (defaults to +page+) | ||||
# <tt>:prefix</tt>:: prefix for pagination links | ||||
# (i.e. Older Pages: 1 2 3 4) | ||||
# <tt>:suffix</tt>:: suffix for pagination links | ||||
# (i.e. 1 2 3 4 <- Older Pages) | ||||
# <tt>:window_size</tt>:: the number of pages to show around | ||||
# the current page (defaults to <tt>2</tt>) | ||||
# <tt>:always_show_anchors</tt>:: whether or not the first and last | ||||
# pages should always be shown | ||||
# (defaults to +true+) | ||||
# <tt>:link_to_current_page</tt>:: whether or not the current page | ||||
# should be linked to (defaults to | ||||
# +false+) | ||||
# <tt>:params</tt>:: any additional routing parameters | ||||
# for page URLs | ||||
# | ||||
# ==== Examples | ||||
# # We'll assume we have a paginator setup in @person_pages... | ||||
# | ||||
# pagination_links(@person_pages) | ||||
# # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a> ... <a href="/?page=10/">10</a> | ||||
# | ||||
# pagination_links(@person_pages, :link_to_current_page => true) | ||||
# # => <a href="/?page=1/">1</a> <a href="/?page=2/">2</a> <a href="/?page=3/">3</a> ... <a href="/?page=10/">10</a> | ||||
# | ||||
# pagination_links(@person_pages, :always_show_anchors => false) | ||||
# # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a> | ||||
# | ||||
# pagination_links(@person_pages, :window_size => 1) | ||||
# # => 1 <a href="/?page=2/">2</a> ... <a href="/?page=10/">10</a> | ||||
# | ||||
# pagination_links(@person_pages, :params => { :viewer => "flash" }) | ||||
# # => 1 <a href="/?page=2&viewer=flash/">2</a> <a href="/?page=3&viewer=flash/">3</a> ... | ||||
# # <a href="/?page=10&viewer=flash/">10</a> | ||||
def pagination_links(paginator, options={}, html_options={}) | ||||
name = options[:name] || DEFAULT_OPTIONS[:name] | ||||
params = (options[:params] || DEFAULT_OPTIONS[:params]).clone | ||||
prefix = options[:prefix] || '' | ||||
suffix = options[:suffix] || '' | ||||
pagination_links_each(paginator, options, prefix, suffix) do |n| | ||||
params[name] = n | ||||
link_to(n.to_s, params, html_options) | ||||
end | ||||
end | ||||
# Iterate through the pages of a given +paginator+, invoking a | ||||
# block for each page number that needs to be rendered as a link. | ||||
# | ||||
# ==== Options | ||||
# <tt>:window_size</tt>:: the number of pages to show around | ||||
# the current page (defaults to +2+) | ||||
# <tt>:always_show_anchors</tt>:: whether or not the first and last | ||||
# pages should always be shown | ||||
# (defaults to +true+) | ||||
# <tt>:link_to_current_page</tt>:: whether or not the current page | ||||
# should be linked to (defaults to | ||||
# +false+) | ||||
# | ||||
# ==== Example | ||||
# # Turn paginated links into an Ajax call | ||||
# pagination_links_each(paginator, page_options) do |link| | ||||
# options = { :url => {:action => 'list'}, :update => 'results' } | ||||
# html_options = { :href => url_for(:action => 'list') } | ||||
# | ||||
# link_to_remote(link.to_s, options, html_options) | ||||
# end | ||||
def pagination_links_each(paginator, options, prefix = nil, suffix = nil) | ||||
options = DEFAULT_OPTIONS.merge(options) | ||||
link_to_current_page = options[:link_to_current_page] | ||||
always_show_anchors = options[:always_show_anchors] | ||||
current_page = paginator.current_page | ||||
window_pages = current_page.window(options[:window_size]).pages | ||||
return if window_pages.length <= 1 unless link_to_current_page | ||||
first, last = paginator.first, paginator.last | ||||
html = '' | ||||
html << prefix if prefix | ||||
if always_show_anchors and not (wp_first = window_pages[0]).first? | ||||
html << yield(first.number) | ||||
html << ' ... ' if wp_first.number - first.number > 1 | ||||
html << ' ' | ||||
end | ||||
window_pages.each do |page| | ||||
if current_page == page && !link_to_current_page | ||||
html << page.number.to_s | ||||
else | ||||
html << yield(page.number) | ||||
end | ||||
html << ' ' | ||||
end | ||||
if always_show_anchors and not (wp_last = window_pages[-1]).last? | ||||
html << ' ... ' if last.number - wp_last.number > 1 | ||||
html << yield(last.number) | ||||
end | ||||
html << suffix if suffix | ||||
html | ||||
end | ||||
end # PaginationHelper | ||||
end # Helpers | ||||
end # ActionView | ||||