How can I update my view keeping all existing ajax and will_paginate functionality in place?
I have a page rehome.html.erb
<div id="options">Option Select Here</>
<div class="all_animals">
<%= render @animals %>
</div>
<% unless @animals.current_page == @animals.total_pages %>
<div id="infinite-scrolling">
<%= will_paginate @animals %>
</div>
<% end %>
// WILL_PAGINATE
<script type="text/javascript">
$(function(){
if($('#infinite-scrolling').size() > 0) {
$(window).on('scroll', function(){
//Bail out right away if we're busy loading the next chunk
if(window.pagination_loading){
return;
}
more_url = $('.pagination a.next_page').attr('href');
if(more_url && $(window).scrollTop() > $(document).height() - $(window).height() - 50){
//Make a note that we're busy loading the next chunk.
window.pagination_loading = true;
$('.pagination').text('Loading.....');
$.getScript(more_url).always(function(){
window.pagination_loading = false;
});
}
});
}
});
</script>
This will load all the @animals collection, paginating it to 6 per page, and when I scroll down the page another 6 are loaded etc etc.
Corresponding controller
class PublicController < ApplicationController
before_filter :default_animal, only: [:rehome]
def rehome
respond_to do |format|
format.html
format.js
end
end
private
def default_animal
@animals = Animal.animals_rehome.paginate(:page => params[:page], :per_page => 6)
end
end
rehome.js.erb
$('.all_animals').append('<%= j render @animals %>');
<% if @animals.next_page %>
$('.pagination').replaceWith('<%= j will_paginate @animals %>');
<% else %>
$(window).off('scroll');
$('.pagination').remove();
<% end %>
So when an option is selected from the dropdown an ajax post is made to create a new query which will return a new collection of @animals
$.ajax({
type: 'POST',
url: '/public/rehomed',
data: data_send,
success: function(data) {
//console.log(data);
}
});
Controller
def rehomed
# conditions logic
@animals = Animal.joins(:user).where(conditions).paginate(:page => params[:page], :per_page => 6)
respond_to do |format|
format.js {render json: @animals }
end
end
What I want to do is have the new collection loaded (paginated to 6 per page again) and when I scroll down only show the objects belonging to the new collection of @animals (if there are any).
At the moment the pagination links are not updated as when I scroll down the page the original collection is loaded.
So I have created a rehomed.js.erb file which is pretty much the same as my rehome.js.erb:
$('.all_animals').empty();
$('.all_animals').append('<%= j render @animals %>');
<% if @animals.next_page %>
$('.pagination').replaceWith('<%= j will_paginate @animals %>');
<% else %>
$(window).off('scroll');
$('.pagination').remove();
<% end %>
and within my rehomed action
respond_to do |format|
format.js
end
So the new collection of animals is loaded, the pagination links are recreated but using the rehomed url, example being:
<a class="next_page" href="/public/rehome?page=2" rel="next">Next →</a>
<a class="next_page" href="/public/rehomed?page=2" rel="next">Next →</a>
So when I scroll down I just get the following as the links don't exist and getScript fails
$('.pagination').text('Loading.....');
I have implemented @japed's answer but now after the new collection is rendered the pagination will continue to render the whole collection of the db including repeating the ones that where selected for the new collection, it's repeating itself.
How can I ensure that the correct url is generated for my links?
Will paginate allows you to set the params hash so you should be able to change it to use your other controller action like this:
will_paginate(@animals, :params => { :controller => "public", :action => "rehomed" })
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