Enviornment
Rails 6
Turbolinks
Kaminari
JQuery
class ProductsController < ApplicationController
def index
@products = Product.order(:name).page(params[:page])
end
end
Products table with pagination
<table class="table table-bordered table-sm infinite-scroll">
<thead>
<tr>
<th>Name</th>
<th>UPC</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<% @products.each do |product| %>
<tr>
<td>
<%= product.name %>
</td>
<td>
<%= product.upc %>
</td>
<td>
<%= product.retail_price.format %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= page_entries_info @products %>
<%= paginate @products %>
Wrapping the contents of #page_entries_info inside a CSS class
module ApplicationHelper
def page_entries_info(*)
tag.span(class: 'page-entries-info') { super }
end
end
infinite-scroll.js
initInfiniteScroll = ->
$table = $('.infinite-scroll')
return if $table.length == 0
# Flag for request status
loading = false
# Hide the pagination
$('.page-entries-info, .pagination').hide()
# Add loading message to the bottom of the table
$table.after('<div class="alert alert-light text-center loading">LOADING...</div>')
handleScroll = ->
return if loading
# if next page link exists
if url = $('.pagination .page-link[rel=next]').attr('href')
if $(window).scrollTop() > $(document).height() - $(window).height() - 500
loading = true
ajax(url, {
headers:
# To get HTML response
'Accept' : 'text/html, application/xhtml+xml'
}).then((r) => r.text()).then (html) ->
$html = $('<html />').append(html)
# Append new records to the table
$table.find('tbody').append $html.find('tbody tr')
# Update pagination
$('.pagination').html $html.find('.pagination')
loading = false
else # no more pages to load
$(window).off('scroll', handleScroll)
$('.loading').remove()
$('.page-entries-info').show()
# show a message, when all the records are loaded
if $('.pagination').length > 0
pageTitle = document.getElementsByClassName('page-title')[0].innerText.toLowerCase()
totalRecords = $('.page-entries-info b:last').text()
$('.page-entries-info').html "Displaying <b>all #{totalRecords}</b> #{pageTitle}"
$(window).on('scroll', handleScroll)
handleScroll()
window.addEventListener 'turbolinks:load', ->
initInfiniteScroll()
# To prevent multiple scroll events on turbolinks:load
document.addEventListener 'turbolinks:before-render', ->
$(window).off('scroll')
🙂