flex_infinite_scroll 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|