flex_infinite_scroll 0.1.3 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 3cb41835798253e2a4d88bdcfe92c12777f14b68c8ed69b1983f59d70ef17253
4
- data.tar.gz: 50e727fdb17ba2d7fbf6990197e4d083e281fe0cfdd79cc10c0a449f156ec243
2
+ SHA1:
3
+ metadata.gz: 566821164973e19e83ef507c84b5b77f0d66e148
4
+ data.tar.gz: e22f3d0148db3746989eef48649e82376c12f02d
5
5
  SHA512:
6
- metadata.gz: ed2d0f945d3afe55c13e162cce7f4c8ef87bb8de0f644de7bd48e818b24e5c0c3d58a1e96769436a513976bd36bf119abf528d35d0e2327101cae85b28f4e415
7
- data.tar.gz: 0e80acdf4f616b7bb78374bed03b75598d4fc25c267fa2fcf22643ad4da39b5e477fdfb6ab73221dd03d7cfeeb1e609069ea7926d1699b82bd9e2b7148bbf807
6
+ metadata.gz: b8a8bf1db18cdb92f26ef9953c5fee972f64c43de1e05f1fe0afae24fe21bbd07e425032d5675a8db5921c4bdab062ae80f2d6914bb542da046e9645be0a0c49
7
+ data.tar.gz: 4b6567f7892c2bc453d32a45a3a1866c8dd2eade75192f8386c3c7502262febd9e5295e6cad57c59a94f872619887eaaa734839ecd5241b5741c975e2b9fb61b
@@ -1,25 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Infinite scroll module
4
- require 'flex_infinite_scroll/view_helpers'
5
- require 'sanitize'
6
-
7
3
  module FlexInfiniteScroll
8
- class Engine < ::Rails::Engine
9
- ActionView::Base.send :include, FlexInfiniteScroll::ViewHelpers
10
- end
11
- extend ActiveSupport::Concern
12
- def infinite_scroll(page = 1, page_size = (ENV['FIS_PAGE_SIZE'] || 20))
13
- page ||= 1
14
- page = page.to_i if page.class == String
15
- offset_skip = (page - 1) * page_size
16
- total_page = (count('*') / page_size.to_f).ceil
17
- {
18
- data: offset(offset_skip).limit(page_size),
19
- total_page: total_page,
20
- prev_page: (page == 1 ? nil : page - 1),
21
- current_page: page,
22
- next_page: (page == total_page ? nil : page + 1)
23
- }
24
- end
4
+ class Engine < ::Rails::Engine; end
25
5
  end
6
+
7
+ require 'flex_infinite_scroll/activerecord'
8
+ require 'flex_infinite_scroll/actionview'
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ ActiveSupport.on_load :action_view do
4
+ require 'flex_infinite_scroll/actionview/extension'
5
+ ::ActionView::Base.include FlexInfiniteScroll::ActionViewExtension
6
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlexInfiniteScroll
4
+ module ActionViewExtension
5
+ def fis_tag(data = nil, fis_config = {}, container_config = {})
6
+ container_config[:data] ||= {}
7
+ container_config[:class] = "fis-container #{container_config[:class]}"
8
+
9
+ virtual_el_size = fis_config[:virtualScrollElementSize]
10
+
11
+ page = fis_config[:startPage] || 1
12
+ fis_config[:startPage] = page + 1
13
+
14
+ fis_config.each do |k, _v|
15
+ container_config[:data][k.to_s.underscore] = fis_config[k]
16
+ end
17
+
18
+ content_tag :div, container_config do
19
+ data = data.fis(page: page, per_page: fis_config[:perPage])
20
+ data_html = data.map { |el| yield el }.join
21
+
22
+ baloons = []
23
+ if virtual_el_size
24
+ (fis_config[:startPage]..data.total_pages).each do |page_number|
25
+ baloons.push(
26
+ content_tag(:div, nil,
27
+ class: 'fis-baloon',
28
+ data: {
29
+ baloon_page: page_number
30
+ },
31
+ style: "height: #{virtual_el_size * data.per_page}px")
32
+ )
33
+ end
34
+ end
35
+ (data_html + baloons.join).html_safe
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ ActiveSupport.on_load :active_record do
4
+ require 'flex_infinite_scroll/activerecord/extension'
5
+ ::ActiveRecord::Base.include FlexInfiniteScroll::ActiveRecordExtension
6
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlexInfiniteScroll
4
+ module ActiveRecordExtension
5
+ extend ActiveSupport::Concern
6
+
7
+ require 'flex_infinite_scroll/activerecord/helpers'
8
+
9
+ included do
10
+ def self.fis(config = { page: 1 })
11
+ page = config[:page].to_i
12
+ per_page = config[:per_page] ? config[:per_page].to_i : 20
13
+ offset(per_page * (page - 1)).limit(per_page).extending do
14
+ include FlexInfiniteScroll::ActiveRecordHelpers
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlexInfiniteScroll
4
+ module ActiveRecordHelpers
5
+ def render_json
6
+ prepare_render.merge(data: as_json)
7
+ end
8
+
9
+ def render_html
10
+ prepare_render.merge(data: map { |el| yield el }.join.html_safe)
11
+ end
12
+
13
+ def per_page
14
+ values[:limit]
15
+ end
16
+
17
+ def page
18
+ (values[:offset] / per_page) + 1
19
+ end
20
+
21
+ def next_page
22
+ page == total_pages ? nil : page + 1
23
+ end
24
+
25
+ def total_pages
26
+ (except(:offset, :limit, :order).count / per_page).ceil
27
+ end
28
+
29
+ private
30
+
31
+ def prepare_render
32
+ {
33
+ next_page: next_page,
34
+ total_pages: total_pages
35
+ }
36
+ end
37
+ end
38
+ end
@@ -1,108 +1,310 @@
1
1
  // Flex Infinite Scroll initialization
2
2
 
3
- $.fn.extend({
4
- flexInfiniteScroll: function(config = {}) {
5
- // Config preparing
6
- var startPage = config.startPage || 1;
7
- var nextPage = startPage + 1;
8
- var dataUrl = config.url;
9
- var scrollContainer = this[0];
10
- var queryParams = config.queryParams;
11
- var dataProcess = config.dataProcess;
12
- var initialLoad = config.initialLoad;
13
- var loadMargin = config.loadMargin || 150;
14
- var beforeAction = config.beforeAction;
15
- var afterAction = config.afterAction;
16
- var targetContainer= config.targetContainer || scrollContainer ;
17
- var eventTarget = (scrollContainer.localName == 'body' ? window : scrollContainer);
18
- if (config.lastPage) nextPage = 'last';
19
- scrollContainer.dataset.fisNextPage = nextPage;
20
- scrollContainer.dataset.fisUrl = dataUrl;
21
- scrollContainer.dataset.fisLoading = 0;
22
-
23
- function getScrollHeight(){
24
- if (scrollContainer.localName == 'body'){
25
- return document.documentElement.scrollHeight
26
- } else {
27
- return eventTarget.scrollHeight
28
- }
29
-
30
- }
31
-
32
- function getData(page = 1){
33
- // Check for loading process and last page
34
- if (scrollContainer.dataset.fisLoading === '1' || page == 'last') return false
35
- scrollContainer.dataset.fisLoading = 1;
36
- // before load action
37
- if (beforeAction) {
38
- if (typeof(beforeAction) == 'function') {
39
- beforeAction();
40
- }else if (typeof(beforeAction) == 'string') {
41
- eval(beforeAction)
3
+ /*
4
+ config = {
5
+ customResponse: function(target, data) {
6
+ 'Data processing after loading next page. By default data will be added as HTML.'
7
+ },
8
+ eventTarget: 'Select different DOM element for scroll event',
9
+ requestUrl: 'URL for next page.',
10
+ loadMargin: 'Bottom margin in pixels, when will start loading next page. Default: 150',
11
+ startPage: 'Start page for loading data. Default: 1',
12
+ requestType: 'Type of AJAX request. Default: GET',
13
+ customParams: function(params) {
14
+ Parameters that will be sent with next page request. Default: {page: next_page}
15
+ return params
16
+ },
17
+ windowScroll: Attach scroll event to window object,
18
+ customResponseAttributes: {
19
+ next_page: 'next_page',
20
+ data: 'data'
21
+ },
22
+ virtualScroll: 'Enable virtual scroll',
23
+ virtualScrollElementSize: 'Element size for virtual scroll',
24
+ perfectScrollbarSupport: 'Enable perfect-scrollbar support'
25
+ perfectScrollbarConfig: 'Config for perfect-scrollbar'
26
+ }
27
+ */
28
+
29
+ 'use strict';
30
+
31
+ class flexIS {
32
+ constructor(targetObject, config = {}) {
33
+ this.targetObject = (typeof(targetObject) === 'object' ? targetObject : document.querySelector(targetObject));
34
+ this.config = {...config, ...this.targetObject.dataset};
35
+ this.loading = false;
36
+ this.nextPage = this.config.startPage || 1;
37
+ this.totalElements;
38
+
39
+ this.config.requestType = this.config.requestType || 'GET';
40
+ this.config.loadMargin = this.config.loadMargin || 150;
41
+ this.config.eventTarget = prepareEventTarget(this);
42
+ this.#customResponseAttributesSet();
43
+
44
+ function prepareEventTarget(object) {
45
+ var eventTarget = document.querySelector(object.config.eventTarget) || object.targetObject;
46
+ if (["true", true].includes(object.config.windowScroll)) {
47
+ return window;
48
+ } else {
49
+ return eventTarget;
50
+ }
42
51
  }
43
- }
44
- $.ajax({
45
- url: scrollContainer.dataset.fisUrl,
46
- // custom query params
47
- data: (queryParams || {page: page}),
48
- dataType: 'json',
49
- type: 'GET',
50
- success: function(json) {
51
-
52
- if (dataProcess){
53
- // custom user processor
54
- dataProcess(json,$(targetContainer));
55
- } else {
56
- // default data processor
57
- $(json.data).appendTo($(targetContainer));
58
- }
59
- scrollContainer.dataset.fisNextPage = json.next_page || 'last';
60
- scrollContainer.dataset.fisLoading = 0;
61
- if (scrollNotApear()) {
62
- // check if on initial load not enough elements on screen
63
- getData(scrollContainer.dataset.fisNextPage)
64
- }
65
- // after load action
66
- if (afterAction) {
67
- if (typeof(afterAction) == 'function') {
68
- afterAction();
69
- }else if (typeof(afterAction) == 'string') {
70
- eval(afterAction)
52
+
53
+ if (["true", true].includes(this.config.perfectScrollbarSupport)) {
54
+ let PSConfig = this.config.perfectScrollbarConfig || {}
55
+ PSConfig.minScrollbarLength = PSConfig.minScrollbarLength || 40
56
+ this.perfectScrollbar = new PerfectScrollbar(
57
+ this.targetObject,
58
+ PSConfig
59
+ );
60
+ }
61
+ }
62
+
63
+ // Init infinite scroll
64
+ init() {
65
+ if(this.#virtualScroll().enabled()) {
66
+ this.#virtualScroll().pagesLoad();
67
+ } else {
68
+ this.#getData();
69
+ }
70
+
71
+ this.config.eventTarget.addEventListener('scroll', () => {
72
+ if(this.#virtualScroll().enabled()) {
73
+ this.#virtualScroll().pagesLoad();
74
+ } else {
75
+ if (this.#scrollHitBottom() && this.nextPage) {
76
+ this.#getData();
77
+ };
78
+ }
79
+ this.#hideInvisibleContent();
80
+ });
81
+ return this;
82
+ }
83
+
84
+ // Reset scroll to specific page
85
+ resetScroll(page) {
86
+ this.targetObject.innerHTML = '';
87
+ this.nextPage = page || this.config.startPage || 1;
88
+ this.#getData();
89
+ return this;
90
+ }
91
+
92
+ // Append element to container
93
+ appendChild(el) {
94
+ this.#appendElementToContainer(el);
95
+ return this;
96
+ }
97
+
98
+ // Private methods
99
+
100
+ // Run data request for next page
101
+ #getData = (page = this.nextPage, forceLoad = false) => {
102
+ var xhr = new XMLHttpRequest();
103
+ var params;
104
+ const beforeLoadEvent = new CustomEvent('FlexIS:beforeLoad');
105
+ const afterLoadEvent = new CustomEvent('FlexIS:afterLoad');
106
+
107
+ if (!page || (this.loading && !forceLoad)) return false;
108
+
109
+ this.loading = true;
110
+
111
+ params = this.#customParams({page: parseInt(page, 10)});
112
+
113
+ this.targetObject.dispatchEvent(beforeLoadEvent);
114
+ xhr.open('GET', this.#requestUrl(params));
115
+ xhr.onload = () => {
116
+ var json = JSON.parse(xhr.response);
117
+
118
+ this.loading = false;
119
+
120
+ if (xhr.status === 200) {
121
+ this.#customResponse(json, page);
122
+ if (!this.#virtualScroll().enabled()) {
123
+ this.nextPage = json[this.config.customResponseAttributes.next_page];
124
+ if (this.#scrollHitBottom()) this.#getData();
71
125
  }
72
126
  }
73
- },
74
- error: function() {
75
- scrollContainer.dataset.fisLoading = 0;
127
+
128
+ this.targetObject.dispatchEvent(afterLoadEvent);
129
+
76
130
  }
77
- });
78
- }
79
-
80
- // intial load
81
- if (initialLoad) {
82
- getData(startPage)
83
- } else if (scrollNotApear()) {
84
- // check if on initial load not enough elements on screen
85
- getData(scrollContainer.dataset.fisNextPage);
86
- }
87
-
88
- // check if body scroll
89
-
90
- function scrollNotApear(){
91
- var containerSize=$(eventTarget).innerHeight();
92
- var scrollSize=getScrollHeight();
93
- return (scrollSize - containerSize - loadMargin <= 0)
94
- }
95
-
96
- $(eventTarget).on('scroll', () => {
97
- var scrollTop=$(eventTarget).scrollTop();
98
- var containerSize=$(eventTarget).innerHeight();
99
- var scrollSize=getScrollHeight();
100
- if (scrollTop + containerSize > scrollSize - loadMargin && scrollContainer.dataset.fisNextPage != 'last'){
101
- getData(scrollContainer.dataset.fisNextPage);
102
- };
131
+ xhr.send();
132
+ }
133
+
134
+ // Full scroll height
135
+ #scrollHeight = () => {
136
+ return this.targetObject.scrollHeight;
137
+ }
138
+
139
+ // Top scroll position
140
+ #scrollTop = () => {
141
+ return this.config.eventTarget.scrollTop || this.config.eventTarget.scrollY || 0;
142
+ }
143
+
144
+ // Get container size
145
+ #containerSize = () => {
146
+ return this.config.eventTarget.innerHeight || this.targetObject.offsetHeight;
147
+ }
148
+
149
+ // Container position
150
+ #containerPosition = () => {
151
+ return this.#scrollTop() + this.#containerSize() + this.config.loadMargin;
152
+ }
153
+
154
+ // Add custom params to request
155
+ #customParams = (params) => {
156
+ var customParams = this.config.customParams;
157
+ if (customParams) {
158
+ if (typeof customParams === "function") {
159
+ return customParams(params);
160
+ } else if (typeof customParams === "object") {
161
+ return {...customParams, ...params};
162
+ } else if (typeof customParams === "string") {
163
+ return {...JSON.parse(customParams), ...params};
164
+ }
165
+ }
166
+ return params;
167
+ }
168
+
169
+ // Response handling
170
+ #customResponse = (json, page) => {
171
+ var customResponse = this.config.customResponse;
172
+ var data = json[this.config.customResponseAttributes.data];
173
+ var div;
174
+
175
+ delete json[this.config.customResponseAttributes.data];
176
+
177
+ if (data.constructor === Array) {
178
+ data.forEach((el) => {
179
+ var htmlEl
180
+ if (typeof customResponse === "function") {
181
+ htmlEl = customResponse(el, json);
182
+ } else {
183
+ let div = document.createElement('div');
184
+ div.innerHTML = el;
185
+ htmlEl = div.children[0];
186
+ }
187
+ this.#appendElementToContainer(htmlEl, page);
188
+ })
189
+ } else if (data.constructor === String) {
190
+ div = document.createElement('div');
191
+ div.innerHTML = data;
192
+ while (div.children.length > 0) {
193
+ this.#appendElementToContainer(div.children[0], page);
194
+ }
195
+ }
196
+
197
+ this.#hideInvisibleContent();
198
+
199
+ if (this.#virtualScroll().enabled()) {
200
+ this.#virtualScroll().destroyBaloon(page);
201
+ }
202
+
203
+ if (this.perfectScrollbar) {
204
+ this.perfectScrollbar.update();
205
+ }
206
+ }
207
+
208
+ #appendElementToContainer = (el, page) => {
209
+ if (this.#virtualScroll().enabled()) {
210
+ this.#virtualScroll().insertBeforeBaloon(page, el);
211
+ } else {
212
+ this.targetObject.appendChild(el);
213
+ }
214
+ }
215
+
216
+ // Hide invisible content, when leaving active zone
217
+ #hideInvisibleContent = () => {
218
+ var elems = this.targetObject.children;
219
+ for (let i = 0; i < elems.length; i++) {
220
+ let elem = elems[i];
221
+ let elementTopPosition = elems[i].offsetTop + elems[i].offsetHeight - this.#scrollTop();
222
+ let elementBottomPosition = elems[i].offsetTop - elems[i].offsetHeight - this.#scrollTop() - this.#containerSize();
223
+
224
+ if (elem.className.includes('ps__rail-x', 'ps__rail-y')) continue;
225
+
226
+ if (elementTopPosition <= 0 || elementBottomPosition >= 0) {
227
+ if (elem.style.visibility === 'hidden') continue;
228
+ elem.style.visibility = 'hidden';
229
+ } else {
230
+ if (elem.style.visibility === '') continue;
231
+ elem.style.visibility = '';
232
+ }
233
+ }
234
+ }
235
+
236
+ #virtualScroll = () => {
237
+ return {
238
+ enabled: () => {
239
+ return ["true", true].includes(this.config.virtualScroll);
240
+ },
241
+ insertBeforeBaloon: (page, el) => {
242
+ var baloon = this.targetObject.querySelector(`[data-baloon-page="${page}"]`)
243
+ var newHeight;
244
+ this.targetObject.insertBefore(el, baloon);
245
+ newHeight = baloon.offsetHeight - el.offsetHeight;
246
+ baloon.style.height = newHeight + 'px';
247
+
248
+ },
249
+ pagesLoad: () => {
250
+ var baloons = [...this.targetObject.getElementsByClassName('fis-baloon')];
251
+ var containerPosition = this.#containerPosition();
252
+ baloons.forEach(baloon => {
253
+ var visibleBottom = this.#containerPosition() > baloon.offsetTop;
254
+ var visibleTop = this.#scrollTop() < baloon.offsetTop + baloon.offsetHeight;
255
+ if (baloon.dataset.loading) return;
256
+ if (visibleBottom && visibleTop) {
257
+ baloon.dataset.loading = true;
258
+ this.#getData(baloon.dataset.baloonPage, true);
259
+ }
260
+ })
261
+ },
262
+ destroyBaloon: (page) => {
263
+ this.targetObject.querySelector(`[data-baloon-page="${page}"]`).remove();
264
+ }
265
+ }
266
+ }
267
+
268
+ // Update response attributes
269
+ #customResponseAttributesSet = () => {
270
+ var attr = this.config.customResponseAttributes || {};
271
+ attr.next_page = attr.next_page || 'next_page';
272
+ attr.data = attr.data || 'data';
273
+ attr.elements_left = attr.elements_left || 'elements_left';
274
+ this.config.customResponseAttributes = attr
275
+ }
276
+
277
+ // Generate url with params
278
+ #requestUrl = (params) => {
279
+ var encodedString = [];
280
+ for (var prop in params) {
281
+ if (params.hasOwnProperty(prop)) {
282
+ encodedString.push(encodeURI(prop + '=' + params[prop]));
283
+ }
284
+ }
285
+ return this.config.requestUrl + '?' + encodedString.join('&');
286
+ }
287
+
288
+ // Check when load next page
289
+ #scrollHitBottom = () => {
290
+ return this.#scrollHeight() - this.#containerPosition() <= 0;
291
+ }
292
+ }
293
+
294
+ document.addEventListener('DOMContentLoaded', () => {
295
+ var fisObjects = [...document.getElementsByClassName('fis-container')];
296
+ fisObjects.forEach(object => {
297
+ object.data = {
298
+ flexIS: new flexIS(object).init()
299
+ };
300
+ })
301
+ })
302
+
303
+ document.addEventListener('turbolinks:load', () => {
304
+ var fisObjects = [...document.getElementsByClassName('fis-turbolinks-container')];
305
+ fisObjects.forEach(object => {
306
+ object.data = {
307
+ flexIS: new flexIS(object).init()
308
+ };
103
309
  })
104
-
105
-
106
-
107
- }
108
- })
310
+ })
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flex_infinite_scroll
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.3.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: 2019-04-21 00:00:00.000000000 Z
11
+ date: 2020-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: sanitize
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 4.6.3
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: 4.6.3
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rails
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -45,7 +31,11 @@ extensions: []
45
31
  extra_rdoc_files: []
46
32
  files:
47
33
  - lib/flex_infinite_scroll.rb
48
- - lib/flex_infinite_scroll/view_helpers.rb
34
+ - lib/flex_infinite_scroll/actionview.rb
35
+ - lib/flex_infinite_scroll/actionview/extension.rb
36
+ - lib/flex_infinite_scroll/activerecord.rb
37
+ - lib/flex_infinite_scroll/activerecord/extension.rb
38
+ - lib/flex_infinite_scroll/activerecord/helpers.rb
49
39
  - vendor/assets/javascript/flex_infinite_scroll.js
50
40
  homepage: https://github.com/aignatov-bio/flex_infinite_scroll
51
41
  licenses:
@@ -65,11 +55,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
55
  - - ">="
66
56
  - !ruby/object:Gem::Version
67
57
  version: '0'
68
- requirements:
69
- - jQuery
58
+ requirements: []
70
59
  rubyforge_project:
71
- rubygems_version: 2.7.6
60
+ rubygems_version: 2.6.14.3
72
61
  signing_key:
73
62
  specification_version: 4
74
- summary: Add infinite scrolling to models and views
63
+ summary: Infinite scroll for Ruby on Rails applications on pure JavaScript.
75
64
  test_files: []
@@ -1,43 +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
- result = if config[:targetContainer]
10
- fis_get_list(data, partial, 'html')
11
- else
12
- content_tag :div, class: "fis-container #{config[:container_class] || ''}" do
13
- fis_get_list(data, partial, 'html')
14
- end
15
- end
16
- config[:scrollContainer] ||= (config[:targetContainer] || 'body')
17
- config[:targetContainer] ||= '.fis-container'
18
- result += javascript_tag do
19
- "$('#{config[:scrollContainer]}').flexInfiniteScroll(#{config.to_json})".html_safe
20
- end
21
- Sanitize.fragment(result,
22
- Sanitize::Config.merge(Sanitize::Config::RELAXED,
23
- elements: Sanitize::Config::RELAXED[:elements] + %w(script))).html_safe
24
- end
25
-
26
- def fis_next_page(data, partial)
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
- Sanitize.fragment(result, Sanitize::Config::RELAXED).html_safe
41
- end
42
- end
43
- end