Infinite Scrolling

Episode #29 by Teacher's Avatar David Kimura

Summary

Infinite scrolling is now a common feature and there are several cases where it is really useful. For instance there are some websites where we simply can’t imagine a good pagination system, like Twitter or even Facebook.
rails view javascript 5:40

Resources

Summary

# Gemfile
gem 'will_paginate'

# products_controller.rb
  def index
    @products = Product.order(name: :asc).paginate(page: params[:page], per_page: 10)
  end

# index.html.erb
<div class="panel panel-primary">
  <div class="panel-heading">
    <h3 class="panel-title">Products</h3>
  </div>
  <div class="table-responsive">
    <table class='table table-hover table-condensed'>
      <thead>
        <tr>
          <th>Name</th>
          <th>Price</th>
          <th>Department</th>
          <th colspan="3"></th>
        </tr>
      </thead>

      <tbody id='products'>
        <%= render @products %>
      </tbody>
    </table>
  </div>
</div>
<%= will_paginate @products %>
<%= link_to 'New Product', new_product_path, class: 'btn btn-lg btn-block btn-primary' %>

# index.js.erb
$('#products').append('<%= j render("product_page_header") %>');
$('#products').append('<%= j render(@products) %>');
<% if @products.next_page %>
  $('.pagination').replaceWith('<%= j will_paginate(@products) %>');
<% else %>
  $('.pagination').remove();
<% end %>

# _product_page_header.html.erb
<tr class='info'>
  <td colspan="6" class='text-center'>
    Page <%= params[:page] %>
  </td>
</tr>

When using infinite scrolling, try to keep three points in mind:

  • Content Accessibility - Do not put links at the bottom of the page as they would be hidden from the client and hard to access.
  • Separate Renders - Creating a separation between renders of the infinite scrolling can make it easier to find content.
  • Searchable List - If using infinite scrolling techniques, make sure that you are including some kind of search to make content accessible.

# products.coffee
$ ->
  if $('.pagination').length && $('#products').length
    $(window).scroll ->
      url = $('.pagination .next_page').attr('href')
      if url && $(window).scrollTop() > $(document).height() - $(window).height() - 50
        $('.pagination').text("Loading more products...")
        $.getScript(url)
    $(window).scroll()