# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/responsive # frozen_string_literal: true require 'json' class Pagy # Default :breakpoints VARS[:breakpoints] = { 0 => [1,4,4,1] } # Helper for building the page_nav with javascript. For example: # with an object like: # Pagy.new count:1000, page: 20, breakpoints: {0 => [1,2,2,1], 350 => [2,3,3,2], 550 => [3,4,4,3]} # it returns something like: # { :items => [1, :gap, 18, 19, "20", 21, 22, 50, 2, 17, 23, 49, 3, 16, 24, 48], # :series => { 0 =>[1, :gap, 18, 19, "20", 21, 22, :gap, 50], # 350 =>[1, 2, :gap, 17, 18, 19, "20", 21, 22, 23, :gap, 49, 50], # 550 =>[1, 2, 3, :gap, 16, 17, 18, 19, "20", 21, 22, 23, 24, :gap, 48, 49, 50] }, # :widths => [550, 350, 0] } # where :items is the unordered array union of all the page numbers for all sizes (passed to the PagyResponsive javascript function) # :series is the hash of the series keyed by width (used by the *_responsive helpers to create the JSON string) # :widths is the desc-ordered array of widths (passed to the PagyResponsive javascript function) def responsive @responsive ||= {items: [], series: {}, widths:[]}.tap do |r| @vars[:breakpoints].key?(0) || raise(ArgumentError, "expected :breakpoints to contain the 0 size; got #{@vars[:breakpoint].inspect}") @vars[:breakpoints].each {|width, size| r[:items] |= r[:series][width] = series(size)} r[:widths] = r[:series].keys.sort!{|a,b| b <=> a} end end # Add nav helpers for responsive pagination module Frontend # Generic responsive pagination: it returns the html with the series of links to the pages # we build the tags as a json object string and render them with the PagyResponsive javascript def pagy_nav_responsive(pagy, id=caller(1,1)[0].hash) tags, link, p_prev, p_next, responsive = {}, pagy_link_proc(pagy), pagy.prev, pagy.next, pagy.responsive tags[:prev] = (p_prev ? %(#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'} ) : %(#{pagy_t('pagy.nav.prev')} )) responsive[:items].each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36] tags[item.to_s] = if item.is_a?(Integer); %(#{link.call item} ) # page link elsif item.is_a?(String) ; %(#{item} ) # current page elsif item == :gap ; %(#{pagy_t('pagy.nav.gap')} ) # page gap end end tags[:next] = (p_next ? %(#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}) : %(#{pagy_t('pagy.nav.next')})) script = %() %(#{script}) end # Responsive pagination for bootstrap: it returns the html with the series of links to the pages # we build the tags as a json object string and render them with the PagyResponsive javascript def pagy_nav_bootstrap_responsive(pagy, id=caller(1,1)[0].hash) tags, link, p_prev, p_next, responsive = {}, pagy_link_proc(pagy, 'class="page-link"'), pagy.prev, pagy.next, pagy.responsive tags['prev'] = (p_prev ? %(