infienity 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -5
- data/README.md +11 -11
- data/lib/infienity/commander.rb +35 -13
- data/lib/infienity/version.rb +1 -1
- data/lib/javascripts/infienity.js +2 -3
- data/lib/layouts/search.html.erb +6 -6
- data/lib/layouts/sort.html.erb +8 -1
- data/lib/layouts/sort_select.html.erb +2 -1
- data/vendor/assets/javascripts/infienity.js +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2d3cd2e39d58792ac133e6b888e1317666ab4270d5b9146785c9cf05834ecfd7
|
|
4
|
+
data.tar.gz: ba60d975cc548c692de81f58aa04f78d3870ff3223098a3f955353d27ae9ec38
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fd83c388b45079493ff20517d2c47db3f83bc6823ea0d80f92d42c24da102644b83ef37d7e7aa0676c65e42c625288fb4e6e9f2db3a3446ad2a90a53f4a83b54
|
|
7
|
+
data.tar.gz: acddbb6deda32c283d6b78fd6d87af3672587e4c01aecc20d71a4885b81553961dff3e2fd3c848bcf332e2e07801ea2a21e896d46dbc8a7ad0afd9e46e0f223b
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
infienity (0.1.
|
|
4
|
+
infienity (0.1.2)
|
|
5
5
|
rails
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -53,10 +53,10 @@ GEM
|
|
|
53
53
|
concurrent-ruby (1.1.4)
|
|
54
54
|
crass (1.0.4)
|
|
55
55
|
diff-lcs (1.3)
|
|
56
|
-
erubi (1.
|
|
56
|
+
erubi (1.8.0)
|
|
57
57
|
globalid (0.4.1)
|
|
58
58
|
activesupport (>= 4.2.0)
|
|
59
|
-
i18n (1.
|
|
59
|
+
i18n (1.3.0)
|
|
60
60
|
concurrent-ruby (~> 1.0)
|
|
61
61
|
loofah (2.2.3)
|
|
62
62
|
crass (~> 1.0.2)
|
|
@@ -66,12 +66,12 @@ GEM
|
|
|
66
66
|
marcel (0.3.3)
|
|
67
67
|
mimemagic (~> 0.3.2)
|
|
68
68
|
method_source (0.9.2)
|
|
69
|
-
mimemagic (0.3.
|
|
69
|
+
mimemagic (0.3.3)
|
|
70
70
|
mini_mime (1.0.1)
|
|
71
71
|
mini_portile2 (2.4.0)
|
|
72
72
|
minitest (5.11.3)
|
|
73
73
|
nio4r (2.3.1)
|
|
74
|
-
nokogiri (1.9.
|
|
74
|
+
nokogiri (1.9.1)
|
|
75
75
|
mini_portile2 (~> 2.4.0)
|
|
76
76
|
rack (2.0.6)
|
|
77
77
|
rack-test (1.1.0)
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Infienity provides infinity scroll, combined with sort and search via web-socket connection. Since infinity scroll requires continuous calls to request new parts of the data, requesting new data via a permanent web-socket connection should be a cleaner approach than using traditional AJAX calls.
|
|
4
4
|
|
|
5
|
-
This gem is dependent on [Fie]("https://github.com/raen79/fie"), a gem that makes DOM manipulations through web sockets possible.
|
|
5
|
+
This gem is dependent on [Fie]("https://github.com/raen79/fie"), a gem that makes DOM manipulations through web sockets possible.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -28,7 +28,7 @@ Add Infienity's javascript in your project, by adding the following lines into `
|
|
|
28
28
|
//= require infienity
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
As Infienity is dependent on Fie, you will have to follow the regular [Fie setup]("https://github.com/raen79/fie"), which also includes setting up Redis.
|
|
31
|
+
As Infienity is dependent on Fie, you will have to follow the regular [Fie setup]("https://github.com/raen79/fie"), which also includes setting up Redis and replacing `yield` in your main layout.
|
|
32
32
|
|
|
33
33
|
## Usage
|
|
34
34
|
For both infinity scroll, searching and sorting you will need to perform the following steps:
|
|
@@ -38,9 +38,9 @@ Add the following line in the model you want to perform the actions on:
|
|
|
38
38
|
extend Infienity::Model
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
Create a commander for your model (for front-end manipulation). The commander should be
|
|
41
|
+
Create a commander for your model (for front-end manipulation). The commander should be correspondent to the controller of your model (path: `app/commanders/[name]_commander) `.
|
|
42
42
|
```ruby
|
|
43
|
-
class
|
|
43
|
+
class UserCommander < Fie::Commander
|
|
44
44
|
extend Infienity::Commander
|
|
45
45
|
commander_assigns :users # model name in this format
|
|
46
46
|
end
|
|
@@ -49,7 +49,7 @@ end
|
|
|
49
49
|
In your controller method, you will need to assign some variables, which will hold the state. you must declare all of them in order for the infinity scroll to work:
|
|
50
50
|
```ruby
|
|
51
51
|
@index = 0
|
|
52
|
-
@per_page =
|
|
52
|
+
@per_page = 5 # or omit if you want the default: 10
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
### Pagination
|
|
@@ -59,15 +59,15 @@ In your controller method, perform the pagination of the infinity scroll like so
|
|
|
59
59
|
@users = User.paginate
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
In your view,
|
|
62
|
+
In your view, wrap the dataset in a `div` or `span`, with the following class and custom attribute. `infienity-model` should include your model name, in plural.
|
|
63
63
|
Example:
|
|
64
64
|
```ruby
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
<div class="paginate" infienity-model="users">
|
|
66
|
+
<% @users.each do |u| %>
|
|
67
67
|
Name: <%= u.full_name %> <br/>
|
|
68
68
|
Username: <%= u.username %>
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
<% end %>
|
|
70
|
+
</span>
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
### Search
|
|
@@ -165,7 +165,7 @@ To style the html in the templates, add the `options` hash inside the locals has
|
|
|
165
165
|
Supported options:
|
|
166
166
|
- `:id`
|
|
167
167
|
- `:class`
|
|
168
|
-
- `:name`
|
|
168
|
+
- `:name` (except for search)
|
|
169
169
|
|
|
170
170
|
## Development
|
|
171
171
|
|
data/lib/infienity/commander.rb
CHANGED
|
@@ -5,56 +5,78 @@ module Infienity
|
|
|
5
5
|
current_class = field.to_s.singularize.classify.constantize
|
|
6
6
|
|
|
7
7
|
define_method "paginate_#{field}" do |pagination_params:, is_first_load: false|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
sorting_dropdown_options = state.try(:sorting_dropdown_options)
|
|
9
|
+
selected_dropdown_option = state.try(:selected_dropdown_option)
|
|
10
|
+
search_attribute = state.try(:search_attribute)
|
|
11
|
+
search_string = state.try(:search_string)
|
|
12
|
+
per_page = state.try(:per_page) || 10
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
search_opts = { attribute: search_attribute, search_string: search_string } if search_string.present?
|
|
15
|
+
sort_opts = sorting_dropdown_options&.fetch(selected_dropdown_option)
|
|
16
|
+
|
|
17
|
+
return if (per_page * state.index) > current_class.paginate_count(search: search_opts)
|
|
12
18
|
|
|
13
19
|
state.index = state.index + 1
|
|
14
|
-
state.
|
|
20
|
+
state.send("#{field.to_sym}=", state.send(field.to_sym) + current_class.paginate(per_page: per_page, start: state.index, search: search_opts, sort: sort_opts))
|
|
15
21
|
|
|
16
22
|
execute_js_function('Infienity.fieResponded', is_first_load)
|
|
17
23
|
end
|
|
18
24
|
|
|
19
25
|
define_method "filter_#{field}" do
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
sorting_dropdown_options = state.try(:sorting_dropdown_options)
|
|
27
|
+
selected_dropdown_option = state.try(:selected_dropdown_option)
|
|
28
|
+
search_attribute = state.try(:search_attribute)
|
|
29
|
+
search_string = state.try(:search_string)
|
|
30
|
+
per_page = state.try(:per_page) || 10
|
|
31
|
+
|
|
32
|
+
search_opts = { attribute: search_attribute, search_string: search_string } if search_string.present?
|
|
33
|
+
sort_opts = sorting_dropdown_options&.fetch(selected_dropdown_option)
|
|
22
34
|
state.index = 0
|
|
23
35
|
|
|
24
|
-
state.
|
|
36
|
+
state.send("#{field.to_s}=", current_class.paginate(per_page: per_page, start: 0, search: search_opts, sort: sort_opts))
|
|
25
37
|
|
|
26
38
|
execute_js_function('Infienity.fieResponded', true)
|
|
27
39
|
end
|
|
28
40
|
|
|
29
41
|
define_method "sort_#{field}" do |sort:|
|
|
30
|
-
|
|
42
|
+
selected_dropdown_option = state.try(:selected_dropdown_option)
|
|
43
|
+
search_attribute = state.try(:search_attribute)
|
|
44
|
+
search_string = state.try(:search_string)
|
|
45
|
+
per_page = state.try(:per_page) || 10
|
|
46
|
+
|
|
47
|
+
unless state.sorting_dropdown_options.key?(selected_dropdown_option)
|
|
31
48
|
raise StandardError("dropdown option not provided in the correct format")
|
|
32
49
|
end
|
|
33
50
|
|
|
34
51
|
state.selected_dropdown_option = sort.keys.first
|
|
35
52
|
|
|
36
|
-
search_opts = { attribute:
|
|
53
|
+
search_opts = { attribute: search_attribute, search_string: search_string } if search_string.present?
|
|
37
54
|
sort_opts = sort.values.first
|
|
38
55
|
state.index = 0
|
|
39
56
|
|
|
40
|
-
state.
|
|
57
|
+
state.send("#{field.to_s}=", current_class.paginate(per_page: per_page, start: 0, search: search_opts, sort: sort_opts))
|
|
41
58
|
|
|
42
59
|
execute_js_function('Infienity.fieResponded', true)
|
|
43
60
|
end
|
|
44
61
|
|
|
45
62
|
define_method "sort_select_#{field}" do
|
|
46
|
-
|
|
63
|
+
selected_dropdown_option = state.try(:selected_dropdown_option)
|
|
64
|
+
search_attribute = state.try(:search_attribute)
|
|
65
|
+
search_string = state.try(:search_string)
|
|
66
|
+
per_page = state.try(:per_page) || 10
|
|
67
|
+
|
|
68
|
+
unless state.sorting_dropdown_options.key?(selected_dropdown_option)
|
|
47
69
|
raise StandardError("dropdown option not provided in the correct format")
|
|
48
70
|
end
|
|
49
71
|
|
|
50
72
|
sort = JSON.parse(@caller[:value])
|
|
51
73
|
state.selected_dropdown_option = sort.keys.first
|
|
52
74
|
|
|
53
|
-
search_opts = { attribute:
|
|
75
|
+
search_opts = { attribute: search_attribute, search_string: search_string } if search_string.present?
|
|
54
76
|
sort_opts = sort.values.first
|
|
55
77
|
state.index = 0
|
|
56
78
|
|
|
57
|
-
state.
|
|
79
|
+
state.send("#{field.to_s}=", current_class.paginate(per_page: per_page, start: 0, search: search_opts, sort: sort_opts))
|
|
58
80
|
|
|
59
81
|
execute_js_function('Infienity.fieResponded', true)
|
|
60
82
|
end
|
data/lib/infienity/version.rb
CHANGED
|
@@ -52,8 +52,8 @@ class Infienity {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
lastEntryOffset(percentage_window_offset = 10) {
|
|
55
|
-
const lastDiv =
|
|
56
|
-
return lastDiv.offsetTop + lastDiv.offsetHeight - (window.innerHeight /
|
|
55
|
+
const lastDiv = document.querySelector('.paginate')
|
|
56
|
+
return lastDiv.offsetTop + lastDiv.offsetHeight - (window.innerHeight * percentage_window_offset / 100)
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -63,4 +63,3 @@ document.addEventListener("DOMContentLoaded", _ => {
|
|
|
63
63
|
|
|
64
64
|
window.Infienity = new Infienity(Fie, `paginate_${modelName}`, {});
|
|
65
65
|
});
|
|
66
|
-
|
data/lib/layouts/search.html.erb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
<% options = {} unless local_assigns[:options] %>
|
|
2
|
+
|
|
3
|
+
<input type="text"
|
|
3
4
|
class="<%= options[:class] %>"
|
|
4
5
|
id="<%= options[:id] %>"
|
|
5
|
-
name="search_string
|
|
6
|
-
value="<%= search_string %>"
|
|
7
|
-
fie-keyup="filter_<%= assign %>"
|
|
8
|
-
</input>
|
|
6
|
+
name="search_string"
|
|
7
|
+
value= "<%= search_string %>"
|
|
8
|
+
fie-keyup="filter_<%= assign %>" />
|
data/lib/layouts/sort.html.erb
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
<% options = {} if local_assigns[:options].nil? %>
|
|
2
|
+
|
|
1
3
|
<div class="dropdown">
|
|
2
|
-
<button class="<%= options[:class] %>"
|
|
4
|
+
<button class="<%= options[:class] %>"
|
|
5
|
+
id="<%= options[:id] %>"
|
|
6
|
+
name="<%= options[:name] %>"
|
|
7
|
+
type="button"
|
|
8
|
+
data-toggle="dropdown">
|
|
9
|
+
<%= current_option %>
|
|
3
10
|
<span class="caret"></span>
|
|
4
11
|
</button>
|
|
5
12
|
<ul class="dropdown-menu">
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<% options = {} unless local_assigns[:options] %>
|
|
2
|
+
|
|
1
3
|
<select
|
|
2
4
|
class="<%= options[:class] %>"
|
|
3
5
|
id="<%= options[:id] %>"
|
|
4
6
|
name="<%= options[:name] %>"
|
|
5
|
-
value="<%= search_string %>"
|
|
6
7
|
fie-keyup="filter_<%= assign %>" >
|
|
7
8
|
fie-change="sort_select_<%= assign %>">
|
|
8
9
|
<% dropdown_options.each do |key,val| %>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e){var t={};function i(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=0)}([function(e,t){class i{constructor(e,t,i){this._fetchNextEntriesFuncName=t,this._isFieQueried=!1,this._params=i,this._fie=e,this._loadNewEntries=this._loadNewEntries.bind(this),this.fieResponded=this.fieResponded.bind(this),this.bindEvents()}bindEvents(){document.addEventListener("fieReady",e=>this._loadNewEntries(!0)),window.addEventListener("scroll",this._loadNewEntries)}unbindEvents(){window.removeEventListener("scroll",this._loadNewEntries)}fieResponded(e=!1){this._isFieQueried=!1,window.setTimeout(t=>{e&&this._loadNewEntries(!0)},300)}setFieAsQueried(){self=this,this._isFieQueried=!0,window.setTimeout(e=>{self._isFieQueried=!1},300)}_loadNewEntries(e=!1){if(this.isUserBelowBottom()&&0==this._isFieQueried){let t={pagination_params:this._params,is_first_load:1==e};this._fie.executeCommanderMethod(this._fetchNextEntriesFuncName,t),this.setFieAsQueried()}}isUserBelowBottom(){return window.scrollY+window.innerHeight>this.lastEntryOffset()}lastEntryOffset(e=10){const t=
|
|
1
|
+
!function(e){var t={};function i(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=0)}([function(e,t){class i{constructor(e,t,i){this._fetchNextEntriesFuncName=t,this._isFieQueried=!1,this._params=i,this._fie=e,this._loadNewEntries=this._loadNewEntries.bind(this),this.fieResponded=this.fieResponded.bind(this),this.bindEvents()}bindEvents(){document.addEventListener("fieReady",e=>this._loadNewEntries(!0)),window.addEventListener("scroll",this._loadNewEntries)}unbindEvents(){window.removeEventListener("scroll",this._loadNewEntries)}fieResponded(e=!1){this._isFieQueried=!1,window.setTimeout(t=>{e&&this._loadNewEntries(!0)},300)}setFieAsQueried(){self=this,this._isFieQueried=!0,window.setTimeout(e=>{self._isFieQueried=!1},300)}_loadNewEntries(e=!1){if(this.isUserBelowBottom()&&0==this._isFieQueried){let t={pagination_params:this._params,is_first_load:1==e};this._fie.executeCommanderMethod(this._fetchNextEntriesFuncName,t),this.setFieAsQueried()}}isUserBelowBottom(){return window.scrollY+window.innerHeight>this.lastEntryOffset()}lastEntryOffset(e=10){const t=document.querySelector(".paginate");return t.offsetTop+t.offsetHeight-window.innerHeight*e/100}}document.addEventListener("DOMContentLoaded",e=>{const t=document.querySelector(".paginate").getAttribute("infienity-model");window.Infienity=new i(Fie,`paginate_${t}`,{})})}]);
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: infienity
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ioana Surdu-Bob
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-12-
|
|
11
|
+
date: 2018-12-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|