Sunday, September 7, 2008

Ajax Pagination in less than 5 minutes

Recently one of my client asked me to add 'ajax' pagination to his application. His site already had a very nice pagination using the excellent will_paginate from Mislav and the guys(PJ & Chris) from err the blog but since my client had a special need where he had to have Ajax.

It took me virtually no time to convert the standard pagination into an Ajax navigation while still degrading gracefully.(it works even without Javascript)

I really enjoy using will_paginate, it's very well written and the authors keep up with the bugs and new features.

Start by installing will_paginate:
http://github.com/mislav/will_paginate/wikis

Then go watch the Railcast screencast about will paginate.

Once you have your pagination working, we will do some ' progressive enhancement'.

What we want is to add a behavior to the pagination link. The behavior would make the same call than the normal link but via an ajax(Javascript) call.

Add lowpro

To do that, you simply need to add the excellent 'lowpro' Prototype extension from Dan Webb
You can get the files directly from the lowpro's repository.

Add lowpro.js to your public/javascript folder.
Don't forget to include the javascript in your page.
<%= javascript_include_tag 'lowpro' %>

Create a behavior

Now open your application.js file (or whichever Javascript file you're using) and add the following:
Event.addBehavior.reassignAfterAjax = true;
Event.addBehavior({
'div.pagination a' : Remote.Link
})
Refresh your cache, reload your page, and test the link. It will probably look like it doesn't do anything but if you are using firebug or if you are checking your logs, you'll notice something happened. The problem is that we didn't tell our action to send an Ajax response so we get the html full page all over again.

Setup a response for javascript requests

Got to your action handling the pagination and let's setup a response for Javascript:
def index
@photos = Photo.paginate(:all, :conditions => ["photos.user_id = ?", current_user.id], :page => params[:page])
respond_to do |format|
format.html # index.html.erb
format.js do
render :update do |page|
page.replace_html 'photos', :partial => "photos"
end
end
end
end
Perfect! Now when a visitor clicks on my pagination links, only the photos are paginated, the rest of the page stays the same. Note that my navigation bar is inside the partial so it gets 'updated' after a visitor clicks on any pagination link.

http://railsontherun.com/2007/9/27/ajax-pagination-in-less-than-5-minutes

No comments: