Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Example application to show infinite pagination with Kaminari and sausage
branch: master

This branch is even with fschwahn:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
app
config
db
doc
lib/tasks
public
script
test
vendor/plugins
.gitignore
Gemfile
Gemfile.lock
README.md
Rakefile
config.ru

README.md

Infinite Scrolling

Introduction

This tutorial shows how to create infinite scrolling pages using Kaminari, jQuery and sausage.

Tutorial

Create a new rails application. We will be using jQuery, so skip the prototype files.

$ rails new endless_page -J

Add 'jquery-rails' and 'kaminari' to the Gemfile and run the bundle command. Run the jQuery-generator to download the necessary files and setup rails to use jQuery.

$ rails generate jquery:install --ui

Download 'jquery.sausage' and add it along with 'jquery' and 'jquery-ui' to your javascript_include_tag.

$ curl -o public/javascripts/jquery.sausage.js http://christophercliff.github.com/sausage/jquery.sausage.js

Let's create a model, which will be used to showcase the infinite scrolling and migrate the database.

$ rails generate scaffold Article title:string author:string body:text
$ rake db:migrate

I use the populator and ffaker gems to fill the database with random data, but this step is only required for showcasing the infinite scrolling. Run rake db:populate if you want to do the same.

In the next step we have to edit the scaffolded controller. We update the index-action so it looks like that:

def index
  @articles = Article.order(:created_at).page(params[:page])

  respond_to do |format|
    format.js
    format.html # index.html.erb
    format.xml  { render :xml => @articles }
  end
end

We are now using pagination powered by Kaminari in the index action. We also make sure that our index-action responds to requests sent from Javascript. In the next step we move the rendering of an article into a partial named '_article.html.erb'. Mine looks like this:

<div class='article'>
  <h3><%= article.title %></h3>
  <div class='author'>by <%= article.author %></div>
  <div class='date'>by <%= article.created_at.to_s(:long) %></div>
  <p>
    <%= article.body %>
  </p>
</div>

We can now use this partial to render the articles in 'index.html.erb' using the following command. The div with a class of 'page' is important for sausage. It is used to determine the different pages for the navigation on the right.

<div id='articles'>
  <div class='page'>
    <%= render @articles %>
  </div>
</div>

Now it is time to use sausage to implement the infinite scrolling. Add the following Javascript to the bottom of 'index.html.erb'.

<script type="text/javascript">
(function() {
  var page = 1,
      loading = false;

  function nearBottomOfPage() {
    return $(window).scrollTop() > $(document).height() - $(window).height() - 200;
  }

  $(window).scroll(function(){
    if (loading) {
      return;
    }

    if(nearBottomOfPage()) {
      loading=true;
      page++;
      $.ajax({
        url: '/articles?page=' + page,
        type: 'get',
        dataType: 'script',
        success: function() {
          $(window).sausage('draw');
          loading=false;
        }
      });
    }
  });

  $(window).sausage();
}());
</script>

The snippet is pretty straightforward. It checks if the user scrolled to the bottom of the page. If that is the case, an ajax-request is sent to the ArticlesController requesting the next page. After the ajax-request is completed successfully the sausage-navigation is redrawn. One last piece is missing. When the ajax-request is sent to the ArticlesController we need to append the next page of articles. We need to create a file named 'index.js.erb' to achieve this goal.

$("#articles").append("<div class='page'><%= escape_javascript(render(@articles)) %></div>");

Now we have an application featuring infinite scrolling in only a couple lines of code. It is easy to modify this example to use a Twitter-like 'read more'-link instead of infinite scrolling.

Notes

Something went wrong with that request. Please try again.