Easy ajax sorting with will_paginate and ujs_sort_helper for rails
Install will_paginate
script/plugin install git://github.com/mislav/will_paginate.git
Install ujs_sort_helper
script/plugin install git://github.com/pengwynn/ujs_sort_helper.git
Install livequery
Livequery is just a javascript file. You can grab it from github (copy and paste is fine) and put it under public/javascripts/jquery.livequery.js.
Configure will_paginate and ujs_sort_helper together
Edit your controller’s list action. This example is nesting will_paginate and so is a little more complex than what you’ll probably use, but sometimes it’s rewarding to the reader to see a little bit more complexity. The key text to look at is the ‘options’ clause though.
1 2 3 4 5 6 7 8 9 10 11 12 13 | def show sort_init 'created_at' sort_update options = {:page => params[:page], :per_page => 10, :order => sort_clause } @project = Project.include_comments.include_watched_projects.find(params[:id]) @comments = @project.comments.order_by.include_user.include_uploads.include_roles.paginate(options) respond_to do |format| format.html # show.html.erb format.xml { render :xml => @project } end end |
Configure application.rhtml with the necessary javascripts
My example is actually using jquery via the jrails plugin so if you are using prototype this might look a bit different. See the README for info on using prototype instead.
1 2 3 4 | <%= javascript_include_tag :defaults %> <%= stylesheet_link_tag "ujs_sort_helper"%> <%= javascript_include_tag "jquery.livequery.js" %> <%= javascript_include_tag "ujs_sort_helper.jquery.js", :plugin => "ujs_sort_helper"%> |
Setup your view
I am not using the typical table so your example might be slightly different, but I figured it might be nice for other people to see how it functions without using a table.
In show.html.erb or list.html.erb or index.html.erb (whatever you used previously in your controller) place your will_paginate links and ujs_sort_helper link(s).
1 2 3 4 5 6 | <!-- Comments --> <div id="comments"> <p id="sort_comments" align="right"><%= sort_header_tag('created_at', :caption => 'Order') %></p> <%= render :partial => 'comments/comment', :collection => @comments %> <%= will_paginate @comments %> </div> |
As you can see, my code uses the sort_header_tag to create the sort link, and I am specifying the text caption with the :caption option. Then I am calling my comment partial with my array of @comments from the controller. And finally, I am including the pagination links using will_paginate and the array I want to paginate.
Edit ujs_sort_helper.jquery.js
We need this file to load the proper div for the ajax sort call.
1 2 3 4 5 6 7 8 9 10 11 12 13 | jQuery(document).ready(function() { jQuery('a.sort_link').livequery('click', function(e) { jQuery('#comments').load(e.target.href + " div#comments"); return false; }); jQuery('div.pagination a').livequery('click', function(e) { jQuery('#comments').load(e.target.href + " div#comments"); return false; }); }); |
