Every day I use will_paginate plugin to paginate list of records. Today I need to paginate with ajax, and googling I only found a patch for the plugin that adds some code inside the generated links. Thus I decided to write a few lines of javascript to generate the same behaviour:

var Pagination = {  

  initLinks: function() {
    $('container').select('div.pagination a').invoke('observe', 'click', Pagination.linkHandler);
  },

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

}

document.observe('dom:loaded', Pagination.initLinks);

Obviously the code it’s not optimized, it’s just an example, but it works. You only need create a list of records inside a div caled ‘container’, and that div will be update with the content loaded by the ajax request.

[UPDATE] I like the prototype OO way to write js. So I wote the same thing with a class:

var Pagination = Class.create({ 

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

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

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

});

document.observe('dom:loaded', function() {
  new Pagination();
});

The latest version is more customizable because the constructor could receive a list of options. For now it’s only one, you can specify the container that will be updated, but you could add more options like the name of the spinner to show during requests and so on.

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Technorati
  • Reddit
  • Furl

One Response to “WillPaginate with ajax and unobtrusive js”

  1. Reggie Says:

    The thing I like the most (and after finding it here I searched for) is the way you used to make the initialization. Sometimes people just arrived to Javascript, make initialization doing something like

    initialize: function(options) {
    if (options) {
    this.options = {};
    this.options.container = options.container || ‘container’;
    this.options.selector = options.selector || ‘a’;
    /* any other option */
    },

    I did it till now, when I searched about your way to make initialization. The good part is that with prototype you can use Object#extend to copy all the properties from one object to another. So we can have

    initialize: function(options) {
    this.options = Object.extend({
    container: ‘container’,
    selector: ‘a’
    /* any other option */
    }, options || {});
    },

    In this way the code became much more readable, because you *firstly* set all the default options, and then you change them just using the arguments.

Leave a Reply