Skip to content

Instantly share code, notes, and snippets.

@secretpray
Last active October 20, 2021 19:04
Show Gist options
  • Save secretpray/245e5f30dafff636a8dcec93ba7a5314 to your computer and use it in GitHub Desktop.
Save secretpray/245e5f30dafff636a8dcec93ba7a5314 to your computer and use it in GitHub Desktop.
Infinite scrolling with pagination (pagy)
-------------------- model Recipe + Favorites -----------------------
1. Add pagination:
===============
Gemfile
-------
gem 'pagy'
$bundle
2. Add to:
==========
config/initializers/pagy.rb
---------------------------
require 'pagy/extras/bootstrap'
application_controller.rb
-------------------------
include Pagy::Backend
application_helper.rb
---------------------
include Pagy::Frontend
recipes_controller.rb
---------------------
def index
@pagy, @recipes = pagy(Recipe.all, items: 10)
end
# optional favorites
def favorites
@pagy, @favorites = pagy(current_user.favorites, items: 6)
end
app/views/recipes/index.html.erb
--------------------------------
<div class='d-flex justify-content-center pagination-link'>
<%== pagy_bootstrap_nav(@pagy).html_safe %>
</div>
# optional favorites
app/views/recipes/favorites.html.erb
-------------------------------------
<div class='d-flex justify-content-center mt-3 pagination-link'>
<%== pagy_bootstrap_nav(@pagy).html_safe %>
</div>
Render recipe/favorite only in patial!!!!!!! Like this:
app/views/recipes/index.html.erb (table)
----------------------------------------
<tbody class='infinity-scroll-target'>
<%= render 'recipes/recipe', locals: { recipes: @recipes } %>
</tbody>
# optional
app/views/recipes/favorites.html.erb (list/card)
------------------------------------------------
<div class='row justify-content-center mt-4 infinity-scroll-target' id='favorite_container'>
<%= render 'recipes/favorite', favorites: @favorites %>
</div>
partials:
app/views/recipes/_recipe.html.erb
app/views/recipes/_favorite.html.erb
2. Infinite Scroll
2.1 Create file:
app/javascript/utilities/infinite_scroll.js
--------------------------------------------
document.addEventListener("turbolinks:load", () => {
let options = {
root: null,
rootMargins: "0px",
threshold: 0.5
};
const observer = new IntersectionObserver(handleIntersect, options);
// check <footer>!
observer.observe(document.querySelector("footer"));
});
function handleIntersect(entries) {
if (entries[0].isIntersecting) {
getData();
}
}
function getData() {
// recipesTarget - target for inject next page
var recipesTarget = document.querySelector('.infinity-scroll-target')
// paginationTarget - target for replace pagination
let paginationTarget = document.querySelector('.pagination-link')
let next_page = document.querySelector("a[rel='next']")
if (next_page == null) { return }
let url = next_page.href
Rails.ajax({
type: 'GET',
url: url,
dataType: 'json',
success: (data) => {
// recipesTarget.insertAdjacentHTML('beforeend', data.entries)
recipesTarget.innerHTML += data.entries
paginationTarget.innerHTML = data.pagination
}
})
}
2.2 Add line to app/javascript/packs/application.js
----------------------------------------------------
require("utilities/infinite_scroll")
2.3 Add to Recipe Controller
app/controllers/recipes_controller.rb
--------------------------------------
respond_to do |format|
format.html
format.json { render json: { entries: render_to_string(partial: 'recipes/recipe', locals: { recipes: @recipes }, formats: [:html]), pagination: view_context.pagy_bootstrap_nav(@pagy)}}
end
# optinal (favorites)
respond_to do |format|
format.html
format.json { render json: { entries: render_to_string(partial: 'recipes/favorite', locals: { favorites: @favorites }, formats: [:html]), pagination: view_context.pagy_bootstrap_nav(@pagy)}}
end
2.4 Check this!!!
- the script checks the page scroll to <footer>;
- the url of the new page is taken from the pagy next_link;
- pagination should be wrapped in a div with the "pagination-link" class;
- the new html list (recipes/favorites) is inserted into a div with the "infinity-scroll-target" class
Worked sample (Stage_37+): https://github.com/secretpray/Recipes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment