render_async 2.1.4 β†’ 2.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35597f0995adbebc4f107d97119e8788124cab866f374fbf17145aed6d9b4cab
4
- data.tar.gz: bdf3a4230bed1b7a16f06247320e382afef3429bb807a5372cd42352f0350f31
3
+ metadata.gz: 6efd10ad97f50cae5b58a0ff6042df5c0b9f5ed0b27ca1a498f4cdb84172ab79
4
+ data.tar.gz: 8daab586cb6b11d66bc873e12929ee2bb1162a6b5578e343ddeb6f03c1094c71
5
5
  SHA512:
6
- metadata.gz: 4177b9a1a8c89b8a02059d0d2b2e871191ff5fec2f141de5321897884d5628dbc95468b5783f6ef8ae988c3a0fb82519d5a68c120fd4cbca88c22ea8209579b4
7
- data.tar.gz: '0149a06b46673296d341a253aa50219778216208ec1a7a30da869128d8380080652cd74dd40684cb97389107d551df0ec9fe71f1dfc9daa8cb62e0826a15132b'
6
+ metadata.gz: aaa98a754f9cbce70521702793d6307fbb976b064a9b981a7a5c43db5dd12527cfa81f5a07269476958f12ae0f0f2a79a4038236146cda6a2bfc2e23b3c36fbf
7
+ data.tar.gz: db95a549cd0d1f3ee086ad35634cf53f94e615de679dd201a543432337e99de43cf9b080d9c10296a0e1e2391e48bedf16717fd868fe7ec7ecae3c35ce7bb384
data/.all-contributorsrc CHANGED
@@ -177,6 +177,53 @@
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
+ ]
217
+ },
218
+ {
219
+ "login": "Mbuckley0",
220
+ "name": "Mitchell Buckley",
221
+ "avatar_url": "https://avatars.githubusercontent.com/u/11203679?v=4",
222
+ "profile": "https://github.com/Mbuckley0",
223
+ "contributions": [
224
+ "code",
225
+ "doc"
226
+ ]
180
227
  }
181
228
  ],
182
229
  "repoType": "github"
@@ -0,0 +1,40 @@
1
+ # :pray: Contributing
2
+
3
+ Thank you for considering or deciding to contribute, this is much appreciated!
4
+ Any kind of bug reports and pull requests are encouraged and welcome on GitHub at
5
+ https://github.com/renderedtext/render_async.
6
+
7
+ ## :inbox_tray: Installing dependencies
8
+
9
+ You can install all needed dependencies by running `bin/setup`.
10
+
11
+ ## :runner: Running RSpec tests
12
+
13
+ You can run either `rake spec` or `bundle exec rspec` to run all the RSpec tests
14
+ in the project.
15
+
16
+ ## :running_woman: Running integration tests
17
+
18
+ There is a simple command `bin/integration-tests` which sets up 2 submodules,
19
+ and runs Cucumber features in them.
20
+
21
+ There are 2 submodules for render_async. The submodules are Rails 5 and Rails 6
22
+ projects which are located in:
23
+
24
+ - `spec/fixtures/rails-5-base-app`, and
25
+ - `spec/fixtures/rails-6-base-app`.
26
+
27
+ You can find [Rails 5 base app here](https://github.com/nikolalsvk/rails-5-base-app/tree/render-async),
28
+ and the [Rails 6 base app here](https://github.com/nikolalsvk/rails-6-base-app/tree/render-async).
29
+
30
+ Each of them have different use cases of render_async defined in `app/views/render_asyncs/_use_cases.html.erb` in their repos.
31
+ All the feature tests are inside `features/render_async.feature` and `features/render_async_jquery.feature` files.
32
+
33
+ If you are adding one or more feature tests or use cases, make sure to make a
34
+ PR on those repos as well and include them in the PR on the render_async repo.
35
+
36
+ ## :sos: Need help?
37
+
38
+ Got any issues or difficulties?
39
+ Join [render_async's Discord channel](https://discord.gg/SPfbeRm)
40
+ and ask questions there. We will try to respond to you as quickly as possible.
@@ -0,0 +1,3 @@
1
+ github: nikolalsvk
2
+ tidelift: rubygems/render_async
3
+ custom: "https://www.paypal.me/nikolalsvk/10"
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .DS_Store
data/.gitmodules CHANGED
@@ -2,3 +2,7 @@
2
2
  path = spec/fixtures/rails-5-base-app
3
3
  url = git@github.com:nikolalsvk/rails-5-base-app.git
4
4
  branch = render-async
5
+ [submodule "spec/fixtures/rails-6-base-app"]
6
+ path = spec/fixtures/rails-6-base-app
7
+ url = git@github.com:nikolalsvk/rails-6-base-app.git
8
+ branch = render-async
data/CHANGELOG.md CHANGED
@@ -1,8 +1,50 @@
1
- ### 2.1.1 (2019/8/17)
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
- [![Build Status](https://semaphoreci.com/api/v1/renderedtext/render_async/branches/master/shields_badge.svg)](https://semaphoreci.com/renderedtext/render_async)
2
- [![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors)
3
- [![Gem Version](https://badge.fury.io/rb/render_async.svg)](https://badge.fury.io/rb/render_async)
4
- [![Code Climate](https://codeclimate.com/github/renderedtext/render_async/badges/gpa.svg)](https://codeclimate.com/github/renderedtext/render_async)
5
- [![Test Coverage](https://codeclimate.com/github/renderedtext/render_async/badges/coverage.svg)](https://codeclimate.com/github/renderedtext/render_async/coverage)
6
- [![Help Contribute to Open Source](https://www.codetriage.com/renderedtext/render_async/badges/users.svg)](https://www.codetriage.com/renderedtext/render_async)
7
-
8
- ![render_async](http://s2blog.wpengine.com/wp-content/uploads/assets/images/2017-06-08/speed-up-rendering-rails-pages-with-render-async.png)
9
-
10
- # render_async
11
-
12
- Speed up rendering Rails pages with this gem.
13
-
14
- `render_async` renders partials to your views **asynchronously**. This is done
15
- through adding JavaScript code that does AJAX request to your controller which
16
- then renders your partial into a Rails view.
17
-
18
- Workflow:
19
-
20
- 1. user visits a Rails page
21
- 2. AJAX request on the controller action
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. partials renders in the place where you put `render_async` helper
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
- ## Installation
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,14 +75,14 @@ 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
43
82
  <%= render_async comment_stats_path %>
44
83
  ```
45
84
 
46
- 2. Then create a route that will `config/routes.rb`:
85
+ 2. Then create a route for it `config/routes.rb`:
47
86
  ```ruby
48
87
  get :comment_stats, controller: :comments
49
88
  ```
@@ -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,23 @@ 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)
133
+ - [Using with Turbo](#using-with-turbo)
89
134
  - [Using with respond_to and JS format](#using-with-respond_to-and-js-format)
90
- - [Nested Async Renders](#nested-async-renders)
91
- - [Configuration](#configuration)
135
+ - [Nested async renders](#nested-async-renders)
136
+ - [Customizing the content_for name](#customizing-the-content_for-name)
137
+ - [Configuration options](#configuration-options)
92
138
 
93
139
  ### Passing in a container ID
94
140
 
@@ -133,23 +179,28 @@ Rendered code in the view:
133
179
  `html_options` is an optional hash that gets passed to a Rails'
134
180
  `javascript_tag`, to drop HTML tags into the `script` element.
135
181
 
136
- Example of utilizing `html_options` with a `nonce`:
182
+ Example of utilizing `html_options` with a [nonce](https://edgeguides.rubyonrails.org/security.html#content-security-policy):
183
+
137
184
  ```erb
138
- <%= render_async users_path, html_options: { nonce: 'lWaaV6eYicpt+oyOfcShYINsz0b70iR+Q1mohZqNaag=' } %>
185
+ <%= render_async users_path, html_options: { nonce: true } %>
139
186
  ```
140
187
 
141
188
  Rendered code in the view:
142
189
  ```html
143
- <div id="render_async_18b8a6cd161499117471">
144
- </div>
145
-
146
- <script nonce="lWaaV6eYicpt+oyOfcShYINsz0b70iR+Q1mohZqNaag=">
190
+ <script nonce="2x012CYGxKgM8qAApxRHxA==">
147
191
  //<![CDATA[
148
192
  ...
149
193
  //]]>
150
194
  </script>
195
+
196
+ ...
197
+
198
+ <div id="render_async_18b8a6cd161499117471" class="">
199
+ </div>
151
200
  ```
152
201
 
202
+ > :bulb: You can enable `nonce` to be set everywhere by using [configuration option](#configuration-options) render_async provides.
203
+
153
204
  ### Passing in an HTML element name
154
205
 
155
206
  `render_async` can take in an HTML element name, allowing you to control
@@ -207,6 +258,9 @@ event after it's done with fetching and rendering request content to HTML.
207
258
  This can be useful to have if you want to add some JavaScript functionality
208
259
  after your partial is loaded through `render_async`.
209
260
 
261
+ You can also access the associated container (DOM node) in the event object
262
+ that gets emitted.
263
+
210
264
  Example of passing it to `render_async`:
211
265
  ```erb
212
266
  <%= render_async users_path, event_name: "users-loaded" %>
@@ -226,15 +280,77 @@ Rendered code in view:
226
280
  </script>
227
281
  ```
228
282
 
229
- Then, in your JS, you could do something like this:
283
+ Then, in your JavaScript code, you could do something like this:
230
284
  ```javascript
231
- document.addEventListener("users-loaded", function() {
232
- console.log("Users have loaded!");
285
+ document.addEventListener("users-loaded", function(event) {
286
+ console.log("Users have loaded!", event.container); // Access the container which loaded the users
233
287
  });
234
288
  ```
235
289
 
236
- NOTE: Dispatching events is also supported for older browsers that don't
237
- support Event constructor.
290
+ > :bulb: Dispatching events is also supported for older browsers that don't support Event constructor.
291
+
292
+ ### Using default events
293
+
294
+ `render_async` will fire the event `render_async_load` when an async partial
295
+ has loaded and rendered on the page.
296
+
297
+ In case there is an error, the event `render_async_error` will fire instead.
298
+
299
+ This event will fire for all `render_async` partials on the page. For every
300
+ event, the associated container (DOM node) will be passed along.
301
+
302
+ This can be useful to apply JavaScript to content loaded after the page is
303
+ ready.
304
+
305
+ Example of using events:
306
+
307
+ ```js
308
+ // Vanilla javascript
309
+ document.addEventListener('render_async_load', function(event) {
310
+ console.log('Async partial loaded in this container:', event.container);
311
+ });
312
+ document.addEventListener('render_async_error', function(event) {
313
+ console.log('Async partial could not load in this container:', event.container);
314
+ });
315
+
316
+ // with jQuery
317
+ $(document).on('render_async_load', function(event) {
318
+ console.log('Async partial loaded in this container:', event.container);
319
+ });
320
+ $(document).on('render_async_error', function(event) {
321
+ console.log('Async partial could not load in this container:', event.container);
322
+ });
323
+ ```
324
+
325
+ ### Refreshing the partial
326
+
327
+ `render_async` lets you refresh (reload) the partial by letting you dispatch
328
+ the 'refresh' event on the `render_async`'s container. An example:
329
+
330
+ ```erb
331
+ <%= render_async comments_path,
332
+ container_id: 'refresh-me',
333
+ replace_container: false %>
334
+
335
+ <button id="refresh-button">Refresh comments</button>
336
+
337
+ <script>
338
+ var button = document.getElementById('refresh-button')
339
+ var container = document.getElementById('refresh-me');
340
+
341
+ button.addEventListener('click', function() {
342
+ var event = new Event('refresh');
343
+
344
+ // Dispatch 'refresh' on the render_async container
345
+ container.dispatchEvent(event)
346
+ })
347
+ </script>
348
+ ```
349
+
350
+ If you follow the example above, when you click "Refresh comments" button,
351
+ `render_async` will trigger again and reload the `comments_path`.
352
+
353
+ > :bulb: Note that you need to pass `replace_container: false` so you can later dispatch an event on that container.
238
354
 
239
355
  ### Retry on failure
240
356
 
@@ -246,13 +362,46 @@ this:
246
362
  <%= render_async users_path, retry_count: 5, error_message: "Couldn't fetch it" %>
247
363
  ```
248
364
 
249
- Now render_async will retry `users_path` for 5 times. If it succedes in
365
+ Now render_async will retry `users_path` for 5 times. If it succeeds in
250
366
  between, it will stop with dispatching requests. If it fails after 5 times,
251
367
  it will show an [error message](#handling-errors) which you need to specify.
252
368
 
253
369
  This can show useful when you know your requests often fail, and you don't want
254
370
  to refresh the whole page just to retry them.
255
371
 
372
+ #### Retry after some time
373
+
374
+ If you want to retry requests but with some delay in between the calls, you can
375
+ pass a `retry_delay` option together with `retry_count` like so:
376
+
377
+ ```erb
378
+ <%= render_async users_path,
379
+ retry_count: 5,
380
+ retry_delay: 2000 %>
381
+ ```
382
+
383
+ This will make `render_async` wait for 2 seconds before retrying after each
384
+ failure. In the end, if the request is still failing after 5th time, it will
385
+ dispatch a [default error event](#using-default-events).
386
+
387
+ > :candy: If you are catching an event after an error, you can get `retryCount` from
388
+ the event. `retryCount` will have the number of retries it took before the event was dispatched.
389
+
390
+ Here is an example on how to get `retryCount`:
391
+
392
+ ```erb
393
+ <%= render_async users_path,
394
+ retry_count: 5,
395
+ retry_delay: 2000,
396
+ error_event_name: 'it-failed-badly' %>
397
+
398
+ <script>
399
+ document.addEventListener('it-failed-badly', function(event) {
400
+ console.log("Request failed after " + event.retryCount + " tries!")
401
+ });
402
+ </script>
403
+ ```
404
+
256
405
  ### Toggle event
257
406
 
258
407
  You can trigger `render_async` loading by clicking or doing another event to a
@@ -262,37 +411,57 @@ default event that will trigger `render_async` will be 'click' event. You can
262
411
  do this by doing the following:
263
412
 
264
413
  ```erb
265
- <a href='#' id='detail-button'>Detail</a>
266
- <%= render_async comments_path, toggle: { selector: '#detail-button', event: :click } %>
414
+ <a href='#' id='comments-button'>Load comments</a>
415
+ <%= render_async comments_path, toggle: { selector: '#comments-button', event: :click } %>
267
416
  ```
268
417
 
269
- This will trigger `render_async` to load the `comments_path` when you click the `#details-button` element.
270
- If you wannt to remove event once it's triggered, you can pass `once: true` in the toggle options.
271
- The `once` option is false by default.
418
+ This will trigger `render_async` to load the `comments_path` when you click the `#comments-button` element.
419
+ If you want to remove an event once it's triggered, you can pass `once: true` in the toggle options.
420
+ The `once` option is false (`nil`) by default.
272
421
 
273
422
  You can also pass in a placeholder before the `render_async` is triggered. That
274
423
  way, the element that started `render_async` logic will be removed after the
275
424
  request has been completed. You can achieve this behaviour with something like this:
276
425
 
277
426
  ```erb
278
- <%= render_async comments_path, toggle: { selector: '#detail-button', event: :click } do %>
279
- <a href='#' id='detail-button'>Detail</a>
427
+ <%= render_async comments_path, toggle: { selector: '#comments-button', event: :click } do %>
428
+ <a href='#' id='comments-button'>Load comments</a>
280
429
  <% end %>
281
430
  ```
282
431
 
432
+ #### Control polling with a toggle
433
+
283
434
  Also, you can mix interval and toggle features. This way, you can turn polling
284
- on, and off by clicking the "Detail" button. In order to do this, you need to
435
+ on, and off by clicking the "Load comments" button. In order to do this, you need to
285
436
  pass `toggle` and `interval` arguments to `render_async` call like this:
286
437
 
287
438
  ```erb
288
- <a href='#' id='detail-button'>Detail</a>
289
- <%= render_async comments_path, toggle: { selector: '#detail-button', event: :click }, interval: 2000 %>
439
+ <a href='#' id='comments-button'>Load comments</a>
440
+ <%= render_async comments_path, toggle: { selector: '#comments-button', event: :click }, interval: 2000 %>
441
+ ```
442
+
443
+ If you want `render_async` to render the request on load, you can pass `start:
444
+ true`. Passing the `start` option inside the `toggle` hash will trigger
445
+ `render_async` on page load. You can then toggle off polling by interacting
446
+ with the element you specified. An example:
447
+
448
+ ```erb
449
+ <a href='#' id='comments-button'>Toggle comments loading</a>
450
+ <%= render_async comments_path,
451
+ toggle: { selector: '#comments-button',
452
+ event: :click,
453
+ start: true },
454
+ interval: 2000 %>
290
455
  ```
291
456
 
457
+ In the example above, the comments will load as soon as the page is rendered.
458
+ Then, you can stop polling for comments by clicking the "Toggle comments
459
+ loading" button.
460
+
292
461
  ### Polling
293
462
 
294
463
  You can call `render_async` with interval argument. This will make render_async
295
- call specified path at specified interval.
464
+ call specified path at the specified interval.
296
465
 
297
466
  By doing this:
298
467
  ```erb
@@ -302,15 +471,65 @@ You are telling `render_async` to fetch comments_path every 5 seconds.
302
471
 
303
472
  This can be handy if you want to enable polling for a specific URL.
304
473
 
305
- NOTE: By passing interval to `render_async`, initial container element
306
- will remain in HTML tree, it will not be replaced with request response.
307
- You can handle how that container element is rendered and its style by
308
- [passing in an HTML element name](#passing-in-an-html-element-name) and
309
- [HTML element class](#passing-in-a-container-class-name).
474
+ > :warning: By passing interval to `render_async`, the initial container element
475
+ > will remain in the HTML tree and it will not be replaced with request response.
476
+ > You can handle how that container element is rendered and its style by
477
+ > [passing in an HTML element name](#passing-in-an-html-element-name) and
478
+ > [HTML element class](#passing-in-a-container-class-name).
479
+
480
+ ### Controlled polling
481
+
482
+ You can controller `render_async` [polling](#polling) in 2 manners.
483
+ First one is pretty simple, and it involves using the [toggle](#toggle-event)
484
+ feature. To do this, you can follow instructions in the
485
+ [control polling with a toggle section](#control-polling-with-a-toggle).
486
+
487
+ The second option is more advanced and it involves emitting events to the `render_async`'s
488
+ container element. From your code, you can emit the following events:
489
+ - 'async-stop' - this will stop polling
490
+ - 'async-start' - this will start polling.
491
+
492
+ > :bulb: Please note that events need to be dispatched to a render_async container.
493
+
494
+ An example of how you can do this looks like this:
495
+
496
+ ```erb
497
+ <%= render_async wave_render_async_path,
498
+ container_id: 'controllable-interval', # set container_id so we can get it later easily
499
+ interval: 3000 %>
500
+
501
+ <button id='stop-polling'>Stop polling</button>
502
+ <button id='start-polling'>Start polling</button>
503
+
504
+ <script>
505
+ var container = document.getElementById('controllable-interval')
506
+ var stopPolling = document.getElementById('stop-polling')
507
+ var startPolling = document.getElementById('start-polling')
508
+
509
+ var triggerEventOnContainer = function(eventName) {
510
+ var event = new Event(eventName);
511
+
512
+ container.dispatchEvent(event)
513
+ }
514
+
515
+ stopPolling.addEventListener('click', function() {
516
+ container.innerHTML = '<p>Polling stopped</p>'
517
+ triggerEventOnContainer('async-stop')
518
+ })
519
+ startPolling.addEventListener('click', function() {
520
+ triggerEventOnContainer('async-start')
521
+ })
522
+ </script>
523
+ ```
524
+
525
+ We are rendering two buttons - "Stop polling" and "Start polling". Then, we
526
+ attach an event listener to catch any clicking on the buttons. When the buttons
527
+ are clicked, we either stop the polling or start the polling, depending on which
528
+ button a user clicks.
310
529
 
311
530
  ### Handling errors
312
531
 
313
- `render_async` let's you handle errors by allowing you to pass in `error_message`
532
+ `render_async` lets you handle errors by allowing you to pass in `error_message`
314
533
  and `error_event_name`.
315
534
 
316
535
  - `error_message`
@@ -356,10 +575,10 @@ Then, in the partial (e.g. `app/views/comments/_comment_stats.html.erb`):
356
575
  <% end %>
357
576
  ```
358
577
 
359
- * The first time the page renders, it will make the AJAX call.
360
- * Any other times (until the cache expires), it will render from cache
578
+ - The first time the page renders, it will make the AJAX call.
579
+ - Any other times (until the cache expires), it will render from cache
361
580
  instantly, without making the AJAX call.
362
- * You can expire cache simply by passing `:expires_in` in your view where
581
+ - You can expire cache simply by passing `:expires_in` in your view where
363
582
  you cache the partial
364
583
 
365
584
  ### Doing non-GET requests
@@ -388,7 +607,7 @@ away from, and then back to, a page with a `render_async` call on it. This will
388
607
  likely show up as an empty div.
389
608
 
390
609
  If you're using Turbolinks 5 or higher, you can resolve this by setting Turbolinks
391
- configurtion of `render_async` to true:
610
+ configuration of `render_async` to true:
392
611
 
393
612
  ```rb
394
613
  RenderAsync.configure do |config|
@@ -397,7 +616,7 @@ end
397
616
  ```
398
617
 
399
618
  This way, you're not breaking Turbolinks flow of loading or reloading a page.
400
- It makes it more efficient that the next option that is suggested below.
619
+ It is more efficient than the next option below.
401
620
 
402
621
  Another option:
403
622
  If you want, you can tell Turbolinks to reload your `render_async` call as follows:
@@ -408,8 +627,38 @@ If you want, you can tell Turbolinks to reload your `render_async` call as follo
408
627
 
409
628
  This will reload the whole page with Turbolinks.
410
629
 
411
- Make sure to put `<%= content_for :render_async %>` in your base view file in
412
- the `<head>` and not the `<body>`.
630
+ > :bulb: If Turbolinks is misbehaving in some way, make sure to put `<%= content_for :render_async %>` in your base view file in
631
+ the `<body>` and not the `<head>`.
632
+
633
+ ### Using with Turbo
634
+
635
+ On Turbo applications, you may experience caching issues when navigating
636
+ away from, and then back to, a page with a `render_async` call on it. This will
637
+ likely show up as an empty div.
638
+
639
+ If you're using Turbo, you can resolve this by setting Turbo
640
+ configuration of `render_async` to true:
641
+
642
+ ```rb
643
+ RenderAsync.configure do |config|
644
+ config.turbo = true # Enable this option if you are using Turbo
645
+ end
646
+ ```
647
+
648
+ This way, you're not breaking Turbos flow of loading or reloading a page.
649
+ It is more efficient than the next option below.
650
+
651
+ Another option:
652
+ If you want, you can tell Turbo to reload your `render_async` call as follows:
653
+
654
+ ```erb
655
+ <%= render_async events_path, 'data-turbo-track': 'reload' %>
656
+ ```
657
+
658
+ This will reload the whole page with Turbo.
659
+
660
+ > :bulb: If Turbo is misbehaving in some way, make sure to put `<%= content_for :render_async %>` in your base view file in
661
+ the `<body>` and not the `<head>`.
413
662
 
414
663
  ### Using with respond_to and JS format
415
664
 
@@ -428,7 +677,7 @@ def comment_stats
428
677
  end
429
678
  ```
430
679
 
431
- When you do this, Rails will sometime set the response's `Content-Type` header
680
+ When you do this, Rails will sometimes set the response's `Content-Type` header
432
681
  to `text/javascript`. This causes the partial not to be rendered in the HTML.
433
682
  This usually happens when there's browser caching.
434
683
 
@@ -439,7 +688,7 @@ render call:
439
688
  render partial: "comment_stats", content_type: 'text/html'
440
689
  ```
441
690
 
442
- ### Nested Async Renders
691
+ ### Nested async renders
443
692
 
444
693
  It is possible to nest async templates within other async templates. When doing
445
694
  so, another `content_for` is required to ensure the JavaScript needed to load
@@ -466,7 +715,20 @@ For example:
466
715
  <%= content_for :render_async %>
467
716
  ```
468
717
 
469
- ### Configuration
718
+ ### Customizing the content_for name
719
+
720
+ The `content_for` name may be customized by passing the `content_for_name`
721
+ option to `render_async`. This option is especially useful when doing [nested async
722
+ renders](#nested-async-renders) to better control the location of the injected JavaScript.
723
+
724
+ For example:
725
+ ```erb
726
+ <%= render_async comment_stats_path, content_for_name: :render_async_comment_stats %>
727
+
728
+ <%= content_for :render_async_comment_stats %>
729
+ ```
730
+
731
+ ### Configuration options
470
732
 
471
733
  `render_async` renders Vanilla JS (regular JavaScript, non-jQuery code)
472
734
  **by default** in order to fetch the request from the server.
@@ -476,10 +738,14 @@ so.
476
738
 
477
739
  You can configure it by doing the following anywhere before you call
478
740
  `render_async`:
741
+
479
742
  ```rb
480
743
  RenderAsync.configure do |config|
481
- config.jquery = true # This will render jQuery code, and skip Vanilla JS code
482
- config.turbolinks = false # Enable this option if you are using Turbolinks 5+
744
+ config.jquery = true # This will render jQuery code, and skip Vanilla JS code. The default value is false.
745
+ config.turbolinks = true # Enable this option if you are using Turbolinks 5+. The default value is false.
746
+ config.turbo = true # Enable this option if you are using Turbo. The default value is false.
747
+ config.replace_container = false # Set to false if you want to keep the placeholder div element from render_async. The default value is true.
748
+ config.nonces = true # Set to true if you want render_async's javascript_tag always to receive nonce: true. The default value is false.
483
749
  end
484
750
  ```
485
751
 
@@ -489,17 +755,34 @@ Also, you can do it like this:
489
755
  RenderAsync.configuration.jquery = true
490
756
  ```
491
757
 
492
- ## Development
758
+ Aside from configuring whether the gem relies on jQuery or VanillaJS, you can
759
+ configure other options:
760
+
761
+ - `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 option is false.
762
+ - `turbo` option - If you are using Turbo, you should enable this option since it supports Turbo way of loading data. The default value for this option is false.
763
+ - `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.
764
+ - `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.
765
+
766
+ ## :hammer_and_pick: Development
493
767
 
494
768
  After checking out the repo, run `bin/setup` to install dependencies. Then, run
495
769
  `rake spec` to run the tests. You can also run `bin/console` for an interactive
496
- prompt that will allow you to experiment.
770
+ prompt that will allow you to experiment. To run integration tests, use
771
+ `bin/integration-tests`. For more information, check out [CONTRIBUTING](.github/CONTRIBUTING.md) file, please.
772
+
773
+ Got any questions or comments about development (or anything else)?
774
+ Join [render_async's Discord channel](https://discord.gg/SPfbeRm)
775
+ and let's make `render_async` even better!
776
+
777
+ ## :pray: Contributing
497
778
 
498
- ## Contributing
779
+ Check out [CONTRIBUTING](.github/CONTRIBUTING.md) file, please.
499
780
 
500
- Bug reports and pull requests are welcome on GitHub at https://github.com/renderedtext/render_async.
781
+ Got any issues or difficulties?
782
+ Join [render_async's Discord channel](https://discord.gg/SPfbeRm)
783
+ and let's make `render_async` even better!
501
784
 
502
- ## License
785
+ ## :memo: License
503
786
 
504
787
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
505
788
 
@@ -512,7 +795,8 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds
512
795
  | [<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") |
513
796
  | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
514
797
  | [<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") |
515
- | [<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") |
798
+ | [<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") |
799
+ | [<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") | [<img src="https://avatars.githubusercontent.com/u/11203679?v=4" width="100px;"/><br /><sub><b>Mitchell Buckley</b></sub>](https://github.com/Mbuckley0)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=Mbuckley0 "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=Mbuckley0 "Documentation") |
516
800
  <!-- ALL-CONTRIBUTORS-LIST:END -->
517
801
 
518
802
  This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!