0

I'm working on an forum-type app in Rails v 4.2.5. My index page is a list of all the questions being discussed in the application and they are default sorted by the created_at date. I am also using the Kaminari gem to paginate all of the questions (25 per page). I originally had my app set up like this:

Questions Controller:

def index
  @questions = Question.order(:created_at).page params[:page]
end

Index View:

# I render a partial that iterates through the questions list to display 
# the title of the questions, then I include the paginate code below.

<div class="pagination">
  <%= paginate @questions  %>
</div>

I eventually decided I wanted users to be able to sort the questions by different criteria (e.g., by total amount of upvotes, by total amount of responses for a question, and by recently asked questions). Right now, you can click a link corresponding to the type of sort you want and it will AJAX the new sorted list (a partial) onto the page. However, when I do this, the pagination does not work and when I click to see the second page of the results, everything becomes unsorted.

Index View with Sort Links:

<div class="sort_selection">
  <h3> Sort By: </h3>
    <%= link_to "By Upvotes", "/questions/top?sort=votes", class:     "question_sort_link" %>
    <%= link_to "Answers Provided", "/questions/top?sort=answers", class: "question_sort_link" %>
    <%= link_to "Recently Asked", "/questions/top?sort=recent", class:     "question_sort_link" %>
</div>

Index Controller:

def top
    case params[:sort]
    when "votes"
      @questions = Question.sort_by_votes #sort_by_votes is a method in my Question model that performs a SQL query
    when "answers"
      @questions = Question.where.not(answers_count: nil).order(answers_count: :desc).limit(25)
    when "recent"
      @questions = Question.order(created_at: :desc).limit(25)
    end
    render partial: 'questions_list', layout: false
end

Javascript AJAX

$(document).on("click", ".question_sort_link", function(event){
event.preventDefault();
  $.ajax({
    method: "get",
    url: $(this).attr("href")
  }).done(function(sorted){
    $('.questions_show_sorted').replaceWith(sorted);
  });
});

I fooled around with the placement of the <%= paginate @questions %> in the view, as well as removed the 25 limit in my controller and added .page params[:page] after all of the queries in the Top route but I still cannot get the pagination to work after I've AJAX'ed a sorted list onto the page. Does anyone have any suggestions?

Pardeep Dhingra
  • 3,916
  • 7
  • 30
  • 56
  • What does you question_list partial look like? You definitely need to call .page params[:page] on the @questions array in your controller for it to work. – nbon Jan 07 '16 at 14:45
  • You'll need to replace the paginate helper when you get the new sort order. – j-dexx Jan 07 '16 at 15:34

2 Answers2

0

When you are switching pages the data about sorting is lost, because you are reloading site with different parameters. You can either try to pass this data (the column you are going to sort, and info is it asc or desc) to the new page, and sort it before loading, or paginate it using AJAX (but that means loading everything at the first load). I can't tell about the "pagination does not work problem", because I don't know what you mean.

In general, this thing you are trying to do is rather complicated, and there is no simple solution for that. There is a library for JS called Datatables that (in theory) makes it easier. There is another library called jQ-Bootgrid, and a ruby gem called "Smart listing".

ZebThan
  • 255
  • 2
  • 17
0

I think you need to provide the pagination links in your ajax response and replace them in your javascript callback. I assume that you return html rather than json, which will make this a bit awkward. Perhaps you could build up a json response with pagination links and html content

{
  next: /list?page=3,
  prev: /list?page=1,
  content: "<ul>
             <li>foo</li>
             <li>bar</li>
            </ul>"
}
sammygadd
  • 299
  • 2
  • 6