Skip to content

Commit

Permalink
renamed multi_series > sequels and relative js arguments and variable…
Browse files Browse the repository at this point in the history
…s; renamed :sizes > :steps; updated nav test cases
  • Loading branch information
ddnexus committed Apr 28, 2019
1 parent 901f779 commit aa1aad9
Show file tree
Hide file tree
Showing 16 changed files with 85 additions and 81 deletions.
29 changes: 16 additions & 13 deletions docs/extras/navs.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,45 +57,49 @@ Other extras provide also the following framework-styled helpers:

| Variable | Description | Default |
|:---------|:------------------------------------------------------------------|:--------|
| `:sizes` | Hash variable to control multipe pagy `:size` at different widths | `nil` |
| `:steps` | Hash variable to control multipe pagy `:size` at different widths | `false` |

### :sizes
### :steps

The `:sizes` variable is an optional non-core variable used by the `pagy*_nav_js` navs. If it's defined, it allows you to control multiple pagy `:size` at different widths. If it's `nil`, the `pagy*_nav_js` will behave exactly as a static `pagy*_nav` respecting the single `:size` variable, just faster and lighter.
The `:steps` is an optional non-core variable used by the `pagy*_nav_js` navs. If it's `false`, the `pagy*_nav_js` will behave exactly as a static `pagy*_nav` respecting the single `:size` variable, just faster and lighter. If it's defined as a hash, it allows you to control multiple pagy `:size` at different widths.

The `:sizes` variable is a hash where the keys are integers representing the widths in pixels and the values are the Pagy `:size` variables to be applied for that width.
You can set the `:steps` as a hash where the keys are integers representing the widths in pixels and the values are the Pagy `:size` variables to be applied for that width.

As usual, depending on the scope of the customization, you can set the variables globally or for a single pagy instance.

For example:

```ruby
# globally
Pagy::VARS[:sizes] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] }
Pagy::VARS[:steps] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] }

# or for a single instance
pagy, records = pagy(collection, sizes: { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } )
pagy, records = pagy(collection, steps: { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } )

# or use the :size as any static pagy*_nav
pagy, records = pagy(collection, steps: false )

```

The above statement means that from `0` to `540` pixels width, Pagy will use the `[2,3,3,2]` size, from `540` to `720` it will use the `[3,5,5,3]` size and over `720` it will use the `[5,7,7,5]` size. (Read more about the `:size` variable in the [How to control the page links](../how-to.md#controlling-the-page-links) section).

**IMPORTANT**: You can set any number of sizes with any arbitrary width/size. The only requirement is that the `:sizes` hash (when defined) must contain always the `0` width or an `ArgumentError` exception will be raises.
**IMPORTANT**: You can set any number of steps with any arbitrary width/size. The only requirement is that the `:steps` hash must contain always the `0` width or an `ArgumentError` exception will be raises.

#### Setting the right sizes

Setting the widths and sizes can create a nice transition between sizes or some apparently erratic behavior.
Setting the widths and sizes can create a nice transition between widths or some apparently erratic behavior.

Here is what you should consider/ensure:

1. The pagy size changes in discrete steps: each widht/size pair in your `:sizes` represents a step.
1. The pagy size changes in discrete `:steps`, defined by the width/size pairs.

2. The transition from one size to another depends on the width available to the pagy nav. That width is the _internal available width_ of its container (excluding eventual horizontal padding).
2. The automatic transition from one size to another depends on the width available to the pagy nav. That width is the _internal available width_ of its container (excluding eventual horizontal padding).

3. You should ensure that each pagy `:size` produces a nav that can be contained in its width.
3. You should ensure that - for each step - each pagy `:size` produces a nav that can be contained in its width.

4. You should ensure that the minimum internal width for the container div be equal (or a bit bigger) to the smaller positive width. (`540` pixels in our previous example).

5. If the container width snaps to specific widths in discrete steps, you should sync the quantity and widths of the pagy `:sizes` to the quantity and internal widths for each discrete step of the container.
5. If the container width snaps to specific widths in discrete steps, you should sync the quantity and widths of the pagy `:steps` to the quantity and internal widths for each discrete step of the container.

## Methods

Expand All @@ -107,7 +111,6 @@ It can take an extra `id` argument, which is used to build the `id` attribute of

**Notice**: passing an explicit id is also a bit faster than having pagy to generate one.


# Javascript Combo Navs

The `pagy*_combo_nav_js` (implemented by this extra or by other frontend extras) offers an alternative pagination UI that combines navigation and pagination info in a single compact element.
Expand Down
4 changes: 2 additions & 2 deletions lib/config/pagy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@
# require 'pagy/extras/semantic'

# Multi size var used by the *_nav_js helpers
# See https://ddnexus.github.io/pagy/extras/navs#sizes
# Pagy::VARS[:sizes] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } # example
# See https://ddnexus.github.io/pagy/extras/navs#steps
# Pagy::VARS[:steps] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } # example


# Feature Extras
Expand Down
12 changes: 6 additions & 6 deletions lib/javascripts/pagy.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ Pagy.init = function(arg){
}
};

Pagy.nav = function(id, marker, tags, series){
Pagy.nav = function(id, marker, tags, sequels){
var pagyEl = document.getElementById(id),
container = pagyEl.parentElement,
lastWidth = undefined,
timeoutId = 0,
marker_re = new RegExp(marker, 'g'),
widths = [];
for (var width in series) { widths.push(parseInt(width)) } // fine with series structure
for (var width in sequels) { widths.push(parseInt(width)) } // fine with sequels structure
widths.sort(function(a, b){return b-a});

var render = function(){
Expand All @@ -29,10 +29,10 @@ Pagy.nav = function(id, marker, tags, series){
}
if (width !== lastWidth) {
while (pagyEl.firstChild) { pagyEl.removeChild(pagyEl.firstChild) }
var html = tags.before,
items = series[width];
for (i = 0, len = items.length; i < len; i++) {
var item = items[i];
var html = tags.before,
series = sequels[width];
for (i = 0, len = series.length; i < len; i++) {
var item = series[i];
if (typeof(item) === 'number') { html += tags.link.replace(marker_re, item) }
else if (item === 'gap') { html += tags.gap }
else if (typeof(item) === 'string') { html += tags.active.replace(marker_re, item) }
Expand Down
2 changes: 1 addition & 1 deletion lib/pagy/extras/bootstrap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def pagy_bootstrap_nav_js(pagy, id=pagy_id)
'gap' => %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.gap')}</a></li>),
'after' => p_next ? %(<li class="page-item next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li></ul>)
: %(<li class="page-item next disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.next')}</a></li></ul>) }
%(<nav id="#{id}" class="pagy-bootstrap-nav-js pagination" role="navigation" aria-label="pager"></nav>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.multi_series)})
%(<nav id="#{id}" class="pagy-bootstrap-nav-js pagination" role="navigation" aria-label="pager"></nav>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.sequels)})
end

# Javascript combo pagination for bootstrap: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
Expand Down
2 changes: 1 addition & 1 deletion lib/pagy/extras/bulma.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def pagy_bulma_nav_js(pagy, id=pagy_id)
'active' => %(<li>#{link.call(MARKER, MARKER, %(class="pagination-link is-current" aria-current="page" aria-label="page #{MARKER}"))}</li>),
'gap' => %(<li><span class="pagination-ellipsis">#{pagy_t('pagy.nav.gap')}</span></li>),
'after' => '</ul>' }
%(<nav id="#{id}" class="pagy-bulma-nav-js pagination is-centered" role="navigation" aria-label="pagination"></nav>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.multi_series)})
%(<nav id="#{id}" class="pagy-bulma-nav-js pagination is-centered" role="navigation" aria-label="pagination"></nav>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.sequels)})
end

# Javascript combo pagination for Bulma: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
Expand Down
2 changes: 1 addition & 1 deletion lib/pagy/extras/foundation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def pagy_foundation_nav_js(pagy, id=pagy_id)
'after' => ( (p_next ? %(<li class="next">#{link.call(p_next, pagy_t('pagy.nav.next'), 'aria-label="next"')}</li>)
: %(<li class="next disabled">#{pagy_t('pagy.nav.next')}</li>)) \
+ '</ul>' ) }
%(<nav id="#{id}" class="pagy-foundation-nav-js" role="navigation" aria-label="Pagination"></nav>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.multi_series)})
%(<nav id="#{id}" class="pagy-foundation-nav-js" role="navigation" aria-label="Pagination"></nav>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.sequels)})
end

# Javascript combo pagination for Foundation: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
Expand Down
2 changes: 1 addition & 1 deletion lib/pagy/extras/materialize.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def pagy_materialize_nav_js(pagy, id=pagy_id)
'after' => ( (p_next ? %(<li class="waves-effect next">#{link.call(p_next, '<i class="material-icons">chevron_right</i>', 'aria-label="next"')}</li>)
: %(<li class="next disabled"><a href="#"><i class="material-icons">chevron_right</i></a></li>)) \
+ '</ul>' ) }
%(<div id="#{id}" class="pagy-materialize-nav-js" role="navigation" aria-label="pager"></div>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.multi_series)})
%(<div id="#{id}" class="pagy-materialize-nav-js" role="navigation" aria-label="pager"></div>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.sequels)})
end

# Javascript combo pagination for materialize: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
Expand Down
2 changes: 1 addition & 1 deletion lib/pagy/extras/navs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def pagy_nav_js(pagy, id=pagy_id)
'gap' => %(<span class="page gap">#{pagy_t('pagy.nav.gap')}</span> ),
'after' => p_next ? %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
: %(<span class="page next disabled">#{pagy_t('pagy.nav.next')}</span>) }
%(<nav id="#{id}" class="pagy-nav-js pagination" role="navigation" aria-label="pager"></nav>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.multi_series)})
%(<nav id="#{id}" class="pagy-nav-js pagination" role="navigation" aria-label="pager"></nav>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.sequels)})
end

# Javascript combo pagination: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
Expand Down
2 changes: 1 addition & 1 deletion lib/pagy/extras/semantic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def pagy_semantic_nav_js(pagy, id=pagy_id)
'gap' => %(<div class="disabled item">#{pagy_t('pagy.nav.gap')}</div>),
'after' => (p_next ? %(#{link.call(p_next, '<i class="right small chevron icon"></i>', 'aria-label="next"')})
: %(<div class="item disabled"><i class="right small chevron icon"></i></div>)) }
%(<div id="#{id}" class="pagy-semantic-nav-js ui pagination menu" role="navigation" aria-label="pager"></div>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.multi_series)})
%(<div id="#{id}" class="pagy-semantic-nav-js ui pagination menu" role="navigation" aria-label="pager"></div>#{pagy_json_tag(:nav, id, MARKER, tags, pagy.sequels)})
end

# Combo pagination for semantic: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
Expand Down
23 changes: 12 additions & 11 deletions lib/pagy/extras/shared.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@

class Pagy

# default :sizes nil will use {0 => :size}
VARS[:sizes] = nil
# default :steps: false will use {0 => @vars[:size]}
VARS[:steps] = false

# The multiple series generated by the :sizes hash
# If :sizes is nil it will use the single {0 => @vars[:size]} pair
# `Pagy` instance method used by the `pagy*_nav_js` helpers.
# It returns the sequels of width/series generated from the :steps hash
# Example:
# >> pagy = Pagy.new(count:1000, page: 20, sizes: {0 => [1,2,2,1], 350 => [2,3,3,2], 550 => [3,4,4,3]})
# >> pagy.multi_series
# >> pagy = Pagy.new(count:1000, page: 20, steps: {0 => [1,2,2,1], 350 => [2,3,3,2], 550 => [3,4,4,3]})
# >> pagy.sequels
# #=> { "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] }
def multi_series
sizes = @vars[:sizes] || {0 => @vars[:size]}
sizes.key?(0) or raise(ArgumentError, "expected :sizes to contain the 0 size; got #{sizes.inspect}")
{}.tap {|multi_series| sizes.each {|width, size| multi_series[width.to_s] = series(size)}}
# Notice: if :steps is false it will use the single {0 => @vars[:size]} size
def sequels
steps = @vars[:steps] || {0 => @vars[:size]}
steps.key?(0) or raise(ArgumentError, "expected :steps to define the 0 width; got #{steps.inspect}")
sequels = {}; steps.each {|width, size| sequels[width.to_s] = series(size)}; sequels
end

module Frontend
Expand All @@ -29,7 +30,7 @@ module Frontend
def pagy_json_tag(*args)
%(<script type="application/json" class="pagy-json">#{Oj.dump(args, mode: :strict)}</script>)
end
else # use slower standard json
else
require 'json'
# returns a script tag with the JSON-serialized args generated with the slower to_json
def pagy_json_tag(*args)
Expand Down
Loading

0 comments on commit aa1aad9

Please sign in to comment.