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.

I love to use prototype and scriptaculous to create Rich Internet Application, and I love all the built-in effects and libraries of script.aculo.us.
Today I was working with Sortable.create to provide a simple way to reorder images inside a gallery. I started using the same code used in the SortableListsDemo page of the official wiki. Each time the list is updated, the serialized list is sent to the server. The server receives the list and updates all the images positions. It’s pretty simple and works fine, but the problem is that the server executes a query for each image in the gallery. This means that if I have 100 images, 100 queries will be run. It’s a hell for my server! The best way to improve this action is to send to the server more detailed information, such as the dragged image, the old position and the new position. In this way I can execute only 2 queries for each movement. To do that I wrote a simple javascript class called LiteSortable that acts like the Sortable.create method. It receives the same parameters, and the same callbacks: onUpdate, onChange. The only change is that these 2 callbacks will receive more information about the movement, and I can improve the previous client side code with:

function sort(list, element, id, old_position, new_position) {
  new Ajax.Request('/admin/gallery_item/sort/', {
    evalScripts:true,
    parameters: {
      id: id,
      old_position: old_position,
      new_position: new_position
    }
  });
}

document.observe('dom:loaded', function() {
  new LiteSortable('list', {
    onUpdate: sort
  });
});

And the server code become like the following:

def sort
  old_position, new_position = params[:old_position].to_i, params[:new_position].to_i
  @item = GalleryItem.find(:first, :conditions => ["id = ? AND position = ?", params[:id], old_position])
  if @item
    x, y, z = old_position < new_position ? ["-", "<", ">"] : ["+", ">", "<"]
    GalleryItem.update_all("position = (position #{x} 1)", ["parent_id IS NULL AND gallery_id = ? AND position #{y}= ? AND position #{z}= ?", @item.gallery_id, new_position, old_position])
    @item.update_attribute('position', new_position)
  else
    @error = true
  end
end

If @error is true, it means that the dragged image it’s been deleted or moved by somone else.
If you want to use LiteSortable you can check out the entire project with:

svn co http://dev.gravityblast.com/svn/projects/js/LiteSortable/

…or save download the lite_sortable.js file from here.