Before we begin, I need to acknowledge that this is not a full proof solution. There's a lot of features lacking.
However, my goal was to achieve a basic infinite scrolling using only Turbo, without any JavaScript or Stimulus.
You can view it Live at: https://games.directory/u/pacmakaveli/c/library
For this, I'm using Rails, Pagy, TailwindCSS, and, Turbo Rails.
Implementation is quite simple, knowing that Turbo's turbo_frame_tag(loading: :lazy)
is only loaded when the element is visible in the DOM.
def library
@pagy, @collections = pagy(user.collections, items: 18, page: params[:page])
if params[:page]
render(turbo_stream: turbo_stream.append('user:collections:library', partial: 'user/collections/collections.library'))
# Ensure we return, otherwise it will complain about double rendering!
#
return
end
render(template: 'user/collections/index.library')
end
Because I'm not using Rails's naming convention when it comes to partials, I have to manually declare the render.
In most apps this won't probably be needed.
Next up is the views:
This is my index.library.slim
view:
.cell-auto
.column
= turbo_frame_tag('user:collections:library') do
= render(partial: 'collections.library')
And this is the _collections.library.slim
partial:
.grid.grid-cols-6 class='gap-0.5'
- @collections.each do |collection|
= turbo_frame_tag(collection, class: 'col-span-1') do
= link_to(user_collection_url(user, collection), class: 'column card relative', target: :_top) do
= lazy_image_tag(collection.cover, class: 'w-full h-60 rounded-md object-cover') if collection.cover.attached?
= collection.name unless collection.cover.attached?
.bg-main.rounded.bg-opacity-50.w-10.h-10.absolute.z-10 class='bottom-1 left-1 p-1.5'
= image_tag("logos/#{ collection.network.class.name.split('::').first.downcase }", class: 'w-full h-full')
= turbo_frame_tag(@pagy.next, loading: :lazy, src: library_user_collections_path(page: @pagy.next)) if @pagy.next
The magic is on the last line, where turbo_frame_tag
will load the next set of results when it becomes visible in the DOM.
And that's it! Turbo is quite powerful, in my opinion, when it comes to stuff like this.
In the near future I want to explore this and introduce a couple of new features, like the pagination on the page reducing the number of pages as it loads, the URL adding the page number on each load and, probably the most important one, removing previous entries from the DOM as the page keeps loading more entries.
It tends to become really slow when you have too many library items loaded on the page since the Images are high quality.
Let me know what you think!
:)
Top comments (0)