render_async 2.1.3 β 2.1.8
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/.all-contributorsrc +37 -0
- data/.github/FUNDING.yml +3 -0
- data/CHANGELOG.md +43 -1
- data/README.md +323 -68
- data/app/views/render_async/_render_async.html.erb +18 -25
- data/app/views/render_async/_request_jquery.js.erb +109 -40
- data/app/views/render_async/_request_vanilla.js.erb +109 -42
- data/lib/render_async/configuration.rb +3 -1
- data/lib/render_async/version.rb +1 -1
- data/lib/render_async/view_helper.rb +36 -8
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25aa48ca09d482b0cdf14569d09e594ef525deaba38b9be8c39bc200b86de28e
|
4
|
+
data.tar.gz: 3d52e3a5a9fcba834c502aa78ea429cfa650eea45de4e27654294e560cc9c177
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b50f5bd6a991c2af51ba3fc52b64dc0eda858e8827ef29b57dd4b8e1d1fd17134ddec8aeeb0df1e337666c9fb909f7b0664a85a069a3f3974fafa99273e66f9
|
7
|
+
data.tar.gz: 06adc494ef7f021ed5211f48f9103cabd5a3ebd42475cbcaedb7ac026df9cc0e62981e465b330ca17e351a17c53322e09bf51d055c2aaa64155457452820aa7f
|
data/.all-contributorsrc
CHANGED
@@ -177,6 +177,43 @@
|
|
177
177
|
"contributions": [
|
178
178
|
"code"
|
179
179
|
]
|
180
|
+
},
|
181
|
+
{
|
182
|
+
"login": "lipsumar",
|
183
|
+
"name": "Emmanuel Pire",
|
184
|
+
"avatar_url": "https://avatars3.githubusercontent.com/u/1191418?v=4",
|
185
|
+
"profile": "http://blog.lipsumarium.com",
|
186
|
+
"contributions": [
|
187
|
+
"code",
|
188
|
+
"doc"
|
189
|
+
]
|
190
|
+
},
|
191
|
+
{
|
192
|
+
"login": "maximgeerinck",
|
193
|
+
"name": "Maxim Geerinck",
|
194
|
+
"avatar_url": "https://avatars1.githubusercontent.com/u/615509?v=4",
|
195
|
+
"profile": "https://github.com/maximgeerinck",
|
196
|
+
"contributions": [
|
197
|
+
"code"
|
198
|
+
]
|
199
|
+
},
|
200
|
+
{
|
201
|
+
"login": "vanboom",
|
202
|
+
"name": "Don",
|
203
|
+
"avatar_url": "https://avatars1.githubusercontent.com/u/251706?v=4",
|
204
|
+
"profile": "https://github.com/vanboom",
|
205
|
+
"contributions": [
|
206
|
+
"code"
|
207
|
+
]
|
208
|
+
},
|
209
|
+
{
|
210
|
+
"login": "villu164",
|
211
|
+
"name": "villu164",
|
212
|
+
"avatar_url": "https://avatars0.githubusercontent.com/u/998682?v=4",
|
213
|
+
"profile": "https://github.com/villu164",
|
214
|
+
"contributions": [
|
215
|
+
"doc"
|
216
|
+
]
|
180
217
|
}
|
181
218
|
],
|
182
219
|
"repoType": "github"
|
data/.github/FUNDING.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,50 @@
|
|
1
|
-
### 2.1.
|
1
|
+
### 2.1.8 (2020/10/24)
|
2
|
+
|
3
|
+
* [#134](https://github.com/renderedtext/render_async/pull/134): Add config option for setting nonce - [@nikolalsvk](https://github.com/nikolalsvk).
|
4
|
+
* [#132](https://github.com/renderedtext/render_async/pull/132): Refresh render_async with an event - [@nikolalsvk](https://github.com/nikolalsvk).
|
5
|
+
* [#131](https://github.com/renderedtext/render_async/pull/131): Start to poll on page load with toggle - [@nikolalsvk](https://github.com/nikolalsvk).
|
6
|
+
* [#130](https://github.com/renderedtext/render_async/pull/130): Set up control events after document loaded - [@nikolalsvk](https://github.com/nikolalsvk).
|
7
|
+
* [#127](https://github.com/renderedtext/render_async/pull/127): Update README.md, to reflect correct turbolinks configuration value - [@villu164](https://github.com/villu164).
|
8
|
+
|
9
|
+
### 2.1.7 (2020/8/1)
|
10
|
+
|
11
|
+
* [#125](https://github.com/renderedtext/render_async/pull/125): Implement retry after some time feature - [@nikolalsvk](https://github.com/nikolalsvk).
|
12
|
+
* [#124](https://github.com/renderedtext/render_async/pull/124): Add more info on how to control polling - [@nikolalsvk](https://github.com/nikolalsvk).
|
13
|
+
* [#123](https://github.com/renderedtext/render_async/pull/123): Simplify calling of start and stop event when interval is defined - [@nikolalsvk](https://github.com/nikolalsvk).
|
14
|
+
* [#119](https://github.com/renderedtext/render_async/pull/119): Add polling control start/stop events - [@vanboom](https://github.com/vanboom).
|
15
|
+
* [#120](https://github.com/renderedtext/render_async/pull/120): Fine tune custom content_for feature - [@nikolalsvk](https://github.com/nikolalsvk).
|
16
|
+
* [#117](https://github.com/renderedtext/render_async/pull/117): Allow a custom content_for name - [@vanboom](https://github.com/vanboom).
|
17
|
+
|
18
|
+
### 2.1.6 (2020/5/9)
|
19
|
+
|
20
|
+
* [#114](https://github.com/renderedtext/render_async/pull/114): Call render_async logic if document state is ready or interactive - [@nikolalsvk](https://github.com/nikolalsvk).
|
21
|
+
* [#113](https://github.com/renderedtext/render_async/pull/113): Remove interval after Turbolinks visit event - [@nikolalsvk](https://github.com/nikolalsvk).
|
22
|
+
* [#112](https://github.com/renderedtext/render_async/pull/112): Add X-Requested-With header in Vanilla JS - [@nikolalsvk](https://github.com/nikolalsvk).
|
23
|
+
* [#110](https://github.com/renderedtext/render_async/pull/110): Remove preventDefault, and load toggle in stream - [@vanboom](https://github.com/vanboom).
|
24
|
+
|
25
|
+
### 2.1.5 (2020/3/22)
|
26
|
+
|
27
|
+
* [#105](https://github.com/renderedtext/render_async/pull/105): Load toggle listeners after page loads - [@nikolalsvk](https://github.com/nikolalsvk).
|
28
|
+
* [#104](https://github.com/renderedtext/render_async/pull/104): Attach container to dispatched events - [@nikolalsvk](https://github.com/nikolalsvk).
|
29
|
+
* [#103](https://github.com/renderedtext/render_async/pull/103): Add generic "load" and "error" events - [@lipsumar](https://github.com/lipsumar).
|
30
|
+
* [#98](https://github.com/renderedtext/render_async/pull/98): Bump nonce pattern in the README to follow Rails CSP standard - [@colinxfleming](https://github.com/colinxfleming).
|
31
|
+
|
32
|
+
### 2.1.4 (2019/11/11)
|
33
|
+
|
34
|
+
* [#96](https://github.com/renderedtext/render_async/pull/96): Add once option to remove event once it's triggered #94 - [@fffx](https://github.com/fffx).
|
35
|
+
|
36
|
+
### 2.1.3 (2019/9/24)
|
37
|
+
|
38
|
+
* [#95](https://github.com/renderedtext/render_async/pull/95): Use double quotes for displaying error message - [@nikolalsvk](https://github.com/nikolalsvk).
|
39
|
+
* [#93](https://github.com/renderedtext/render_async/pull/93): Fix: "Uncaught ReferenceError: \_interval" #92 - [@fffx](https://github.com/fffx).
|
40
|
+
|
41
|
+
### 2.1.2 (2019/8/17)
|
42
|
+
|
2
43
|
* [#89](https://github.com/renderedtext/render_async/pull/89): Bump version to 2.1.2 - [@nikolalsvk](https://github.com/nikolalsvk).
|
3
44
|
* [#82](https://github.com/renderedtext/render_async/pull/88): When toggle true, do not fire `_renderAsyncFunc` on `turbolinks:load` - [@ThanhKhoaIT](https://github.com/ThanhKhoaIT).
|
4
45
|
|
5
46
|
### 2.1.1 (2019/8/17)
|
47
|
+
|
6
48
|
* [#85](https://github.com/renderedtext/render_async/pull/85): Rename main JS function and support toggle feature with other features - [@nikolalsvk](https://github.com/nikolalsvk).
|
7
49
|
* [#82](https://github.com/renderedtext/render_async/pull/82): Add toggle selector and event to render - [@ThanhKhoaIT](https://github.com/ThanhKhoaIT).
|
8
50
|
* DEPRECATION WARNING - html_options is now a hash that you pass to render_async instead of an argument. If you passed for example a nonce: '21312aas...', you will need to pass
|
data/README.md
CHANGED
@@ -1,31 +1,70 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
1
|
+
<p align="center">
|
2
|
+
<img src='http://s2blog.wpengine.com/wp-content/uploads/assets/images/2017-06-08/speed-up-rendering-rails-pages-with-render-async.png' alt='render_async' />
|
3
|
+
|
4
|
+
<h1 align="center">π Welcome to render_async</h1>
|
5
|
+
|
6
|
+
<h3 align="center">Let's make your Rails pages fast again :racehorse:</h3>
|
7
|
+
|
8
|
+
<br />
|
9
|
+
|
10
|
+
<p align="center">
|
11
|
+
<a href="https://www.paypal.me/nikolalsvk/10" target="_blank">
|
12
|
+
<img src="https://img.shields.io/badge/$-support-green.svg" alt="Donate" />
|
13
|
+
</a>
|
14
|
+
<a href="https://rubygems.org/gems/render_async" target="_blank">
|
15
|
+
<img src="https://img.shields.io/gem/dt/render_async" alt="Downloads" />
|
16
|
+
</a>
|
17
|
+
<a href="#contributors" target="_blank">
|
18
|
+
<img src="https://img.shields.io/github/all-contributors/renderedtext/render_async" alt="All contributors" />
|
19
|
+
</a>
|
20
|
+
<a href="https://badge.fury.io/rb/render_async" target="_blank">
|
21
|
+
<img src="https://badge.fury.io/rb/render_async.svg" alt="Gem Version" />
|
22
|
+
</a>
|
23
|
+
<br />
|
24
|
+
<a href="https://discord.gg/SPfbeRm" target="_blank">
|
25
|
+
<img src="https://img.shields.io/discord/738783603214909521" alt="Discord Server" />
|
26
|
+
</a>
|
27
|
+
<a href="https://semaphoreci.com/renderedtext/render_async" target="_blank">
|
28
|
+
<img src="https://semaphoreci.com/api/v1/renderedtext/render_async/branches/master/shields_badge.svg" alt="Build Status" />
|
29
|
+
</a>
|
30
|
+
<a href="https://codeclimate.com/github/renderedtext/render_async" target="_blank">
|
31
|
+
<img src="https://img.shields.io/codeclimate/maintainability/renderedtext/render_async" alt="Code Climate Maintainablity" />
|
32
|
+
</a>
|
33
|
+
<a href="https://codeclimate.com/github/renderedtext/render_async/coverage" target="_blank">
|
34
|
+
<img src="https://img.shields.io/codeclimate/coverage/renderedtext/render_async" alt="Test Coverage" />
|
35
|
+
</a>
|
36
|
+
<a href="https://github.com/renderedtext/render_async/blob/master/LICENSE" target="_blank">
|
37
|
+
<img src="https://img.shields.io/github/license/renderedtext/render_async" alt="License" />
|
38
|
+
</a>
|
39
|
+
<a href="https://www.codetriage.com/renderedtext/render_async" target="_blank">
|
40
|
+
<img src="https://www.codetriage.com/renderedtext/render_async/badges/users.svg" alt="Help Contribute to Open Source" />
|
41
|
+
</a>
|
42
|
+
</p>
|
43
|
+
</p>
|
44
|
+
|
45
|
+
### `render_async` is here to make your pages show faster to users.
|
46
|
+
|
47
|
+
Pages become faster seamlessly by rendering partials to your views.
|
48
|
+
|
49
|
+
Partials render **asynchronously** and let users see your page **faster**
|
50
|
+
than using regular rendering.
|
51
|
+
|
52
|
+
It works with Rails and its tools out of the box.
|
53
|
+
|
54
|
+
:sparkles: A quick overview of how `render_async` does its magic:
|
55
|
+
|
56
|
+
1. user visits a page
|
57
|
+
2. `render_async` makes an AJAX request on the controller action
|
22
58
|
3. controller renders a partial
|
23
|
-
4.
|
59
|
+
4. partial renders in the place where you put `render_async` view helper
|
24
60
|
|
25
|
-
JavaScript is injected into `<%= content_for :render_async %>` so you choose
|
61
|
+
JavaScript is injected straight into `<%= content_for :render_async %>` so you choose
|
26
62
|
where to put it.
|
27
63
|
|
28
|
-
|
64
|
+
:mega: P.S. Join our [Discord channel](https://discord.gg/SPfbeRm) for help and discussion, and let's make `render_async` even better!
|
65
|
+
|
66
|
+
## :package: Installation
|
67
|
+
|
29
68
|
Add this line to your application's Gemfile:
|
30
69
|
|
31
70
|
```ruby
|
@@ -36,7 +75,7 @@ And then execute:
|
|
36
75
|
|
37
76
|
$ bundle install
|
38
77
|
|
39
|
-
## Usage
|
78
|
+
## :hammer: Usage
|
40
79
|
|
41
80
|
1. Include `render_async` view helper somewhere in your views (e.g. `app/views/comments/show.html.erb`):
|
42
81
|
```erb
|
@@ -69,7 +108,7 @@ And then execute:
|
|
69
108
|
<%= content_for :render_async %>
|
70
109
|
```
|
71
110
|
|
72
|
-
## Advanced usage
|
111
|
+
## :hammer_and_wrench: Advanced usage
|
73
112
|
|
74
113
|
Advanced usage includes information on different options, such as:
|
75
114
|
|
@@ -79,16 +118,22 @@ Advanced usage includes information on different options, such as:
|
|
79
118
|
- [Passing in an HTML element name](#passing-in-an-html-element-name)
|
80
119
|
- [Passing in a placeholder](#passing-in-a-placeholder)
|
81
120
|
- [Passing in an event name](#passing-in-an-event-name)
|
121
|
+
- [Using default events](#using-default-events)
|
122
|
+
- [Refreshing the partial](#refreshing-the-partial)
|
82
123
|
- [Retry on failure](#retry-on-failure)
|
124
|
+
- [Retry after some time](#retry-after-some-time)
|
83
125
|
- [Toggle event](#toggle-event)
|
126
|
+
- [Control polling with a toggle](#control-polling-with-a-toggle)
|
84
127
|
- [Polling](#polling)
|
128
|
+
- [Controlled polling](#controlled-polling)
|
85
129
|
- [Handling errors](#handling-errors)
|
86
130
|
- [Caching](#caching)
|
87
131
|
- [Doing non-GET requests](#doing-non-get-requests)
|
88
132
|
- [Using with Turbolinks](#using-with-turbolinks)
|
89
133
|
- [Using with respond_to and JS format](#using-with-respond_to-and-js-format)
|
90
|
-
- [Nested
|
91
|
-
- [
|
134
|
+
- [Nested async renders](#nested-async-renders)
|
135
|
+
- [Customizing the content_for name](#customizing-the-content_for-name)
|
136
|
+
- [Configuration options](#configuration-options)
|
92
137
|
|
93
138
|
### Passing in a container ID
|
94
139
|
|
@@ -133,23 +178,28 @@ Rendered code in the view:
|
|
133
178
|
`html_options` is an optional hash that gets passed to a Rails'
|
134
179
|
`javascript_tag`, to drop HTML tags into the `script` element.
|
135
180
|
|
136
|
-
Example of utilizing `html_options` with a
|
181
|
+
Example of utilizing `html_options` with a [nonce](https://edgeguides.rubyonrails.org/security.html#content-security-policy):
|
182
|
+
|
137
183
|
```erb
|
138
|
-
<%= render_async users_path, html_options: { nonce:
|
184
|
+
<%= render_async users_path, html_options: { nonce: true } %>
|
139
185
|
```
|
140
186
|
|
141
187
|
Rendered code in the view:
|
142
188
|
```html
|
143
|
-
<
|
144
|
-
</div>
|
145
|
-
|
146
|
-
<script nonce="lWaaV6eYicpt+oyOfcShYINsz0b70iR+Q1mohZqNaag=">
|
189
|
+
<script nonce="2x012CYGxKgM8qAApxRHxA==">
|
147
190
|
//<![CDATA[
|
148
191
|
...
|
149
192
|
//]]>
|
150
193
|
</script>
|
194
|
+
|
195
|
+
...
|
196
|
+
|
197
|
+
<div id="render_async_18b8a6cd161499117471" class="">
|
198
|
+
</div>
|
151
199
|
```
|
152
200
|
|
201
|
+
> :bulb: You can enable `nonce` to be set everywhere by using [configuration option](#configuration-option) render_async provides.
|
202
|
+
|
153
203
|
### Passing in an HTML element name
|
154
204
|
|
155
205
|
`render_async` can take in an HTML element name, allowing you to control
|
@@ -207,6 +257,9 @@ event after it's done with fetching and rendering request content to HTML.
|
|
207
257
|
This can be useful to have if you want to add some JavaScript functionality
|
208
258
|
after your partial is loaded through `render_async`.
|
209
259
|
|
260
|
+
You can also access the associated container (DOM node) in the event object
|
261
|
+
that gets emitted.
|
262
|
+
|
210
263
|
Example of passing it to `render_async`:
|
211
264
|
```erb
|
212
265
|
<%= render_async users_path, event_name: "users-loaded" %>
|
@@ -226,15 +279,77 @@ Rendered code in view:
|
|
226
279
|
</script>
|
227
280
|
```
|
228
281
|
|
229
|
-
Then, in your
|
282
|
+
Then, in your JavaScript code, you could do something like this:
|
230
283
|
```javascript
|
231
|
-
document.addEventListener("users-loaded", function() {
|
232
|
-
console.log("Users have loaded!");
|
284
|
+
document.addEventListener("users-loaded", function(event) {
|
285
|
+
console.log("Users have loaded!", event.container); // Access the container which loaded the users
|
286
|
+
});
|
287
|
+
```
|
288
|
+
|
289
|
+
> :bulb: Dispatching events is also supported for older browsers that don't support Event constructor.
|
290
|
+
|
291
|
+
### Using default events
|
292
|
+
|
293
|
+
`render_async` will fire the event `render_async_load` when an async partial
|
294
|
+
has loaded and rendered on page.
|
295
|
+
|
296
|
+
In case there is an error, the event `render_async_error` will fire instead.
|
297
|
+
|
298
|
+
This event will fire for all `render_async` partials on the page. For every
|
299
|
+
event, the associated container (DOM node) will be passed along.
|
300
|
+
|
301
|
+
This can be useful to apply JavaScript to content loaded after the page is
|
302
|
+
ready.
|
303
|
+
|
304
|
+
Example of using events:
|
305
|
+
|
306
|
+
```js
|
307
|
+
// Vanilla javascript
|
308
|
+
document.addEventListener('render_async_load', function(event) {
|
309
|
+
console.log('Async partial loaded in this container:', event.container);
|
310
|
+
});
|
311
|
+
document.addEventListener('render_async_error', function(event) {
|
312
|
+
console.log('Async partial could not load in this container:', event.container);
|
313
|
+
});
|
314
|
+
|
315
|
+
// with jQuery
|
316
|
+
$(document).on('render_async_load', function(event) {
|
317
|
+
console.log('Async partial loaded in this container:', event.container);
|
233
318
|
});
|
319
|
+
$(document).on('render_async_error', function(event) {
|
320
|
+
console.log('Async partial could not load in this container:', event.container);
|
321
|
+
});
|
322
|
+
```
|
323
|
+
|
324
|
+
### Refreshing the partial
|
325
|
+
|
326
|
+
`render_async` lets you refresh (reload) the partial by letting you dispatch
|
327
|
+
the 'refresh' event on the `render_async`'s container. An example:
|
328
|
+
|
329
|
+
```erb
|
330
|
+
<%= render_async comments_path,
|
331
|
+
container_id: 'refresh-me',
|
332
|
+
replace_container: false %>
|
333
|
+
|
334
|
+
<button id="refresh-button">Refresh comments</button>
|
335
|
+
|
336
|
+
<script>
|
337
|
+
var button = document.getElementById('refresh-button')
|
338
|
+
var container = document.getElementById('refresh-me');
|
339
|
+
|
340
|
+
button.addEventListener('click', function() {
|
341
|
+
var event = new Event('refresh');
|
342
|
+
|
343
|
+
// Dispatch 'refresh' on the render_async container
|
344
|
+
container.dispatchEvent(event)
|
345
|
+
})
|
346
|
+
</script>
|
234
347
|
```
|
235
348
|
|
236
|
-
|
237
|
-
|
349
|
+
If you follow the example above, when you click "Refresh comments" button,
|
350
|
+
`render_async` will trigger again and reload the `comments_path`.
|
351
|
+
|
352
|
+
> :bulb: Note that you need to pass `replace_container: false` so you can later dispatch an event on that container.
|
238
353
|
|
239
354
|
### Retry on failure
|
240
355
|
|
@@ -246,13 +361,46 @@ this:
|
|
246
361
|
<%= render_async users_path, retry_count: 5, error_message: "Couldn't fetch it" %>
|
247
362
|
```
|
248
363
|
|
249
|
-
Now render_async will retry `users_path` for 5 times. If it
|
364
|
+
Now render_async will retry `users_path` for 5 times. If it succeeds in
|
250
365
|
between, it will stop with dispatching requests. If it fails after 5 times,
|
251
366
|
it will show an [error message](#handling-errors) which you need to specify.
|
252
367
|
|
253
368
|
This can show useful when you know your requests often fail, and you don't want
|
254
369
|
to refresh the whole page just to retry them.
|
255
370
|
|
371
|
+
#### Retry after some time
|
372
|
+
|
373
|
+
If you want to retry requests but with some delay in between the calls, you can
|
374
|
+
pass a `retry_delay` option together with `retry_count` like so:
|
375
|
+
|
376
|
+
```erb
|
377
|
+
<%= render_async users_path,
|
378
|
+
retry_count: 5,
|
379
|
+
retry_delay: 2000 %>
|
380
|
+
```
|
381
|
+
|
382
|
+
This will make `render_async` wait for 2 seconds before retrying after each
|
383
|
+
failure. In the end, if the request is still failing after 5th time, it will
|
384
|
+
dispatch a [default error event](#using-default-events).
|
385
|
+
|
386
|
+
> :candy: If you are catching an event after an error, you can get `retryCount` from
|
387
|
+
the event. `retryCount` will have number of retries it took before the event was dispatched.
|
388
|
+
|
389
|
+
Here is an example on how to get `retryCount`:
|
390
|
+
|
391
|
+
```erb
|
392
|
+
<%= render_async users_path,
|
393
|
+
retry_count: 5,
|
394
|
+
retry_delay: 2000,
|
395
|
+
error_event_name: 'it-failed-badly' %>
|
396
|
+
|
397
|
+
<script>
|
398
|
+
document.addEventListener('it-failed-badly', function(event) {
|
399
|
+
console.log("Request failed after " + event.retryCount + " tries!")
|
400
|
+
});
|
401
|
+
</script>
|
402
|
+
```
|
403
|
+
|
256
404
|
### Toggle event
|
257
405
|
|
258
406
|
You can trigger `render_async` loading by clicking or doing another event to a
|
@@ -262,31 +410,53 @@ default event that will trigger `render_async` will be 'click' event. You can
|
|
262
410
|
do this by doing the following:
|
263
411
|
|
264
412
|
```erb
|
265
|
-
<a href='#' id='
|
266
|
-
<%= render_async comments_path, toggle: { selector: '#
|
413
|
+
<a href='#' id='comments-button'>Load comments</a>
|
414
|
+
<%= render_async comments_path, toggle: { selector: '#comments-button', event: :click } %>
|
267
415
|
```
|
268
416
|
|
269
|
-
This will trigger `render_async` to load the `comments_path` when you click the `#
|
417
|
+
This will trigger `render_async` to load the `comments_path` when you click the `#comments-button` element.
|
418
|
+
If you want to remove event once it's triggered, you can pass `once: true` in the toggle options.
|
419
|
+
The `once` option is false (`nil`) by default.
|
270
420
|
|
271
421
|
You can also pass in a placeholder before the `render_async` is triggered. That
|
272
422
|
way, the element that started `render_async` logic will be removed after the
|
273
423
|
request has been completed. You can achieve this behaviour with something like this:
|
274
424
|
|
275
425
|
```erb
|
276
|
-
<%= render_async comments_path, toggle: { selector: '#
|
277
|
-
<a href='#' id='
|
426
|
+
<%= render_async comments_path, toggle: { selector: '#comments-button', event: :click } do %>
|
427
|
+
<a href='#' id='comments-button'>Load comments</a>
|
278
428
|
<% end %>
|
279
429
|
```
|
280
430
|
|
431
|
+
#### Control polling with a toggle
|
432
|
+
|
281
433
|
Also, you can mix interval and toggle features. This way, you can turn polling
|
282
|
-
on, and off by clicking the "
|
434
|
+
on, and off by clicking the "Load comments" button. In order to do this, you need to
|
283
435
|
pass `toggle` and `interval` arguments to `render_async` call like this:
|
284
436
|
|
285
437
|
```erb
|
286
|
-
<a href='#' id='
|
287
|
-
<%= render_async comments_path, toggle: { selector: '#
|
438
|
+
<a href='#' id='comments-button'>Load comments</a>
|
439
|
+
<%= render_async comments_path, toggle: { selector: '#comments-button', event: :click }, interval: 2000 %>
|
440
|
+
```
|
441
|
+
|
442
|
+
If you want `render_async` to render the request on load, you can pass `start:
|
443
|
+
true`. Passing the `start` option inside the `toggle` hash will trigger
|
444
|
+
`render_async` on page load. You can then toggle off polling by interacting
|
445
|
+
with the element you specified. An example:
|
446
|
+
|
447
|
+
```erb
|
448
|
+
<a href='#' id='comments-button'>Toggle comments loading</a>
|
449
|
+
<%= render_async comments_path,
|
450
|
+
toggle: { selector: '#comments-button',
|
451
|
+
event: :click,
|
452
|
+
start: true },
|
453
|
+
interval: 2000 %>
|
288
454
|
```
|
289
455
|
|
456
|
+
In the example above, the comments will load as soon as the page is rendered.
|
457
|
+
Then, you can stop polling for comments by clicking the "Toggle comments
|
458
|
+
loading" button.
|
459
|
+
|
290
460
|
### Polling
|
291
461
|
|
292
462
|
You can call `render_async` with interval argument. This will make render_async
|
@@ -300,11 +470,61 @@ You are telling `render_async` to fetch comments_path every 5 seconds.
|
|
300
470
|
|
301
471
|
This can be handy if you want to enable polling for a specific URL.
|
302
472
|
|
303
|
-
|
304
|
-
will remain in HTML tree, it will not be replaced with request response.
|
305
|
-
You can handle how that container element is rendered and its style by
|
306
|
-
[passing in an HTML element name](#passing-in-an-html-element-name) and
|
307
|
-
[HTML element class](#passing-in-a-container-class-name).
|
473
|
+
> :warning: By passing interval to `render_async`, initial container element
|
474
|
+
> will remain in HTML tree, it will not be replaced with request response.
|
475
|
+
> You can handle how that container element is rendered and its style by
|
476
|
+
> [passing in an HTML element name](#passing-in-an-html-element-name) and
|
477
|
+
> [HTML element class](#passing-in-a-container-class-name).
|
478
|
+
|
479
|
+
### Controlled polling
|
480
|
+
|
481
|
+
You can controller `render_async` [polling](#polling) in 2 manners.
|
482
|
+
First one is pretty simple, and it involves using the [toggle](#toggle-event)
|
483
|
+
feature. To do this, you can follow instructions in the
|
484
|
+
[control polling with a toggle section](#control-polling-with-a-toggle).
|
485
|
+
|
486
|
+
Second option is more advanced and it involves emitting events to the `render_async`'s
|
487
|
+
container element. From your code, you can emit following events:
|
488
|
+
- 'async-stop' - this will stop polling
|
489
|
+
- 'async-start' - this will start polling.
|
490
|
+
|
491
|
+
> :bulb: Please note that events need to be dispatched to a render_async container.
|
492
|
+
|
493
|
+
An example of how you can do this looks like this:
|
494
|
+
|
495
|
+
```erb
|
496
|
+
<%= render_async wave_render_async_path,
|
497
|
+
container_id: 'controllable-interval', # set container_id so we can get it later easily
|
498
|
+
interval: 3000 %>
|
499
|
+
|
500
|
+
<button id='stop-polling'>Stop polling</button>
|
501
|
+
<button id='start-polling'>Start polling</button>
|
502
|
+
|
503
|
+
<script>
|
504
|
+
var container = document.getElementById('controllable-interval')
|
505
|
+
var stopPolling = document.getElementById('stop-polling')
|
506
|
+
var startPolling = document.getElementById('start-polling')
|
507
|
+
|
508
|
+
var triggerEventOnContainer = function(eventName) {
|
509
|
+
var event = new Event(eventName);
|
510
|
+
|
511
|
+
container.dispatchEvent(event)
|
512
|
+
}
|
513
|
+
|
514
|
+
stopPolling.addEventListener('click', function() {
|
515
|
+
container.innerHTML = '<p>Polling stopped</p>'
|
516
|
+
triggerEventOnContainer('async-stop')
|
517
|
+
})
|
518
|
+
startPolling.addEventListener('click', function() {
|
519
|
+
triggerEventOnContainer('async-start')
|
520
|
+
})
|
521
|
+
</script>
|
522
|
+
```
|
523
|
+
|
524
|
+
We are rendering two buttons - "Stop polling" and "Start polling". Then, we
|
525
|
+
attach event listener to catch any clicking on the buttons. When the buttons
|
526
|
+
are clicked, we either stop the polling, or start the polling, depending which
|
527
|
+
button a user clicks.
|
308
528
|
|
309
529
|
### Handling errors
|
310
530
|
|
@@ -354,10 +574,10 @@ Then, in the partial (e.g. `app/views/comments/_comment_stats.html.erb`):
|
|
354
574
|
<% end %>
|
355
575
|
```
|
356
576
|
|
357
|
-
|
358
|
-
|
577
|
+
- The first time the page renders, it will make the AJAX call.
|
578
|
+
- Any other times (until the cache expires), it will render from cache
|
359
579
|
instantly, without making the AJAX call.
|
360
|
-
|
580
|
+
- You can expire cache simply by passing `:expires_in` in your view where
|
361
581
|
you cache the partial
|
362
582
|
|
363
583
|
### Doing non-GET requests
|
@@ -386,7 +606,7 @@ away from, and then back to, a page with a `render_async` call on it. This will
|
|
386
606
|
likely show up as an empty div.
|
387
607
|
|
388
608
|
If you're using Turbolinks 5 or higher, you can resolve this by setting Turbolinks
|
389
|
-
|
609
|
+
configuration of `render_async` to true:
|
390
610
|
|
391
611
|
```rb
|
392
612
|
RenderAsync.configure do |config|
|
@@ -406,7 +626,7 @@ If you want, you can tell Turbolinks to reload your `render_async` call as follo
|
|
406
626
|
|
407
627
|
This will reload the whole page with Turbolinks.
|
408
628
|
|
409
|
-
Make sure to put `<%= content_for :render_async %>` in your base view file in
|
629
|
+
> :bulb: Make sure to put `<%= content_for :render_async %>` in your base view file in
|
410
630
|
the `<head>` and not the `<body>`.
|
411
631
|
|
412
632
|
### Using with respond_to and JS format
|
@@ -437,7 +657,7 @@ render call:
|
|
437
657
|
render partial: "comment_stats", content_type: 'text/html'
|
438
658
|
```
|
439
659
|
|
440
|
-
### Nested
|
660
|
+
### Nested async renders
|
441
661
|
|
442
662
|
It is possible to nest async templates within other async templates. When doing
|
443
663
|
so, another `content_for` is required to ensure the JavaScript needed to load
|
@@ -464,7 +684,20 @@ For example:
|
|
464
684
|
<%= content_for :render_async %>
|
465
685
|
```
|
466
686
|
|
467
|
-
###
|
687
|
+
### Customizing the content_for name
|
688
|
+
|
689
|
+
The `content_for` name may be customized by passing the `content_for_name`
|
690
|
+
option to `render_async`. This option is especially useful when doing [nested async
|
691
|
+
renders](#nested-async-renders) to better control the location of the injected JavaScript.
|
692
|
+
|
693
|
+
For example:
|
694
|
+
```erb
|
695
|
+
<%= render_async comment_stats_path, content_for_name: :render_async_comment_stats %>
|
696
|
+
|
697
|
+
<%= content_for :render_async_comment_stats %>
|
698
|
+
```
|
699
|
+
|
700
|
+
### Configuration options
|
468
701
|
|
469
702
|
`render_async` renders Vanilla JS (regular JavaScript, non-jQuery code)
|
470
703
|
**by default** in order to fetch the request from the server.
|
@@ -474,10 +707,13 @@ so.
|
|
474
707
|
|
475
708
|
You can configure it by doing the following anywhere before you call
|
476
709
|
`render_async`:
|
710
|
+
|
477
711
|
```rb
|
478
712
|
RenderAsync.configure do |config|
|
479
|
-
config.jquery = true # This will render jQuery code, and skip Vanilla JS code
|
480
|
-
config.turbolinks =
|
713
|
+
config.jquery = true # This will render jQuery code, and skip Vanilla JS code. The default value is false.
|
714
|
+
config.turbolinks = true # Enable this option if you are using Turbolinks 5+. The default value is false.
|
715
|
+
config.replace_container = false # Set to false if you want to keep the placeholder div element from render_async. The default value is true.
|
716
|
+
config.nonces = true # Set to true if you want render_async's javascript_tag to always receive nonce: true. The default value is false.
|
481
717
|
end
|
482
718
|
```
|
483
719
|
|
@@ -487,17 +723,35 @@ Also, you can do it like this:
|
|
487
723
|
RenderAsync.configuration.jquery = true
|
488
724
|
```
|
489
725
|
|
490
|
-
|
726
|
+
Aside from configuring whether the gem relies on jQuery or VanillaJS, you can
|
727
|
+
configure other options:
|
728
|
+
|
729
|
+
- `turbolinks` option - If you are using Turbolinks 5+, you should enable this option since it supports Turbolinks way of loading data. The default value for this options if false.
|
730
|
+
- `replace_container` option - If you want render_async to replace its container with the request response, turn this on. You can turn this on globally for all render_async calls, but if you use this option in a specific render_async call, it will override the global configuration. The default value is true.
|
731
|
+
- `nonces` - If you need to pass in `nonce: true` to the `javascript_tag` in your application, it might make sense for you to turn this on globally for all render_async calls. To read more about nonces, check out [Rails' official guide on security](https://edgeguides.rubyonrails.org/security.html). The default value is false.
|
732
|
+
|
733
|
+
## :hammer_and_pick: Development
|
491
734
|
|
492
735
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
493
736
|
`rake spec` to run the tests. You can also run `bin/console` for an interactive
|
494
|
-
prompt that will allow you to experiment.
|
737
|
+
prompt that will allow you to experiment. To run integration tests, use
|
738
|
+
`bin/integration-tests`.
|
739
|
+
|
740
|
+
Got any questions or comments about development (or anything else)?
|
741
|
+
Join [render_async's Discord channel](https://discord.gg/SPfbeRm)
|
742
|
+
and let's make `render_async` even better!
|
743
|
+
|
744
|
+
## :pray: Contributing
|
495
745
|
|
496
|
-
|
746
|
+
Thank you for considering or deciding to contribute, this is much appreciated!
|
747
|
+
Any kind of bug reports and pull requests are encouraged and welcome on GitHub at
|
748
|
+
https://github.com/renderedtext/render_async.
|
497
749
|
|
498
|
-
|
750
|
+
Got any issues or difficulties?
|
751
|
+
Join [render_async's Discord channel](https://discord.gg/SPfbeRm)
|
752
|
+
and let's make `render_async` even better!
|
499
753
|
|
500
|
-
## License
|
754
|
+
## :memo: License
|
501
755
|
|
502
756
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
503
757
|
|
@@ -510,7 +764,8 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds
|
|
510
764
|
| [<img src="https://avatars2.githubusercontent.com/u/3028124?v=4" width="100px;"/><br /><sub><b>Nikola Δuza</b></sub>](https://nikolalsvk.github.io)<br />[π¬](#question-nikolalsvk "Answering Questions") [π»](https://github.com/renderedtext/render_async/commits?author=nikolalsvk "Code") [π](https://github.com/renderedtext/render_async/commits?author=nikolalsvk "Documentation") [π](#review-nikolalsvk "Reviewed Pull Requests") | [<img src="https://avatars0.githubusercontent.com/u/3866868?v=4" width="100px;"/><br /><sub><b>Colin</b></sub>](http://www.colinxfleming.com)<br />[π»](https://github.com/renderedtext/render_async/commits?author=colinxfleming "Code") [π](https://github.com/renderedtext/render_async/commits?author=colinxfleming "Documentation") [π‘](#example-colinxfleming "Examples") | [<img src="https://avatars2.githubusercontent.com/u/334273?v=4" width="100px;"/><br /><sub><b>Kasper Grubbe</b></sub>](http://kaspergrubbe.com)<br />[π»](https://github.com/renderedtext/render_async/commits?author=kaspergrubbe "Code") | [<img src="https://avatars2.githubusercontent.com/u/163584?v=4" width="100px;"/><br /><sub><b>Sai Ram Kunala</b></sub>](https://sairam.xyz/)<br />[π](https://github.com/renderedtext/render_async/commits?author=sairam "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/3065882?v=4" width="100px;"/><br /><sub><b>Josh Arnold</b></sub>](https://github.com/nightsurge)<br />[π»](https://github.com/renderedtext/render_async/commits?author=nightsurge "Code") [π](https://github.com/renderedtext/render_async/commits?author=nightsurge "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/107798?v=4" width="100px;"/><br /><sub><b>Elad Shahar</b></sub>](https://eladshahar.com)<br />[π»](https://github.com/renderedtext/render_async/commits?author=SaladFork "Code") [π‘](#example-SaladFork "Examples") | [<img src="https://avatars3.githubusercontent.com/u/232392?v=4" width="100px;"/><br /><sub><b>Sasha</b></sub>](http://www.revzin.co.il)<br />[π»](https://github.com/renderedtext/render_async/commits?author=sasharevzin "Code") [π](https://github.com/renderedtext/render_async/commits?author=sasharevzin "Documentation") |
|
511
765
|
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
|
512
766
|
| [<img src="https://avatars3.githubusercontent.com/u/50223?v=4" width="100px;"/><br /><sub><b>Ernest Surudo</b></sub>](http://elsurudo.com)<br />[π»](https://github.com/renderedtext/render_async/commits?author=elsurudo "Code") | [<img src="https://avatars1.githubusercontent.com/u/334809?v=4" width="100px;"/><br /><sub><b>Kurtis Rainbolt-Greene</b></sub>](https://kurtis.rainbolt-greene.online)<br />[π»](https://github.com/renderedtext/render_async/commits?author=krainboltgreene "Code") | [<img src="https://avatars2.githubusercontent.com/u/59744?v=4" width="100px;"/><br /><sub><b>Richard Schneeman</b></sub>](https://www.schneems.com)<br />[π](https://github.com/renderedtext/render_async/commits?author=schneems "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/75705?v=4" width="100px;"/><br /><sub><b>Richard Venneman</b></sub>](https://www.cityspotters.com)<br />[π](https://github.com/renderedtext/render_async/commits?author=richardvenneman "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/381395?v=4" width="100px;"/><br /><sub><b>Filipe W. Lima</b></sub>](https://github.com/filipewl)<br />[π](https://github.com/renderedtext/render_async/commits?author=filipewl "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/3135638?v=4" width="100px;"/><br /><sub><b>JesΓΊs Eduardo Clemens Chong</b></sub>](https://github.com/eclemens)<br />[π»](https://github.com/renderedtext/render_async/commits?author=eclemens "Code") | [<img src="https://avatars3.githubusercontent.com/u/1935686?v=4" width="100px;"/><br /><sub><b>RenΓ© KlaΔan</b></sub>](https://github.com/reneklacan)<br />[π»](https://github.com/renderedtext/render_async/commits?author=reneklacan "Code") |
|
513
|
-
| [<img src="https://avatars1.githubusercontent.com/u/1313442?v=4" width="100px;"/><br /><sub><b>Gil Gomes</b></sub>](http://gilgomes.com.br)<br />[π](https://github.com/renderedtext/render_async/commits?author=gil27 "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/6081795?v=4" width="100px;"/><br /><sub><b>Khoa Nguyen</b></sub>](https://github.com/ThanhKhoaIT)<br />[π»](https://github.com/renderedtext/render_async/commits?author=ThanhKhoaIT "Code") [π](https://github.com/renderedtext/render_async/commits?author=ThanhKhoaIT "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/8645918?v=4" width="100px;"/><br /><sub><b>Preet Sethi</b></sub>](https://www.linkedin.com/in/preetsethila/)<br />[π»](https://github.com/renderedtext/render_async/commits?author=preetsethi "Code") | [<img src="https://avatars3.githubusercontent.com/u/11586335?v=4" width="100px;"/><br /><sub><b>fangxing</b></sub>](https://github.com/fffx)<br />[π»](https://github.com/renderedtext/render_async/commits?author=fffx "Code") |
|
767
|
+
| [<img src="https://avatars1.githubusercontent.com/u/1313442?v=4" width="100px;"/><br /><sub><b>Gil Gomes</b></sub>](http://gilgomes.com.br)<br />[π](https://github.com/renderedtext/render_async/commits?author=gil27 "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/6081795?v=4" width="100px;"/><br /><sub><b>Khoa Nguyen</b></sub>](https://github.com/ThanhKhoaIT)<br />[π»](https://github.com/renderedtext/render_async/commits?author=ThanhKhoaIT "Code") [π](https://github.com/renderedtext/render_async/commits?author=ThanhKhoaIT "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/8645918?v=4" width="100px;"/><br /><sub><b>Preet Sethi</b></sub>](https://www.linkedin.com/in/preetsethila/)<br />[π»](https://github.com/renderedtext/render_async/commits?author=preetsethi "Code") | [<img src="https://avatars3.githubusercontent.com/u/11586335?v=4" width="100px;"/><br /><sub><b>fangxing</b></sub>](https://github.com/fffx)<br />[π»](https://github.com/renderedtext/render_async/commits?author=fffx "Code") | [<img src="https://avatars3.githubusercontent.com/u/1191418?v=4" width="100px;"/><br /><sub><b>Emmanuel Pire</b></sub>](http://blog.lipsumarium.com)<br />[π»](https://github.com/renderedtext/render_async/commits?author=lipsumar "Code") [π](https://github.com/renderedtext/render_async/commits?author=lipsumar "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/615509?v=4" width="100px;"/><br /><sub><b>Maxim Geerinck</b></sub>](https://github.com/maximgeerinck)<br />[π»](https://github.com/renderedtext/render_async/commits?author=maximgeerinck "Code") | [<img src="https://avatars1.githubusercontent.com/u/251706?v=4" width="100px;"/><br /><sub><b>Don</b></sub>](https://github.com/vanboom)<br />[π»](https://github.com/renderedtext/render_async/commits?author=vanboom "Code") |
|
768
|
+
| [<img src="https://avatars0.githubusercontent.com/u/998682?v=4" width="100px;"/><br /><sub><b>villu164</b></sub>](https://github.com/villu164)<br />[π](https://github.com/renderedtext/render_async/commits?author=villu164 "Documentation") |
|
514
769
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
515
770
|
|
516
771
|
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|