Sergio Panagia Blog

Easy Ajax Infinite Scroll with Ruby On Rails and MooTools

versione italiana, icona Italian version

Modern web design trends are going far from classic numbering pagination. Facebook, Twitter, Tumblr: all of them chose the infinite scroll paradigm to show more contents.

There are mainly to different cases in that technique: update content on user explicit action (like click on a button) or when user’s reach the end of page.

For a matter of User Experience and Usability, I generally prefer the first one, specially if you got a footer.

Anyway, this effect is easily obtained with a bit of Rails3 code and MooTools magic, so let’s make some assumptions:

  • You have a Post model with relative controller and view
  • You have a index method in your controller
  • You’re using Rails3 plugin for MooTools

Infinite loop will show posts from last one to older, so let’s define the default scope in Post model:

models/post.rb

default_scope order('posts.created_at desc')

Let’s begin with the index method:

controllers/posts_controller.rb

def index 
  @posts = Post.limit(10)
  @posts.length
  respond_to do |format|
    format.html
  end
end

So we’re limiting the number of posts loaded. At this point let’s take a look at the view

views/posts/index.html.erb

<%= render @posts %>

<%= link_to "Load more..", {:action => :load_from, :start => @posts.last.id},{ :remote => true, :id => "pageLoader" } %>

We’re basically creating a link (remote, so using Ajax) to perform an HTTP GET request passing a certain id as parameter, handled by a custom action that we’re going to define in posts controller:

controllers/posts_controller.rb

def load_from
  @start_point = params[:start]
  @start_point = @start_point.to_i -1
  @new_posts = Post.where('id < ?', @start_point).limit(10)
  respond_to do |format|
    format.js
  end
end

So we're selecting the rest piece of data and manage a response for a js request. The javascript file, by convention over configuration, is located in the related view with the same name of the method's called:

views/posts/load_from.js.erb


var postsHtml = '<%= escape_javascript(render(@new_posts)) %>';
var el = new Element('div', {'html': postsHtml}).inject(document.id('posts'));
document.id('pageLoader').set('href', '/ajax/more?start=<%= @new_posts.last.id %>');
rails.applyEvents(el);

So we're creating the new element and injecting into posts container.

Then with the set('href') function we update the last post index on the 'load more' link in the view.

Finally, we attach rails3 events to our new created elements by calling function rails.applyEvents(el).

Lascia un Commento

L'indirizzo email non verrĂ  pubblicato. I campi obbligatori sono contrassegnati *

*

*

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>