flex_infinite_scroll 0.1.4 → 0.2.0
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/lib/flex_infinite_scroll.rb +1 -20
- data/vendor/assets/javascript/flex_infinite_scroll.js +131 -105
- metadata +3 -5
- data/lib/flex_infinite_scroll/view_helpers.rb +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b2a488c4c9a4e8d1c412c49188eb0a5b386e6ab
|
4
|
+
data.tar.gz: b2e285288ffaba7bd0b3c0e82d1ee74a1f38bdac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66f797500898467fb03d9602f69756962dee609f10673a8efd925dd36893c37e586fa3d0c7db8956ee25ad98793d79160662cf12728df563e7609fa3d36fa1c4
|
7
|
+
data.tar.gz: 4df833cc66d11917c625d88cc2caade11fcee8863d61b8a8f5639eefebf42331018760a3dfbe548ec07fe2f328e16e40dc87a4a14b246366bca16e472cb4b271
|
data/lib/flex_infinite_scroll.rb
CHANGED
@@ -1,24 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Infinite scroll module
|
4
|
-
require 'flex_infinite_scroll/view_helpers'
|
5
|
-
|
6
3
|
module FlexInfiniteScroll
|
7
|
-
class Engine < ::Rails::Engine
|
8
|
-
ActionView::Base.send :include, FlexInfiniteScroll::ViewHelpers
|
9
|
-
end
|
10
|
-
extend ActiveSupport::Concern
|
11
|
-
def infinite_scroll(page = 1, page_size = (ENV['FIS_PAGE_SIZE'] || 20))
|
12
|
-
page ||= 1
|
13
|
-
page = page.to_i if page.class == String
|
14
|
-
offset_skip = (page - 1) * page_size
|
15
|
-
total_page = (count('*') / page_size.to_f).ceil
|
16
|
-
{
|
17
|
-
data: offset(offset_skip).limit(page_size),
|
18
|
-
total_page: total_page,
|
19
|
-
prev_page: (page == 1 ? nil : page - 1),
|
20
|
-
current_page: page,
|
21
|
-
next_page: (page == total_page ? nil : page + 1)
|
22
|
-
}
|
23
|
-
end
|
4
|
+
class Engine < ::Rails::Engine; end
|
24
5
|
end
|
@@ -1,122 +1,148 @@
|
|
1
1
|
// Flex Infinite Scroll initialization
|
2
2
|
|
3
|
+
'use strict';
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
5
|
+
class flexIS {
|
6
|
+
constructor(targetObject, config = {}) {
|
7
|
+
this.targetObject = (typeof(targetObject) === 'object' ? targetObject : document.querySelector(targetObject));
|
8
|
+
this.config = {...config, ...this.targetObject.dataset};
|
9
|
+
this.loading = false;
|
10
|
+
this.nextPage = this.config.startPage || 1;
|
11
|
+
|
12
|
+
this.config.requestType = this.config.requestType || 'GET';
|
13
|
+
this.config.loadMargin = this.config.loadMargin || 150;
|
14
|
+
this.config.eventTarget = prepareEventTarget(this);
|
15
|
+
|
16
|
+
function prepareEventTarget(object) {
|
17
|
+
var eventTarget = document.querySelector(object.config.eventTarget) || object.targetObject;
|
18
|
+
if (object.config.windowScroll) {
|
19
|
+
return window
|
20
|
+
} else {
|
21
|
+
return eventTarget
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
init() {
|
27
|
+
this.#getData();
|
28
|
+
this.config.eventTarget.addEventListener('scroll', () => {
|
29
|
+
if (this.#scrollHitBottom() && this.nextPage) {
|
30
|
+
this.#getData();
|
31
|
+
};
|
32
|
+
});
|
33
|
+
return this;
|
30
34
|
}
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
resetScroll(page) {
|
37
|
+
this.targetObject.innerHTML = '';
|
38
|
+
this.nextPage = page || this.config.startPage || 1;
|
39
|
+
this.#getData();
|
40
|
+
return this;
|
41
|
+
}
|
42
|
+
|
43
|
+
// Private methods
|
44
|
+
|
45
|
+
#getData = (page = this.nextPage ) => {
|
46
|
+
var xhr = new XMLHttpRequest();
|
47
|
+
var params;
|
48
|
+
const beforeLoadEvent = new CustomEvent('FlexIS:beforeLoad');
|
49
|
+
const afterLoadEvent = new CustomEvent('FlexIS:afterLoad');
|
50
|
+
|
51
|
+
if (!page || this.loading) return false;
|
52
|
+
|
53
|
+
this.loading = true;
|
54
|
+
|
55
|
+
params = this.#customParams({page: parseInt(page, 10)});
|
56
|
+
|
57
|
+
this.targetObject.dispatchEvent(beforeLoadEvent)
|
58
|
+
xhr.open('GET', this.#requestUrl(params));
|
59
|
+
xhr.onload = () => {
|
60
|
+
var json = JSON.parse(xhr.response);
|
61
|
+
|
62
|
+
this.loading = false;
|
63
|
+
|
64
|
+
if (xhr.status === 200) {
|
65
|
+
this.#customResponse(json)
|
66
|
+
this.nextPage = json.next_page;
|
67
|
+
if (this.#scrollHitBottom()) this.#getData();
|
40
68
|
}
|
41
|
-
|
42
|
-
|
69
|
+
|
70
|
+
this.targetObject.dispatchEvent(afterLoadEvent)
|
71
|
+
|
72
|
+
}
|
73
|
+
xhr.send();
|
74
|
+
}
|
75
|
+
|
76
|
+
#scrollHeight = () => {
|
77
|
+
return this.targetObject.scrollHeight;
|
78
|
+
}
|
79
|
+
|
80
|
+
#scrollTop = () => {
|
81
|
+
return this.config.eventTarget.scrollTop || this.config.eventTarget.scrollY;
|
43
82
|
}
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
if (
|
52
|
-
|
53
|
-
|
54
|
-
|
83
|
+
|
84
|
+
#containerSize = () => {
|
85
|
+
return this.config.eventTarget.innerHeight || this.targetObject.offsetHeight;
|
86
|
+
}
|
87
|
+
|
88
|
+
#customParams = (params) => {
|
89
|
+
var customParams = this.config.customParams;
|
90
|
+
if (customParams) {
|
91
|
+
if (typeof customParams === "function") {
|
92
|
+
return customParams(params);
|
93
|
+
} else if (typeof customParams === "object") {
|
94
|
+
return {...customParams, ...params};
|
95
|
+
} else if (typeof customParams === "string") {
|
96
|
+
return {...JSON.parse(customParams), ...params};
|
97
|
+
}
|
55
98
|
}
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
var
|
62
|
-
if (
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
} else {
|
67
|
-
// default data processor
|
68
|
-
var div = document.createElement('div');
|
99
|
+
return params;
|
100
|
+
}
|
101
|
+
|
102
|
+
#customResponse = (json) => {
|
103
|
+
var customResponse = this.config.customResponse;
|
104
|
+
var div;
|
105
|
+
if (typeof customResponse === "function") {
|
106
|
+
customResponse(this.targetObject, json);
|
107
|
+
} else {
|
108
|
+
div = document.createElement('div');
|
69
109
|
div.innerHTML = json.data;
|
70
110
|
while (div.children.length > 0) {
|
71
|
-
|
111
|
+
this.targetObject.appendChild(div.children[0]);
|
72
112
|
}
|
73
|
-
}
|
74
|
-
scrollContainer.dataset.fisNextPage = json.next_page || 'last';
|
75
|
-
scrollContainer.dataset.fisLoading = 0;
|
76
|
-
if (scrollNotApear()) {
|
77
|
-
// check if on initial load not enough elements on screen
|
78
|
-
getData(scrollContainer.dataset.fisNextPage);
|
79
|
-
}
|
80
|
-
// after load action
|
81
|
-
if (afterAction) {
|
82
|
-
if (typeof(afterAction) == 'function') {
|
83
|
-
afterAction();
|
84
|
-
}else if (typeof(afterAction) == 'string') {
|
85
|
-
eval(afterAction)
|
86
|
-
}
|
87
|
-
}
|
88
|
-
} else {
|
89
|
-
scrollContainer.dataset.fisLoading = 0;
|
90
113
|
}
|
91
|
-
|
92
|
-
xhr.send();
|
114
|
+
|
93
115
|
}
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
116
|
+
|
117
|
+
#requestUrl = (params) => {
|
118
|
+
var encodedString = [];
|
119
|
+
for (var prop in params) {
|
120
|
+
if (params.hasOwnProperty(prop)) {
|
121
|
+
encodedString.push(encodeURI(prop + '=' + params[prop]));
|
122
|
+
}
|
123
|
+
}
|
124
|
+
return this.config.requestUrl + '?' + encodedString.join('&');
|
101
125
|
}
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
function scrollNotApear(){
|
106
|
-
var containerSize=(object_id == 'body' ? eventTarget.innerHeight : eventTarget.offsetHeight);
|
107
|
-
var scrollSize=getScrollHeight();
|
108
|
-
return (scrollSize - containerSize - loadMargin <= 0);
|
126
|
+
|
127
|
+
#scrollHitBottom = () => {
|
128
|
+
return (this.#scrollHeight() - this.#scrollTop() - this.#containerSize() - this.config.loadMargin <= 0);
|
109
129
|
}
|
130
|
+
}
|
110
131
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
};
|
132
|
+
document.addEventListener('DOMContentLoaded', () => {
|
133
|
+
var fisObjects = [...document.getElementsByClassName('fis-container')];
|
134
|
+
fisObjects.forEach(object => {
|
135
|
+
object.data = {
|
136
|
+
flexIS: new flexIS(object).init()
|
137
|
+
}
|
118
138
|
})
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
139
|
+
})
|
140
|
+
|
141
|
+
document.addEventListener('turbolinks:load', () => {
|
142
|
+
var fisObjects = [...document.getElementsByClassName('fis-turbolinks-container')];
|
143
|
+
fisObjects.forEach(object => {
|
144
|
+
object.data = {
|
145
|
+
flexIS: new flexIS(object).init()
|
146
|
+
}
|
147
|
+
})
|
148
|
+
})
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flex_infinite_scroll
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anton Ignatov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -31,7 +31,6 @@ extensions: []
|
|
31
31
|
extra_rdoc_files: []
|
32
32
|
files:
|
33
33
|
- lib/flex_infinite_scroll.rb
|
34
|
-
- lib/flex_infinite_scroll/view_helpers.rb
|
35
34
|
- vendor/assets/javascript/flex_infinite_scroll.js
|
36
35
|
homepage: https://github.com/aignatov-bio/flex_infinite_scroll
|
37
36
|
licenses:
|
@@ -56,6 +55,5 @@ rubyforge_project:
|
|
56
55
|
rubygems_version: 2.6.14.3
|
57
56
|
signing_key:
|
58
57
|
specification_version: 4
|
59
|
-
summary: Infinite scroll for Ruby on Rails applications on pure JavaScript.
|
60
|
-
Kaminari support for pagination.
|
58
|
+
summary: Infinite scroll for Ruby on Rails applications on pure JavaScript.
|
61
59
|
test_files: []
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module FlexInfiniteScroll
|
4
|
-
module ViewHelpers
|
5
|
-
include ActionView::Helpers::TagHelper
|
6
|
-
include ActionView::Context
|
7
|
-
|
8
|
-
def fis_init_list(data, partial, config = {})
|
9
|
-
data = kaminari_prepare(data) if config[:kaminari]
|
10
|
-
result = if config[:targetContainer]
|
11
|
-
fis_get_list(data, partial, 'html')
|
12
|
-
else
|
13
|
-
content_tag :div, id: 'fis-container', class: (config[:container_class] || '').to_s do
|
14
|
-
fis_get_list(data, partial, 'html')
|
15
|
-
end
|
16
|
-
end
|
17
|
-
config[:scrollContainer] ||= (config[:targetContainer] || 'body')
|
18
|
-
config[:targetContainer] ||= 'fis-container'
|
19
|
-
result += javascript_tag do
|
20
|
-
"flexInfiniteScroll('#{config[:scrollContainer]}',#{config.to_json})".html_safe
|
21
|
-
end
|
22
|
-
result.html_safe
|
23
|
-
end
|
24
|
-
|
25
|
-
def fis_next_page(data, partial, config = {})
|
26
|
-
data = kaminari_prepare(data) if config[:kaminari]
|
27
|
-
data[:data] = fis_get_list(data, partial, 'json')
|
28
|
-
data
|
29
|
-
end
|
30
|
-
|
31
|
-
def fis_get_list(data, partial, format)
|
32
|
-
result = ''
|
33
|
-
data[:data].each do |member|
|
34
|
-
result += if format == 'json'
|
35
|
-
render_to_string(partial: partial, locals: { fis_object: member })
|
36
|
-
else
|
37
|
-
render partial: partial, locals: { fis_object: member }
|
38
|
-
end
|
39
|
-
end
|
40
|
-
result.html_safe
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def kaminari_prepare(data)
|
46
|
-
{
|
47
|
-
data: data,
|
48
|
-
next_page: data.next_page
|
49
|
-
}
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|