WillPaginate with ajax and unobtrusive js
March 25th, 2008
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.





April 21st, 2008 at 2:11 pm
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.