Skip to content

Commit

Permalink
added support extra
Browse files Browse the repository at this point in the history
  • Loading branch information
ddnexus committed Dec 3, 2018
1 parent 055af34 commit 2bdb1e5
Show file tree
Hide file tree
Showing 8 changed files with 376 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -110,6 +110,7 @@ Use the official extras, or write your own in just a few lines. Extras add speci
- [i18n](http://ddnexus.github.io/pagy/extras/i18n): Use the `I18n` gem instead of the pagy implementation
- [items](http://ddnexus.github.io/pagy/extras/items): Allow the client to request a custom number of items per page with an optional selector UI
- [overflow](http://ddnexus.github.io/pagy/extras/overflow): Allow for easy handling of overflowing pages
- [support](http://ddnexus.github.io/pagy/extras/support): Extra support for features like: incremental, infinite, auto-scroll pagination
- [trim](http://ddnexus.github.io/pagy/extras/trim): Remove the `page=1` param from the first page link

### Alternative components
Expand Down
3 changes: 2 additions & 1 deletion docs/_layouts/default.html
Expand Up @@ -37,7 +37,7 @@ <h1 id="site-title">{{ site.title | default: site.github.repository_name }} <a c
<a href="{{ site.baseurl }}/extras/array"><p class="indent1" {% if page.title == 'Array' %}id="active"{% endif %} >Array</p></a>
<a href="{{ site.baseurl }}/extras/bootstrap"><p class="indent1" {% if page.title == 'Bootstrap' %}id="active"{% endif %} >Bootstrap</p></a>
<a href="{{ site.baseurl }}/extras/bulma"><p class="indent1" {% if page.title == 'Bulma' %}id="active"{% endif %} >Bulma</p></a>
<a href="{{ site.baseurl }}/extras/countless"><p class="indent1" {% if page.title == 'countless' %}id="active"{% endif %} >Countless</p></a>
<a href="{{ site.baseurl }}/extras/countless"><p class="indent1" {% if page.title == 'Countless' %}id="active"{% endif %} >Countless</p></a>
<a href="{{ site.baseurl }}/extras/elasticsearch_rails"><p class="indent1" {% if page.title == 'Elasticsearch Rails' %}id="active"{% endif %} >Elasticsearch Rails</p></a>
<a href="{{ site.baseurl }}/extras/foundation"><p class="indent1" {% if page.title == 'Foundation' %}id="active"{% endif %} >Foundation</p></a>
<a href="{{ site.baseurl }}/extras/i18n"><p class="indent1" {% if page.title == 'I18n' %}id="active"{% endif %} >I18n</p></a>
Expand All @@ -47,6 +47,7 @@ <h1 id="site-title">{{ site.title | default: site.github.repository_name }} <a c
<a href="{{ site.baseurl }}/extras/plain"><p class="indent1" {% if page.title == 'Plain' %}id="active"{% endif %} >Plain</p></a>
<a href="{{ site.baseurl }}/extras/searchkick"><p class="indent1" {% if page.title == 'Searchkick' %}id="active"{% endif %} >Searchkick</p></a>
<a href="{{ site.baseurl }}/extras/semantic"><p class="indent1" {% if page.title == 'Semantic' %}id="active"{% endif %} >Semantic</p></a>
<a href="{{ site.baseurl }}/extras/support"><p class="indent1" {% if page.title == 'Support' %}id="active"{% endif %} >Support</p></a>
<a href="{{ site.baseurl }}/extras/trim"><p class="indent1" {% if page.title == 'Trim' %}id="active"{% endif %} >Trim</p></a>
<a href="{{ site.baseurl }}/migration-tips"><p {% if page.title == 'Migration Tips' %}id="active"{% endif %} >Migration Tips</p></a>
<p id="gitter-support"><a href="https://gitter.im/ruby-pagy/Lobby" rel="nofollow" target="_blank">&gt; Chat Support on Gitter &lt;</a></p>
Expand Down
10 changes: 9 additions & 1 deletion docs/extras.md
Expand Up @@ -20,6 +20,7 @@ Pagy comes with a few optional extensions/extras:
| `plain` | Add responsive and compact plain/unstyled helpers | [plain.rb](https://github.com/ddnexus/pagy/blob/master/lib/pagy/extras/plain.rb), [documentation](extras/plain.md) |
| `searchkick` | Paginate arrays efficiently avoiding expensive array-wrapping and without overriding | [searchkick.rb](https://github.com/ddnexus/pagy/blob/master/lib/pagy/extras/searchkick.rb), [documentation](extras/searchkick.md) |
| `semantic` | Add nav, responsive and compact helpers for the Semantic UI CSS [pagination component](https://semantic-ui.com/collections/menu.html) | [semantic.rb](https://github.com/ddnexus/pagy/blob/master/lib/pagy/extras/semantic.rb), [documentation](extras/semantic.md) |
| `support` | Extra support for features like: incremental, infinite, auto-scroll pagination | [support.rb](https://github.com/ddnexus/pagy/blob/master/lib/pagy/extras/support.rb), [documentation](extras/support.md) |
| `trim` | Remove the `page=1` param from links | [trim.rb](https://github.com/ddnexus/pagy/blob/master/lib/pagy/extras/trim.rb), [documentation](extras/trim.md) |

## Synopsis
Expand All @@ -41,7 +42,14 @@ All the added methods are documented in the respective extras.

## Javascript

The `compact` and `responsive` navs, and the `items` extra use javascript, so if you use any of them you should load the [pagy.js](https://github.com/ddnexus/pagy/blob/master/lib/javascripts/pagy.js) file, and run `Pagy.init()` on window load.
A few helpers use javascript:

- `pagy_*_compact_nav`
- `pagy_*_responsive_nav`
- `pagy_items_selector`
- `pagy_apply_init_tag`

If you use any of them you should load the [pagy.js](https://github.com/ddnexus/pagy/blob/master/lib/javascripts/pagy.js) file, and run `Pagy.init()` on window load.

### In rails apps

Expand Down
112 changes: 112 additions & 0 deletions docs/extras/support.md
@@ -0,0 +1,112 @@
---
title: Support
---
# Support Extra

This extra adds support for features like countless or navless pagination, where you don't need the full link bar but only a simple `next` or `prev` link or no link at all (like for auto-scroll).

It also provides a couple of helpers to setup you own custom javascript components.

## Synopsis

See [extras](../extras.md) for general usage info.

In the `pagy.rb` initializer:

```ruby
require 'pagy/extras/support'
```

## Support for alternative pagination types and features

Besides the classic navbar pagination, the `compact` and the `responsive` UI components, Pagy offers a few helpers to support a few alternative types of pagination and related features.

### Countless

You can totally avoid one query per render by using the [countless](countless.md) extra. It has a few limitation, but still supports navbar links (see also [Pagy::Countless](../api/countless.md) for more details).

### Navless/incremental

If you don't need the navbar you can just set the `:size` variable to an empty value and the page links will be skipped from the rendering. That works with `Pagy` and `Pagy:Countless` instances. All the `*nav` helpers will render only the `prev` and `next` links/buttons, allowing for a manual incremental pagination.

You can also use the `pagy_prev_link` and `pagy_next_link` helpers provided by this extra, mostly useful if you also use the `countless` extra.

### Circular/Infinite

This type of pagination sets the `next` page to `1` when the current page is the last page, allowing an infinite loop through the pages.

For example, it is often used to show a few suggestions of "similar products" in a horizontal stripe of just a few page of a few items each. Clicking on next will continue to loop through.

For example:

```ruby
@pagy, @suggestions = Pagy.new(count: 25, items: 5, cycle: true)
```

Passing a forced `:count` of 25 will generate 5 pages of 5 items each that will always have a next page. Regardless the actual collection count, you will show the first 25 items of the collection, looping in stripes of 5 items each.

You may want to combine it with something like:

```erb
<%== pagy_next_link(@pagy, 'More...')
```

### Auto-scroll

Pagy supports auto-scroll pagination by providing the `pagy_apply_init_tag` helper, which initializes your custom pagination elements by calling your custom defined javascript function at page load.

### Custom UIs

You can use the `pagy_prev_url` and `pagy_next_url` to build your own links or buttons. Besides, with the `pagy_apply_init_tag` and `pagy_serialized` helpers you can also setup you own custom javascript components.

## Methods

### pagy_prev_url(pagy)

Returns the url for the previous page. Useful to build minimalistic UIs that don't use nav bar links (e.g. `countless` extra).

### pagy_next_url(pagy)

Returns the url for the next page. Useful to build minimalistic UIs that don't use nav bar links (e.g. `countless` extra).

### pagy_prev_link(pagy, text=pagy_t('pagy.nav.prev'), link_extra='')

Returns the link for the next page. It is the same prev link string which is part of the `pagy_nav` helper.

Useful to build minimalistic helpers UIs that don't use nav bar links (e.g. `countless` extra).

### pagy_next_link(pagy, text=pagy_t('pagy.nav.next'), link_extra='')

Returns the link for the next page. It is the same next link string which is part of the `pagy_nav` helper.

Useful to build minimalistic helpers UIs that don't use nav bar links (e.g. `countless` extra).

### pagy_serialized(pagy)

Returns a hash with all the instance variables, series, prev_url and next_url of the `pagy` argument. Useful to use in some client-side javascript. It's the default payload of `pagy_apply_init_tag`.

### pagy_apply_init_tag(pagy, function, payload=...)

This is a multi-purpose helper that generates a JSON tag that will be loaded and exececuted by the `Pagy.init` javascript function at document load (see [Javascript](../extras.md#javascript)).

The method requires a pagy object, a javascript function name and accepts an optional payload (default to the hash returned by `pagy_serialized` method) that will get passed to the function. For example:

```ryby
# this uses the serialized pagy object as the default payload
pagy_apply_init_tag(@pagy, :myInitFunction)
# this uses a custom payload
pagy_apply_init_tag(@pagy, :myOtherFunction, {a: 1, b: 2})
```

You should define your functions in the `PagyInit` namespace, as follow, using the payload as needed:

```javascript
PagyInit.myInitFunction = function(payload){
console.log(payload);
doSomethingWith(payload);
...
}
```

You can use it to initialize your custom pagination elements. For auto-scroll, you may want to update some client side variable with the `pagy_next_url` at each page load.
4 changes: 4 additions & 0 deletions lib/config/pagy.rb
Expand Up @@ -61,6 +61,10 @@

# Feature Extras

# Support extra: Extra support for features like: incremental, infinite, auto-scroll pagination
# See https://ddnexus.github.io/pagy/extras/support
# require 'pagy/extras/support'

# Items extra: Allow the client to request a custom number of items per page with an optional selector UI
# See https://ddnexus.github.io/pagy/extras/items
# require 'pagy/extras/items'
Expand Down
4 changes: 4 additions & 0 deletions lib/javascripts/pagy.js
Expand Up @@ -86,3 +86,7 @@ Pagy.init = function(){
}
})
};

function PagyInit(){}

Pagy.applyInit = function(name, payload){ PagyInit[name].apply(null, [payload]) };
54 changes: 54 additions & 0 deletions lib/pagy/extras/support.rb
@@ -0,0 +1,54 @@
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/support
# frozen_string_literal: true

require 'pagy/extras/shared'

class Pagy

def to_h
{ count: @count,
page: @page,
items: @items,
pages: @pages,
last: @last,
offset: @offset,
from: @from,
to: @to,
prev: @prev,
next: @next,
vars: @vars,
series: series }
end

module Frontend

def pagy_prev_url(pagy)
pagy_url_for(pagy.prev, pagy) if pagy.prev
end

def pagy_next_url(pagy)
pagy_url_for(pagy.next, pagy) if pagy.next
end

def pagy_prev_link(pagy, text = pagy_t('pagy.nav.prev'), link_extra = '')
pagy.prev ? %(<span class="page prev"><a href="#{pagy_prev_url(pagy)}" rel="next" aria-label="next" #{pagy.vars[:link_extra]} #{link_extra}>#{text}</a></span>)
: %(<span class="page prev disabled">#{text}</span>)
end

def pagy_next_link(pagy, text = pagy_t('pagy.nav.next'), link_extra = '')
pagy.next ? %(<span class="page next"><a href="#{pagy_next_url(pagy)}" rel="next" aria-label="next" #{pagy.vars[:link_extra]} #{link_extra}>#{text}</a></span>)
: %(<span class="page next disabled">#{text}</span>)
end

def pagy_serialized(pagy)
pagy.to_h.merge(prev_url: pagy_prev_url(pagy), next_url: pagy_next_url(pagy))
end

# Multi purpose JSON tag for custom javascript initialization
def pagy_apply_init_tag(pagy, function, payload=pagy_serialized(pagy))
pagy_json_tag(:applyInit, function, payload)
end

end

end

0 comments on commit 2bdb1e5

Please sign in to comment.