I'm trying to implementing an endless scroll on my project. I'm using a mix of the Railscast #114 Endless Page and this.
Everything works fine besides a weird behavior when I try to stop sending requests when the page hits its end.
So far I have:
Controller:
def show
@title = Photoset.find(params[:id]).name
@photos = Photoset.find(params[:id]).photo.paginate(:page => params[:page], :per_page => 20)
respond_to do |format|
format.js
format.html
end
end
Show.html.erb:
<% content_for :body_class, '' %>
<%= render 'shared/header' %>
<div id="photos_container">
<div id="photos_header">
<h2><%= @title %></h2>
</div>
<%= render :partial => 'photo', :collection => @photos %>
</div>
<%= render :partial => 'endless_scroll' %>
Javascript (loaded via partial):
<script type="text/javascript">
(function() {
var page = 1,
loading = false,
finish = false;
function nearBottomOfPage() {
return $(window).scrollTop() > $(document).height() - $(window).height() - 200;
}
function finish() {
finish = true;
}
$(window).scroll(function(){
if (loading) {
return;
}
if(nearBottomOfPage() && !finish) {
loading=true;
page++;
$.ajax({
url: '/photosets/<%= params[:id] %>?page=' + page,
type: 'get',
dataType: 'script',
success: function() {
loading=false;
}
});
}
});
}());
</script>
show.js.erb
$("#photos_container").append("<%= escape_javascript(render :partial => 'photo', :collection => @photos) %>");
<% if @photos.total_pages == params[:page].to_i() %>
page.call 'finish'
<% end %>
As you can see, on my show.js.erb
I have a page.call
that assigns true to the finish
variable. This stops the requests.
The wired thing is that it never loads the last page. When @photos.total_pages == params[:page].to_i()
instead of just calling the finish
function and setting the variable to true
, it's also preventing the $("#photos_container").append("<%= escape_javascript(render :partial => 'photo', :collection => @photos) %>");
from running.
It sends the request to the controller, runs the SQL but doesn't append the last page.
If I change the condition to @photos.total_pages < params[:page].to_i()
it works, but send an extra request to a page that doesn't exist.
I'd appreciate any help on my implementation. I'm not sure if there's a more adequate (Rails) way to accomplish this.
First of all you can render html from the partial when request is xhr type:
def show
photoset = Photoset.includes(:photos).find(params[:id])
@title = photoset.name
@photos = photoset.photo.paginate(:page => params[:page], :per_page => 20)
if request.xhr?
render '_photo', :layout => false
end
end
Then use ajax call:
$.ajax({
url: '/photosets/<%= params[:id] %>?page=' + page,
type: 'get',
dataType: 'script',
success: function(response) {
$("#photos_container").append(response);
if (response == "") {
//stop calling endless scroll
}
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With