3     # Provides methods for linking to ActionController::Pagination objects using a simple generator API.  You can optionally
 
   4     # also build your links manually using ActionView::Helpers::AssetHelper#link_to like so:
 
   6     # <%= link_to "Previous page", { :page => paginator.current.previous } if paginator.current.previous %>
 
   7     # <%= link_to "Next page", { :page => paginator.current.next } if paginator.current.next %>
 
   8     module PaginationHelper
 
   9       unless const_defined?(:DEFAULT_OPTIONS)
 
  13           :always_show_anchors => true,
 
  14           :link_to_current_page => false,
 
  19       # Creates a basic HTML link bar for the given +paginator+.  Links will be created
 
  20       # for the next and/or previous page and for a number of other pages around the current
 
  21       # pages position. The +html_options+ hash is passed to +link_to+ when the links are created.
 
  24       # <tt>:name</tt>::                 the routing name for this paginator
 
  25       #                                  (defaults to +page+)
 
  26       # <tt>:prefix</tt>::               prefix for pagination links
 
  27       #                                  (i.e. Older Pages: 1 2 3 4)
 
  28       # <tt>:suffix</tt>::               suffix for pagination links
 
  29       #                                  (i.e. 1 2 3 4 <- Older Pages)
 
  30       # <tt>:window_size</tt>::          the number of pages to show around
 
  31       #                                  the current page (defaults to <tt>2</tt>)
 
  32       # <tt>:always_show_anchors</tt>::  whether or not the first and last
 
  33       #                                  pages should always be shown
 
  34       #                                  (defaults to +true+)
 
  35       # <tt>:link_to_current_page</tt>:: whether or not the current page
 
  36       #                                  should be linked to (defaults to
 
  38       # <tt>:params</tt>::               any additional routing parameters
 
  42       #  # We'll assume we have a paginator setup in @person_pages...
 
  44       #  pagination_links(@person_pages)
 
  45       #  # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a>  ... <a href="/?page=10/">10</a>
 
  47       #  pagination_links(@person_pages, :link_to_current_page => true)
 
  48       #  # => <a href="/?page=1/">1</a> <a href="/?page=2/">2</a> <a href="/?page=3/">3</a>  ... <a href="/?page=10/">10</a>
 
  50       #  pagination_links(@person_pages, :always_show_anchors => false)
 
  51       #  # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a>
 
  53       #  pagination_links(@person_pages, :window_size => 1)
 
  54       #  # => 1 <a href="/?page=2/">2</a>  ... <a href="/?page=10/">10</a>
 
  56       #  pagination_links(@person_pages, :params => { :viewer => "flash" })
 
  57       #  # => 1 <a href="/?page=2&viewer=flash/">2</a> <a href="/?page=3&viewer=flash/">3</a>  ...
 
  58       #  #    <a href="/?page=10&viewer=flash/">10</a>
 
  59       def pagination_links(paginator, options = {}, html_options = {})
 
  60         name = options[:name] || DEFAULT_OPTIONS[:name]
 
  61         params = (options[:params] || DEFAULT_OPTIONS[:params]).clone
 
  63         prefix = options[:prefix] || ""
 
  64         suffix = options[:suffix] || ""
 
  66         pagination_links_each(paginator, options, prefix, suffix) do |n|
 
  68           link_to(n.to_s, params, html_options)
 
  72       # Iterate through the pages of a given +paginator+, invoking a
 
  73       # block for each page number that needs to be rendered as a link.
 
  76       # <tt>:window_size</tt>::          the number of pages to show around
 
  77       #                                  the current page (defaults to +2+)
 
  78       # <tt>:always_show_anchors</tt>::  whether or not the first and last
 
  79       #                                  pages should always be shown
 
  80       #                                  (defaults to +true+)
 
  81       # <tt>:link_to_current_page</tt>:: whether or not the current page
 
  82       #                                  should be linked to (defaults to
 
  86       #  # Turn paginated links into an Ajax call
 
  87       #  pagination_links_each(paginator, page_options) do |link|
 
  88       #    options = { :url => {:action => 'list'}, :update => 'results' }
 
  89       #    html_options = { :href => url_for(:action => 'list') }
 
  91       #    link_to_remote(link.to_s, options, html_options)
 
  93       def pagination_links_each(paginator, options, prefix = nil, suffix = nil)
 
  94         options = DEFAULT_OPTIONS.merge(options)
 
  95         link_to_current_page = options[:link_to_current_page]
 
  96         always_show_anchors = options[:always_show_anchors]
 
  98         current_page = paginator.current_page
 
  99         window_pages = current_page.window(options[:window_size]).pages
 
 100         return unless link_to_current_page || window_pages.length > 1
 
 102         first = paginator.first
 
 103         last = paginator.last
 
 107         html << prefix if prefix
 
 109         if always_show_anchors && !(wp_first = window_pages[0]).first?
 
 110           html << yield(first.number)
 
 111           html << " ... " if wp_first.number - first.number > 1
 
 115         window_pages.each do |page|
 
 116           html << if current_page == page && !link_to_current_page
 
 124         if always_show_anchors && !(wp_last = window_pages[-1]).last?
 
 125           html << " ... " if last.number - wp_last.number > 1
 
 126           html << yield(last.number)
 
 129         html << suffix if suffix
 
 134       def pagination_items(paginator, options)
 
 135         options = DEFAULT_OPTIONS.merge(options)
 
 136         link_to_current_page = options[:link_to_current_page]
 
 137         always_show_anchors = options[:always_show_anchors]
 
 139         current_page = paginator.current_page
 
 140         window_pages = current_page.window(options[:window_size]).pages
 
 142         first = paginator.first
 
 143         last = paginator.last
 
 147         if always_show_anchors && !(wp_first = window_pages[0]).first?
 
 148           items.push [first.number.to_s, first]
 
 149           items.push ["...", "disabled"] if wp_first.number - first.number > 1
 
 152         window_pages.each do |page|
 
 153           if current_page == page && !link_to_current_page
 
 154             items.push [page.number.to_s, "active"]
 
 156             items.push [page.number.to_s, page]
 
 160         if always_show_anchors && !(wp_last = window_pages[-1]).last?
 
 161           items.push ["...", "disabled"] if last.number - wp_last.number > 1
 
 162           items.push [last.number.to_s, last]