Generic Infinite Scrolling
I am building an app that has a couple of columns and I only want one column to scroll infinitely. I am trying to hack together a gem free version, but I am a novice with .js or jquery.
My question is this: Is there a way to create pagination with something using find_each and batches....
Post.find_each(:batch_size => 25) do |post|
code...
end
And then trigger another "batch" with some sort of event, number, marker, or scroll event? Maybe something when you hit the 23rd record of each batch is generates a new batch?
Not sure if this is possible. I am just thinking out loud here.
Hey Ryan, thought I'd jump in here... I haven't done pagination in some time, but hopefully this can help!
On the server side, I'd personally I'd use the offset
and limit
query methods, so you can write Post.offset(20).limit(20)
, which will return the second 'batch' of 20 posts. To paginate it, you could pass the page # in the request parameters (params[:page]
) and multiply that by the page size to calculate the offset. Hopefully that makes sense...
With find_each
, you're iterating through all those posts which, unless you actually want to do something with them all, isn't necessary.
As for the client, you're right to use some event as a marker. Using the scroll position is common as that's independent of your layout and you can refine it for your desired experience. To do that, I'd recommend you set a boolean flag to true when the window scrolls, and set an interval timer to handle the pagination requests. Attaching the handler directly to the scroll event isn't great for performance.
Assuming you're using jQuery, you can listen to the scroll event with $(window).scroll(/* set the flag to true */)
and setInterval(/* request posts if a) window scrolled and b) the window is near the bottom */, 250)
to do your magic every 250ms. If the window did scroll, remember to set the flag to false. You can use $(window).scrollTop()
to find the scroll position, and I'll let you find the function for the window height. ;)
Finally, you'll need a page counter that you increase with every request and, as you don't want to reload the page on every request, a .js.erb
view file to load in the new posts.
I hope that helps, let me know if not! :)