Last active
October 20, 2021 19:04
-
-
Save secretpray/245e5f30dafff636a8dcec93ba7a5314 to your computer and use it in GitHub Desktop.
Infinite scrolling with pagination (pagy)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-------------------- 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