#114 Endless Page (revised)
Dec 16, 2011 | 7 minutes | Ajax
Transform traditional pagination into infinite scrolling which will automatically fetch more records when the user scrolls down to the bottom of the page.
- source codeProject Files in Zip (86.7 KB)
- mp4Full Size H.264 Video (17.9 MB)
- m4vSmaller H.264 Video (9.39 MB)
- webmFull Size VP8 Video (10.7 MB)
- ogvFull Size Theora Video (20.9 MB)
Great screencast as usual, wondering though the following:
1) This is similar to the approach you showed in the sharing mustache templates screencast, wondering given that it essentially achieves the same objective when you would choose to use this simpler jquery approach vs using mustache template, ie what are the pros and cons of each.
2) any hints how one can test endless scrolling in rspec/capybara integration tests, specifically, any ideas as to how you would simulate a scroll near the bottom in capybara?
Nice revision. In fact, I am creating a web app for my company (unbeknownst to them) that connects to a legacy DB and one of our tables has hundreds of rows. This is going to look good on that page!
I am so glad I signed up for your Railscasts. Keep them coming!
I tried this for some reason. my index.js.erb is not being listened to but i see it on my terminal " Processing by BusinessesController#index as HTML" .
All the products (businesses) are being loaded at once. I am not sure what i'm missing, any ideas?
Interesting, i was appending a class instead on an id and that was causing the problem. I didn't think this mattered at all. Strange.
Nice an neat except for this trick with multiple scroll events being triggered. I think it would be much cleaner to unbind the scroll event till we get the results and once more products are loaded, bind it again.
You are right. Sometimes there where multiple ajax requests.
This script only fires one time, removes the eventlistener on scroll end adds it when finished.
This works with turbolinks.
Railscast is the best $9 I spend every month. I would love to pay $50 and get one episode each weekday.
9$ is best for one month for me.. :) I assume that the price will be same in 10 years ;) But you should also denote Ryan for 50$.
Excellent episode Ryan, I really love the fallback functionality remaining intact. Definitely going to use this.
Couldn't agree more - love the thought that's gone into the fallback. Will be on my current project soon! :)
The main problem - how can i give a link to a some comment?
I've wanted to implement this for some time now but had a few questions:
1) Should the URL change? i.e. /?page=2
2) What happens when you click a product then click back, are all the same products still loaded? I have seen this problem with a couple websites that use Endless Page.
great question jDeppen; Ryan, or other commenters come across any solutions for question #2?
Id love to know as well.. the back button is problematic
Back button ... I'd like to know as well!
Some people use pop-ups rather than going to another page. That seems to work fine. But if you really need to go to another page, then I'm not sure. I'll try this tonight.
You can implement it with the history object, and it will solve problems with the back button, bookmarks etc.
I like endless scrolling except for one gotcha - it makes it very hard for users to access links on the page footer. One way to work around this is to use the jQuery Waypoints plugin to ensure that the footer is always displayed (despite the endless scrolling).
Static footers...if you really want it.
See this page about performance impacts of adding attaching a handler to window scroll: http://ejohn.org/blog/learning-from-twitter/
this is a good read on the subject, thanks for posting!
Thanks for sharing this ! It turns out there is a transition between the paginator pages line is being shown and removed for adding next page results. And my client complained a lot for this.
I have a
respond_toblock in the index action of my controller, so I had to add
format.jsto render the RJS template associated with this action (i.e.
Wow thank you @Barwin! I've been wrestling with this for the past 2 days and just couldn't figure out what I was doing wrong. I also had a respond_to block and just needed to pop in a
format.js. Works like a champ.
Thanks from me too! I wasn't close to finding a solution for this issue until I read your comment.
I decided against the Endless Page feature, and instead slightly adapted this RailsCast's code to provide a "Show more results" link, which would append results in much the same manner, but instead by click rather than reached-bottom-of-page detection.
The main change is the addition of the prepend line in
Regarding the view, I only added a surrounding div:
products/index.js.erbI just changed the
$('#append_and_paginate').remove();so that both the "Show more results" link and pagination is removed when no more results are available.
Of course some css had to be added to make things look nice.
I like your approach. Thanks for sharing.
+1. nice alternative. Still prefer the endless scrolling feature for image heavy sites. So much easier to handle.
ah I was looking for this for half a day! :) Thank you!!
Thanks for posting this. Very useul.
your method is really nice ,,,I tried it ,,but with internationalization ,,,its not working ,,,on console it gives me the get method for url is ok ..but no appending happens for pagination ...I am using kaminari so I replaced .next_page with .next a , and I used
your method is really nice ,,,I tried it ,,but with internationalization ,,,its not working ,,,on console it gives me the get method for url is ok ..but no appending happens for pagination ...I am using kaminari so , and I used
I knew my problem now ...your idea is really cool and saved many days of search...
I used next_page with a ,,,but after adding 'a' its working now
thanks @Bardwin for sharing! This works great but I want to hide the pagination on every page vs just the very last page and simply have the "Show more products" button on each page. Any ideas on how to accomplish that?
Currently my index.js.erb is below
$('#items').append('<%= j render('items') %>');
<% if @items.next_page %>
$('.pagination').replaceWith('<%= j will_paginate(@items) %>');
<% else %>
<% end %>
<% sleep 1 %>
Simple and useful.
Only feedback is that the products/index.js.erb in show notes is missing the sleep call.
Thanks for this ryan, amazing as always!
I used this with Kaminari along with using a script to see if the pagination links are in the window view area (since I was working with a table that is in the middle of the page)
Coffee Script below:
And in the index.js.erb file:
@pages.current_page < @pages.num_pagessince I couldn't get the
@pages.next?method working with collections. Hopefully it will work in a future release.
In case anyone else is using Kaminari - you might need to change '.next_page' to '.next' :)
This was extremely helpful, @Pranay. Thanks!
I posted a question on Stack Overflow that is related to this episode. I'd be much obliged if anyone could provide some insight.
rails infinite scroll ajax actions on page > 1 items
Is there any way to use jQuery to filter items that are on next page or subsequent pages before you have scrolled to them? The use case would be a view of thumbnails that the user can scroll through with a list of tags above them that the user could use to narrow down the set of results. The problem I am having is not being able to return the correct results if the user has not scrolled down the page.
I guess Google would index the endless page as multiple pages (products?page=1, products?page=2) by following the links in the will_paginate nav.
@brucepom: Add rel="nofollow" to the pagination links, so Google will not index the paginated list. In addition, add a sitemap.xml to your site to tell Google the single pages.
I keep getting weird errors in rails 3 when using the render method. Also I don't have access to the instance variable. I wrote my issue on stack overflow if any you guys would have the time to have a look at my code. Please
Is there an issue with using render in rails 3 in js files?
How can u get rid of the "page=1" on the url link?
Getting an error on this line (in the coffeescript file)
The error message says: Uncaught TypeError: Cannot read property 'length' of null
What could have gone wrong? The div exists in my index :(
This approach doesn't seem to work on all mobile browsers. It worked in Chrome for iPhone, but not in Safari.
This was very helpful. Thanks!
Can partials be cached with this approach?
In chrome however it seems to 'stutter' or 'jump' when it loads more. I've removed all other css, trying to rule any wierdness out.
It does work perfectly in Firefox however. I disabled any extensions as well. Other sites like facebook.com or fab.com are super smooth in chrome, is this normal using this method?
My mistake, I found that I was pulling an association in the partial, which wasn't included on the order method.
Updated to Book.order("name").includes(:authors) and it works like a charm! Way smoother.
doesnt work, wasted $9
sorry about my comment, I was very angry that day; it works fine and the vids are great
it doesnt work
Great tutorial. I couldn't get it to work until I changed line 4 in products.js.coffee from
url = $('.pagination .next_page').attr('href')
url = $('.pagination .next_page a').attr('href')
otherwise it doesn't pull the href attribute from the link.
Thanks for the tutorial!
For some reason some of my posts are getting duplicated when the next page of posts are getting loaded. Has anyone had this happen to them??
Well the problem, weirdly, was i hid the pagination class in my css because I wasn't able to get the pagination links to disappear and replace with the text "Fetching more products"...so now it works fine but the pagination is still showing at the bottom of the page before the next page gets loaded
I managed to do it with an "index.js.erb" file in Rails 4. Just add this coffeescript:
This loads the next page then uses the pagination on the newly loaded page until there are no more next pages. Just replace "#articles" with the id of your container in the script. Skip the index.js.erb and respond_to jazz.
Thank you for this!
Has anyone every tried implementing an endless scroll up? Trying to do this for an e-commerce site, it mostly works but there are a few bugs that need to worked out. If anyone has done anything like this, I would love to know how you went about it. Thanks
Thanks for tutorial. I did infinite scrolling for my Art Asian site. However, when I go to a product page, then hit back button, it not keep same content and position. Is there any plugin to do that same as Pinterest or Polyvore
Thanks for another great tutorial Ryan! Works great with Rails 4.
For anyone that is interested, here's a slick way to replace the generic loading text with an animated gif.
You can create and download your own loading animation here:
You can add the downloaded gif to your images directory under assets. Rails knows to look there.
works fantastic with Kaminari AND Rails 4 with turbolinks. even after so many years. Thanks Ryan!
Tip: If you're using Kaminari, just add class="next_page" to the next page link in the Kaminari view
How to use endless loading with group_by . I am using will_paginate. But when add group_by it show "undefined method 'count' for AR Relation.