DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Simple Conversion Of Rails Will_paginate To Ajax

12.14.2010
| 7758 views |
  • submit to reddit
        This, by default, converts will_paginate links to Ajax links using unobtrusive Javascript. It uses Prototype and assumes the container to be refreshed has an id of 'pagination_container', but this can be overridden. It is a modified version of <a href="http://gravityblast.com/2008/03/25/will_paginate-with-ajax-and-unobtrusive-javascript/">Andrea Franz' code</a>, written for the same purpose. The modifications allow one to use the code to turn any link into an Ajax call.

Place the following in application.js
var UnobtrusiveLinker = Class.create({ 

  initialize: function() {
    this.options = Object.extend({
      container: 'pagination_container',
      selector: 'div.pagination a'
    }, arguments[0] || {});
    this.initLinks();
  },  

  initLinks: function() {
    $(this.options.container).select(this.options.selector).invoke('observe', 'click', this.linkHandler.bind(this));
  },  

  linkHandler: function(event) {
    event.stop();
    new Ajax.Updater(this.options.container, event.element().getAttribute('href'),{
      method: 'get',
      onComplete: this.initLinks.bind(this)
    });
  }

});

To convert will_paginate to Ajax, simply embed the following in the applicable page:
<script type="text/javascript">
 document.observe('dom:loaded', function() {
  new UnobtrusiveLinker();
 });
</script>

But, it is easier to use a helper in application_helper.rb:
  def make_links_ajax(opts = [{}])
    opts = [opts] if opts.is_a? Hash
    ret = "document.observe('dom:loaded', function() { "
    opts.each {|option| ret += "new UnobtrusiveLinker(#{option.to_json}); "}
    ret + "});\n"
  end

Which allows this for the default case:
<%= javascript_tag(make_links_ajax()) %>

Or the following if you want to specify the container and selector, or specify more than one:
<%= javascript_tag(make_links_ajax(:container => 'my_container', :selector => 'a.my_links')) %>

<%= javascript_tag( make_links_ajax([{:container => 'pagination_container', :selector => 'div.pagination a'}, {:container => 'another_container', :selector => 'a.another_link_class'}]) ) %>
    

Comments

Snippets Manager replied on Mon, 2007/08/27 - 6:52pm

Leave out the showPageSpinner(); and onComplete: ... in that comment unless you want to write your own show and hide spinner.

Snippets Manager replied on Mon, 2007/08/27 - 6:52pm

If your container is always the same, you can do all of this with the following code: document.on('click', function(event) { var element = event.element(); var trigger = event.findElement('div.pagination a'); if (trigger && element == trigger) { event.stop(); showPageSpinner(); new Ajax.Updater('list_container', element.getAttribute('href'),{ method: 'get', onComplete: function(request){hidePageSpinner();}, evalScripts: true }); return false; } });