r123454321
r123454321

Reputation: 3403

Rails 4: Loading posts w/ JQuery & AJAX on a "Load More" button

I have a collection of Ideas (you can think of them as posts), and I want to display 6 on my index page initially, then have 6 more load whenever the user hits the "Load more" button. Here's my code:

ideas_controller.rb: (Index action)

# Get ideas that were created most recently
@ideas = Idea.page(params[:page]).per(6).order('created_at DESC')

Ideas index view:

.ordered-ideas
  = render @ideas
= link_to_next_page @ideas, 'Load More', :remote => true, :id =>"load_more_link"

_idea.html.haml (Partial):

%ul{ :class => 'span4' }
  %a{ :href => idea_path(idea.id), :class => 'thumbnail', :id => "idea_#{idea.id}" }
    .idea-concept-index
      = idea.concept

    .idea-description-index
      = idea.description
    %hr

    .idea-index-icons
      .idea-index-teams
        %i{ :class => 'fa fa-wrench' }
        = idea.teams.count
        teams

      .idea-index-like
        %i{ :class => 'fa fa-heart pink' }
        = idea.likes.count 
        likes

index.js.erb:

$('.ordered-ideas').append("<%=j render @ideas %>");

However, when I hit "Load more", nothing happens... what do I need to add? Thanks.

Upvotes: 0

Views: 3764

Answers (1)

CuriousMind
CuriousMind

Reputation: 34155

First thing you will need is pagination, since you haven't mentioned what library you are using. I am going to show how to do this with will_paginate.

Step 1: Add gem will_paginate to your Gemfile & run bundle.

Step 2: Use pagination:

@ideas = Idea.paginate(page: params[:page], per_page: 6).order(created_at: :desc)
respond_to do |format|
  format.html
  format.js
end

Step 3: View integration:

<div id="ordered-ideas">
  <%= render @ideas %>
</div>

<div id="infinite-scrolling">
  <%= will_paginate @ideas %>
</div>

_idea.html.haml (Partial):

%ul{ :class => 'span4' }
  %a{ :href => idea_path(idea.id), :class => 'thumbnail', :id => "idea_#{idea.id}" }
    .idea-concept-index
      = idea.concept

    .idea-description-index
      = idea.description
    %hr

    .idea-index-icons
      .idea-index-teams
        %i{ :class => 'fa fa-wrench' }
        = idea.teams.count
        teams

      .idea-index-like
        %i{ :class => 'fa fa-heart pink' }
        = idea.likes.count 
        likes

Step 4: Infinite Scrolling

Create a new file pagination.js.coffee inside the javascripts directory.

jQuery ->
  if $('#infinite-scrolling').size() > 0
    $(window).on 'scroll', ->
      more_ideas_url = $('.pagination .next_page a').attr('href')
        if more_posts_url && $(window).scrollTop() > $(document).height() - $(window).height() - 60
            $('.pagination').html('<img src="/assets/ajax-loader.gif" alt="Loading..." title="Loading..." />')
            $.getScript more_ideas_url
        return
      return 

The last thing to do is to create a view that will be rendered when responding with JS:

index.js.erb

$('#ordered-ideas').append('<%= j render @ideas %>');
<% if @ideas.next_page %>
  $('.pagination').replaceWith('<%= j will_paginate @ideas %>');
<% else %>
  $(window).off('scroll');
  $('.pagination').remove();

if you have done everything till here correctly, your "load more" should be working. if not, then post with the code & error. so we can help you further.

Upvotes: 1

Related Questions