Redline Software Inc. - Winnipeg's Leader in Ruby on Rails Development

Will_paginate and Remote AJAX Links

Updated for will_paginate 2.3.x

So you’re using the will_paginate plugin and want to use remote AJAX links. You’re not using the will_paginate plugin? Simply install it with…

1
script/plugin install git://github.com/mislav/will_paginate.git

or install the gem and specify it in your config/environment.rb file

1
sudo gem install mislav-will_paginate

1
config.gem 'mislav-will_paginate', :lib => 'will_paginate', :source => 'http://gems.github.com'

will_paginate is an alternative to the classic_pagination plugin, which is the pagination plugin that basically took the pre Rails 2.0 pagination implementation and packaged it in plugin form. I won’t discuss the differences between the two plugins here, but there’s a good video explaining the two from Railscasts [here](http://railscasts.com/episodes/51).
Out of the box, will_paginate doesn’t allow remote AJAX links for page links, so I’ll show you an easy way to add such functionality…

I’ve read a number of blogs that seem to go a bit overboard in order to implement remote links, but will_paginate allows you to customize the links quite nicely already.

By default will_paginate uses the WillPaginate::LinkRender class to render links. So lets use this is a base and add to it. We can derive from this class and add our own functionality.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# app/helpers/remote_link_renderer.rb

class RemoteLinkRenderer < WillPaginate::LinkRenderer
  def initialize(collection, options, template)
    @remote = options.delete(:remote)
    super
  end

  def page_link_or_span(page, span_class = 'current', text = nil)
    text ||= page.to_s
    if page and page != current_page
      @template.link_to_remote(text, {:url => url_options(page), :method => :get}.merge(@remote))
    else
      @template.content_tag :span, text, :class => span_class
    end
  end
end

All I’m doing is creating a subclass to the existing renderer and overriding the page_link_or_span method that makes the link_to method call and replacing it with a call to link_to_remote (I also added the :method => :get option to work with my restful code).

So how do we use this? One of two ways.

  • Use the :renderer and :remote(optional) option on will_paginate. The :remote option takes any options that link_to_remote does, so refer to the rails docs for allowable options. The :with and :update options are simply being used to show example usage.

1
<%= will_paginate @collection, :renderer => 'RemoteLinkRenderer' , :remote => {:with => value, :update => some_div} %>

  • or set the default renderer in config/environment.rb

1
WillPaginate::ViewHelpers.pagination_options[:renderer] = 'RemoteLinkRenderer'

  • and use it without the :renderer option.

1
<%= will_paginate @collection, :remote => {:with => value, :update => some_div} %>

That’s all there is to it. You could get fancier when creating your LinkRenderer class to allow for additional customization, but this is a good start.

Update for will_paginate 2.3.x

This is even more concise in the new version.

1
2
3
4
5
6
7
8
9
10
11
12
13
# app/helpers/remote_link_renderer.rb

class RemoteLinkRenderer < WillPaginate::LinkRenderer
  def prepare(collection, options, template)
    @remote = options.delete(:remote) || {}
    super
  end

protected
  def page_link(page, text, attributes = {})
    @template.link_to_remote(text, {:url => url_for(page), :method => :get}.merge(@remote), attributes)
  end
end

The usage remains the same as above.

To use the new version, see the Installation section at http://github.com/mislav/will_paginate/tree/master

Comments