Introduction

Endless scrolling allows a website to let users avoid having to click page links in order to load additional pages of content. It is used by a number of sites such as Pinterest in order to enhanced the user experience. This article will show you how to implement endless scrolling in your Rails application. Let's get started.

Rails Application Setup

Endless scrolling uses the will_paginate gem to manage paging. This has a couple of advantages. First, if your endless scrolling code doesn't work properly or is disabled, the pagination links themselves will still be present and allow the user to page. Second, the will_paginate gem provides us with the pagination functionality itself so that we do not need to reinvent the wheel.

To get started, add the will_paginate gem to your Gemfile.

Gemfile:

gem 'will_paginate', '~> 3.0.7'

Now run a bundle install to install the gem.

Terminal Commands:

bundle install

For our example app, we will create a simple Post model with the fields title, and body. In addition, we will create a simple Posts controller with an index method. Run the commands below to create these items now.

Terminal Commands:

rails g model Post title body:text
rake db:migrate
rails g controller Posts index

Great, now open up your routes file and modify it so that it looks like the code listed below.

config/routes.rb:

Rails.application.routes.draw do
  root to: "posts#index"
end

Next we need some seed data to play with. Open up your seeds.rb file and add in the code listed below. This code will create 100 posts for us to play with.

db/seeds.rb:

(1..100).each do |i|
  Post.create!(title: "Lipsum Post #{i}", body: %{
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. In feugiat purus dapibus fermentum sagittis. Fusce in tempus felis. Phasellus a erat ut lorem lacinia bibendum. Vivamus viverra facilisis neque, in scelerisque urna pharetra vel. Donec a est mauris. Integer eget metus quis eros egestas elementum. Integer bibendum risus hendrerit dapibus tempor. Fusce placerat in orci vitae tincidunt.
  })
end

Now run a rake db:seed to create the seed data.

Terminal Commands:

rake db:seed

Now open up your Posts controller and modify it so that it looks like the code listed below.

app/controllers/posts_controller.rb:

class PostsController < ApplicationController
  def index
    @posts = Post.paginate(:page => params[:page], :per_page => 20)
  end
end

Now modify the index view for your Posts controller so that it looks like the code listed below.

app/views/posts/index.html.erb:

<div id="posts">
  <h1>Posts</h1>
  <%= render @posts %>
</div>
<%= will_paginate @posts %>

Now let's create the post partial. Create a file called _post.html.erb for your Posts controller and add in the code listed below.

app/views/posts/_post.html.erb:

<div class="post">
  <h2><%= post.title %></h2>
  <p><%= post.body %></p>
</div>

If you were to start a rails server at this point, you'd see a typical paginated list of posts. Now it's time to add in the javascript that will make endless scrolling work. Open up your application.js file and add in the code listed below.

app/assets/javascripts/application.js:

$(document).ready(function() {
  if ($('.pagination').length) {
    $(window).scroll(function() {
      var url = $('.pagination .next_page').attr('href');
      if (url && $(window).scrollTop() > $(document).height() - $(window).height() - 50) {
        $('.pagination').text("Please Wait...");
        return $.getScript(url);
      }
    });
    return $(window).scroll();
  }
});

Now create a file called index.js.erb for your Posts controller and add in the code listed below.

app/views/posts/index.js.erb:

$('#posts').append('<%= escape_javascript render(@posts) %>');
$('.pagination').replaceWith('<%= escape_javascript will_paginate(@posts) %>');

The code works by watching the window's scroll event. Once the user scrolls past the specified threshold, more posts are loaded using AJAX. That's it! Thanks for reading!