I have a long block of comments on a view of model Page
. Instead of showing all the comments on page load, I'm trying to create a "view more" button that shows the next ten comments. The button sends an ajax request to the controller, which then renders this block using jquery:
_view_more.html.erb
<% comments.each_with_index do |comment, index|%>
<% if (( index > @start_number) && (index < @end_number) ) %>
<%= comment.text %>
<% end %>
Let's say I always want to show the next 10 comments. I would just set @start_number = @start_number + 10
and @end_number = @end_number + 10
in the controller, but instance variables get reset, so @start_number
would be nil. How can I set a variable that increases by 10 upon every ajax request?
"view more" button
<%= link_to "view more", view_more_page_path, remote: true %>
pages_controller.rb
def view_more
@page = Page.find(params[:id])
respond_to do |format|
format.html { redirect_to root_path }
format.js
end
end
view_more
$("#comments-body").append("<%= escape_javascript(render 'view_more') %>");
I will use haml
and coffee-script
When rendering comments
you put an html5
data attribute
with the id
of the comment
:
#view where to render comments
%div#comments-wrapper{:"data-pageid" => @page.id}
=render @comments
=link_to "View more", "#", id: "view-more-link"
The comment partial
#comments/_comment.html.haml
%p.single-comment{:"data-commentid" => comment.id}
=comment.body
application.coffee
$ ->
$("#view-more-link").on 'click', ->
last_comment_id = $("#comments-wrapper .single-comment").last().data('commentid')
page_id = $("#comments-wrapper").data("pageid")
$.ajax
url: "/comments/view_more"
dataType: "script"
data:
last_comment_id: last_comment_id
page_id: page_id
comments_controller
def view_more
@page = Page.find(params[:pageid])
if params[:last_comment_id]
@comments = @page.comments.where("comments.id > ?", params[:last_comment_id]).limit(10)
end
respond_to do |format|
format.js
end
end
comments/view_more.js.erb
$("#comments-wrapper").append("<%= escape_javascript(render @comments) %>");
Note: I don't how your routes were set up so I put the page.id
as a data-attribute as well
I would use already implemented pagination gems kaminari or will_paginate . I'll create this example using will_paginate.
First of all, it's important to say that your approach is incorrect, because it loads all comments every view_more
request. If you want to show 10 comments, makes sense select only they from database, right? The pagination gem will do it for you!
Let's to the code:
"view more" button
<%= link_to "view more", view_more_page_path, remote: true, id: 'view-more-btn' %>
pages_controller.rb
def view_more
@comments = Page.find(params[:id]).comments.paginate(page: params[:page], per_page: 10)
respond_to do |format|
format.html { redirect_to root_path }
format.js
end
end
_view_more.html.erb
<% @comments.each do |comment| %>
<%= comment.text %>
<% end %>
view_more.js.erb
$("#comments-wrapper").append("<%= escape_javascript(render 'view_more') %>");
# We need to update the 'view more' link with the next page number
$('#view-more-btn').attr('href', '<%= view_more_page_path((params[:page] || 0) + 1) %>')
is it not good to update an hidden variable before making ajax call with the count..?
var currentVal = parseInt($("[type=hidden]").val());
$("[type=hidden]").val( currentVal + 1 );
add the hidden field right at the begining of the comments section with default value as "0"
<input type="hidden" name="hiddenId" id="hiddenId" value="0">
Hope it will help
If you want a quick and dirty approach, you could save start_number and end_number inside a cookie .
But keeping track of what needs to be rendered next on client side would be a right thing to do.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.