render_async 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +125 -14
- data/app/views/render_async/_render_async.html.erb +27 -9
- data/app/views/render_async/_request_jquery.js.erb +45 -0
- data/app/views/render_async/_request_vanilla.js.erb +56 -0
- data/lib/render_async.rb +19 -0
- data/lib/render_async/configuration.rb +9 -0
- data/lib/render_async/version.rb +1 -1
- data/lib/render_async/view_helper.rb +13 -2
- metadata +4 -2
- data/app/views/render_async/_request.js.erb +0 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 301c0dec3cac35c32dd7946334151d2c968fe8f182006b1e67e4fc21655e1899
|
4
|
+
data.tar.gz: 0df8c63b19c81621726efb95c993377caa81c554ba29d29d782451f5a4116d21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 261185dde786cf96d86e1d9abb5e9d67d0b0b431786adb4459f3f230621d55e34ebd89ed98950f27fb0541af355c26150ef766bae254e3ea28d7367f504ce388
|
7
|
+
data.tar.gz: 6af545d420676f1a39c98fe43dda6c63f66c8d944faab86ed57f4912dfc65243b6e350a538156389d5ed7e3ae63a579c28cd1a4161597bb09d504c79c9b93dfa
|
data/README.md
CHANGED
@@ -26,11 +26,10 @@ JavaScript is injected into `<%= content_for :render_async %>` so you choose
|
|
26
26
|
where to put it.
|
27
27
|
|
28
28
|
## Installation
|
29
|
-
S
|
30
29
|
Add this line to your application's Gemfile:
|
31
30
|
|
32
31
|
```ruby
|
33
|
-
gem '
|
32
|
+
gem 'render_async'
|
34
33
|
```
|
35
34
|
|
36
35
|
And then execute:
|
@@ -46,7 +45,7 @@ And then execute:
|
|
46
45
|
|
47
46
|
2. Then create a route that will `config/routes.rb`:
|
48
47
|
```ruby
|
49
|
-
get :comment_stats, :
|
48
|
+
get :comment_stats, controller: :comments
|
50
49
|
```
|
51
50
|
|
52
51
|
3. Fill in the logic in your controller (e.g. `app/controllers/comments_controller.rb`):
|
@@ -54,7 +53,7 @@ And then execute:
|
|
54
53
|
def comment_stats
|
55
54
|
@stats = Comment.get_stats
|
56
55
|
|
57
|
-
render :
|
56
|
+
render partial: "comment_stats"
|
58
57
|
end
|
59
58
|
```
|
60
59
|
|
@@ -74,23 +73,62 @@ And then execute:
|
|
74
73
|
|
75
74
|
Advanced usage includes information on different options, such as:
|
76
75
|
|
76
|
+
- [Passing in a container ID](#passing-in-a-container-id)
|
77
|
+
- [Passing in a container class name](#passing-in-a-container-class-name)
|
77
78
|
- [Passing in HTML options](#passing-in-html-options)
|
78
79
|
- [Passing in an HTML element name](#passing-in-an-html-element-name)
|
79
80
|
- [Passing in a placeholder](#passing-in-a-placeholder)
|
80
81
|
- [Passing in an event name](#passing-in-an-event-name)
|
82
|
+
- [Handling errors](#handling-errors)
|
81
83
|
- [Caching](#caching)
|
84
|
+
- [Doing non-GET requests](#doing-non-get-requests)
|
82
85
|
- [Using with Turbolinks](#using-with-turbolinks)
|
83
86
|
- [Using with respond_to and JS format](#using-with-respond_to-and-js-format)
|
84
87
|
- [Nested Async Renders](#nested-async-renders)
|
88
|
+
- [Configuration](#configuration)
|
85
89
|
|
86
|
-
### Passing in
|
90
|
+
### Passing in a container ID
|
91
|
+
|
92
|
+
`render_async` renders an element that gets replaced with the content
|
93
|
+
of your request response. In order to have more control over the element
|
94
|
+
that renders first (before the request), you can set the ID of that element.
|
95
|
+
|
96
|
+
To set ID of the container element, you can do the following:
|
97
|
+
```erb
|
98
|
+
<%= render_async users_path, container_id: 'users-container' %>
|
99
|
+
```
|
100
|
+
|
101
|
+
Rendered code in the view:
|
102
|
+
```html
|
103
|
+
<div id="users-container">
|
104
|
+
</div>
|
105
|
+
|
106
|
+
...
|
107
|
+
```
|
108
|
+
|
109
|
+
### Passing in a container class name
|
87
110
|
|
88
|
-
`render_async`
|
111
|
+
`render_async` renders an element that gets replaced with the content of your
|
112
|
+
request response. If you want to style that element, you can set the class name
|
113
|
+
on it.
|
114
|
+
|
115
|
+
```erb
|
116
|
+
<%= render_async users_path, container_class: 'users-container-class' %>
|
117
|
+
```
|
118
|
+
|
119
|
+
Rendered code in the view:
|
120
|
+
```html
|
121
|
+
<div id="render_async_18b8a6cd161499117471" class="users-container-class">
|
122
|
+
</div>
|
123
|
+
|
124
|
+
...
|
125
|
+
```
|
126
|
+
|
127
|
+
### Passing in HTML options
|
89
128
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
`javascript_tag`, to drop html tags into the `script` element.
|
129
|
+
`render_async` can accept `html_options` argument.
|
130
|
+
`html_options` is an optional hash that gets passed to a Rails'
|
131
|
+
`javascript_tag`, to drop HTML tags into the `script` element.
|
94
132
|
|
95
133
|
Example of utilizing `html_options` with a `nonce`:
|
96
134
|
```erb
|
@@ -168,7 +206,7 @@ after your partial is loaded through `render_async`.
|
|
168
206
|
|
169
207
|
Example of passing it to `render_async`:
|
170
208
|
```erb
|
171
|
-
<%= render_async users_path, :
|
209
|
+
<%= render_async users_path, event_name: "users-loaded" %>
|
172
210
|
```
|
173
211
|
|
174
212
|
Rendered code in view:
|
@@ -192,6 +230,38 @@ document.addEventListener("users-loaded", function() {
|
|
192
230
|
});
|
193
231
|
```
|
194
232
|
|
233
|
+
NOTE: Dispatching events is also supported for older browsers that don't
|
234
|
+
support Event constructor.
|
235
|
+
|
236
|
+
### Handling errors
|
237
|
+
|
238
|
+
`render_async` let's you handle errors by allowing you to pass in `error_message`
|
239
|
+
and `error_event_name`.
|
240
|
+
|
241
|
+
- `error_message`
|
242
|
+
|
243
|
+
passing an `error_message` will render a message if the AJAX requests fails for
|
244
|
+
some reason
|
245
|
+
```erb
|
246
|
+
<%= render_async users_path,
|
247
|
+
error_message: '<p>Sorry, users loading went wrong :(</p>' %>
|
248
|
+
```
|
249
|
+
|
250
|
+
- `error_event_name`
|
251
|
+
|
252
|
+
calling `render_async` with `error_event_name` will dispatch event in the case
|
253
|
+
of an error with your AJAX call.
|
254
|
+
```erb
|
255
|
+
<%= render_asyc users_path, error_event_name: 'users-error-event' %>
|
256
|
+
```
|
257
|
+
|
258
|
+
You can then catch the event in your code with:
|
259
|
+
```js
|
260
|
+
document.addEventListener('users-error-event', function() {
|
261
|
+
// I'm on it
|
262
|
+
})
|
263
|
+
```
|
264
|
+
|
195
265
|
### Caching
|
196
266
|
|
197
267
|
`render_async` can utilize view fragment caching to avoid extra AJAX calls.
|
@@ -204,7 +274,7 @@ In your views (e.g. `app/views/comments/show.html.erb`):
|
|
204
274
|
|
205
275
|
Then, in the partial (e.g. `app/views/comments/_comment_stats.html.erb`):
|
206
276
|
```erb
|
207
|
-
<% cache render_async_cache_key(request.path), :
|
277
|
+
<% cache render_async_cache_key(request.path), skip_digest: true do %>
|
208
278
|
<div class="col-md-6">
|
209
279
|
<%= @stats %>
|
210
280
|
</div>
|
@@ -217,6 +287,25 @@ Then, in the partial (e.g. `app/views/comments/_comment_stats.html.erb`):
|
|
217
287
|
* You can expire cache simply by passing `:expires_in` in your view where
|
218
288
|
you cache the partial
|
219
289
|
|
290
|
+
### Doing non-GET requests
|
291
|
+
|
292
|
+
By default, `render_async` creates AJAX GET requests for the path you provide.
|
293
|
+
If you want to change this behaviour, you can pass in a `method` argument to
|
294
|
+
`render_async` view helper.
|
295
|
+
|
296
|
+
```erb
|
297
|
+
<%= render_async users_path, method: 'POST' %>
|
298
|
+
```
|
299
|
+
|
300
|
+
You can also set `body` and `headers` of the request if you need them.
|
301
|
+
|
302
|
+
```erb
|
303
|
+
<%= render_async users_path,
|
304
|
+
method: 'POST',
|
305
|
+
data: { fresh: 'AF' },
|
306
|
+
headers: { 'Content-Type': 'text' } %>
|
307
|
+
```
|
308
|
+
|
220
309
|
### Using with Turbolinks
|
221
310
|
|
222
311
|
On Turbolinks applications, you may experience caching issues when navigating
|
@@ -243,7 +332,7 @@ def comment_stats
|
|
243
332
|
format.js do
|
244
333
|
@stats = Comment.get_stats
|
245
334
|
|
246
|
-
render :
|
335
|
+
render partial: "comment_stats"
|
247
336
|
end
|
248
337
|
end
|
249
338
|
end
|
@@ -257,7 +346,7 @@ You can get around it by specifying the content type to `text/html` in the
|
|
257
346
|
render call:
|
258
347
|
|
259
348
|
```ruby
|
260
|
-
render :
|
349
|
+
render partial: "comment_stats", content_type: 'text/html'
|
261
350
|
```
|
262
351
|
|
263
352
|
### Nested Async Renders
|
@@ -287,6 +376,28 @@ For example:
|
|
287
376
|
<%= content_for :render_async %>
|
288
377
|
```
|
289
378
|
|
379
|
+
### Configuration
|
380
|
+
|
381
|
+
`render_async` renders Vanilla JS (regular JavaScript, non-jQuery code)
|
382
|
+
**by default** in order to fetch the request from the server.
|
383
|
+
|
384
|
+
If you want `render_async` to use jQuery code, you need to configure it to do
|
385
|
+
so.
|
386
|
+
|
387
|
+
You can configure it by doing the following anywhere before you call
|
388
|
+
`render_async`:
|
389
|
+
```rb
|
390
|
+
RenderAsync.configure do |config|
|
391
|
+
jquery = true # This will render jQuery code, and skip Vanilla JS code
|
392
|
+
end
|
393
|
+
```
|
394
|
+
|
395
|
+
Also, you can do it like this:
|
396
|
+
```rb
|
397
|
+
# This will render jQuery code, and skip Vanilla JS code
|
398
|
+
RenderAsync.configuration.jquery = true
|
399
|
+
```
|
400
|
+
|
290
401
|
## Development
|
291
402
|
|
292
403
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
@@ -1,16 +1,34 @@
|
|
1
|
-
<<%= html_element_name %>
|
1
|
+
<<%= html_element_name %>
|
2
|
+
id="<%= container_id %>"
|
3
|
+
class="<%= container_class %>"
|
4
|
+
>
|
2
5
|
<%= placeholder %>
|
3
6
|
</<%= html_element_name %>>
|
4
7
|
|
5
8
|
<% content_for :render_async do %>
|
6
9
|
<%= javascript_tag html_options do %>
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
<% if RenderAsync.configuration.jquery %>
|
11
|
+
<%= render partial: 'render_async/request_jquery',
|
12
|
+
formats: [:js],
|
13
|
+
locals: { container_id: container_id,
|
14
|
+
path: path,
|
15
|
+
method: method,
|
16
|
+
data: data,
|
17
|
+
event_name: event_name,
|
18
|
+
headers: headers,
|
19
|
+
error_message: error_message,
|
20
|
+
error_event_name: error_event_name } %>
|
21
|
+
<% else %>
|
22
|
+
<%= render partial: 'render_async/request_vanilla',
|
23
|
+
formats: [:js],
|
24
|
+
locals: { container_id: container_id,
|
25
|
+
path: path,
|
26
|
+
method: method,
|
27
|
+
data: data,
|
28
|
+
event_name: event_name,
|
29
|
+
headers: headers,
|
30
|
+
error_message: error_message,
|
31
|
+
error_event_name: error_event_name } %>
|
32
|
+
<% end %>
|
15
33
|
<% end %>
|
16
34
|
<% end %>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
if (window.jQuery) {
|
2
|
+
(function($) {
|
3
|
+
$(document).ready(function() {
|
4
|
+
var headers = <%= headers.to_json.html_safe %>;
|
5
|
+
var csrfTokenElement = document.querySelector('meta[name="csrf-token"]')
|
6
|
+
if (csrfTokenElement)
|
7
|
+
headers['X-CSRF-Token'] = csrfTokenElement.content
|
8
|
+
|
9
|
+
$.ajax({
|
10
|
+
url: '<%= path.html_safe %>',
|
11
|
+
method: '<%= method %>',
|
12
|
+
data: "<%= escape_javascript(data.to_s.html_safe) %>",
|
13
|
+
headers: headers
|
14
|
+
}).done(function(response) {
|
15
|
+
$("#<%= container_id %>").replaceWith(response);
|
16
|
+
|
17
|
+
<% if event_name.present? %>
|
18
|
+
var event = undefined;
|
19
|
+
if (typeof(Event) === 'function') {
|
20
|
+
event = new Event("<%= event_name %>");
|
21
|
+
} else {
|
22
|
+
event = document.createEvent('Event');
|
23
|
+
event.initEvent('<%= event_name %>', true, true);
|
24
|
+
}
|
25
|
+
document.dispatchEvent(event);
|
26
|
+
<% end %>
|
27
|
+
}).error(function(response) {
|
28
|
+
$("#<%= container_id %>").replaceWith('<%= error_message.try(:html_safe) %>');
|
29
|
+
|
30
|
+
<% if error_event_name.present? %>
|
31
|
+
var event = undefined;
|
32
|
+
if (typeof(Event) === 'function') {
|
33
|
+
event = new Event("<%= error_event_name %>");
|
34
|
+
} else {
|
35
|
+
event = document.createEvent('Event');
|
36
|
+
event.initEvent('<%= error_event_name %>', true, true);
|
37
|
+
}
|
38
|
+
document.dispatchEvent(event);
|
39
|
+
<% end %>
|
40
|
+
});
|
41
|
+
});
|
42
|
+
}(jQuery));
|
43
|
+
} else {
|
44
|
+
console.warn("Looks like you've enabled jQuery for render_async, but jQuery is not defined");
|
45
|
+
};
|
@@ -0,0 +1,56 @@
|
|
1
|
+
(function() {
|
2
|
+
document.addEventListener("DOMContentLoaded", function() {
|
3
|
+
var request = new XMLHttpRequest();
|
4
|
+
var asyncRequest = true;
|
5
|
+
var SUCCESS = 200;
|
6
|
+
var ERROR = 400;
|
7
|
+
|
8
|
+
request.open('<%= method %>', '<%= path.html_safe %>', asyncRequest);
|
9
|
+
|
10
|
+
var headers = <%= headers.to_json.html_safe %>;
|
11
|
+
var csrfTokenElement = document.querySelector('meta[name="csrf-token"]')
|
12
|
+
if (csrfTokenElement)
|
13
|
+
headers['X-CSRF-Token'] = csrfTokenElement.content
|
14
|
+
|
15
|
+
Object.keys(headers).map(function(key) {
|
16
|
+
request.setRequestHeader(key, headers[key]);
|
17
|
+
});
|
18
|
+
|
19
|
+
request.onreadystatechange = function() {
|
20
|
+
if (request.readyState === 4) {
|
21
|
+
if (request.status >= SUCCESS && request.status < ERROR) {
|
22
|
+
var container = document.getElementById('<%= container_id %>');
|
23
|
+
container.outerHTML = request.response;
|
24
|
+
|
25
|
+
<% if event_name.present? %>
|
26
|
+
var event = undefined;
|
27
|
+
if (typeof(Event) === 'function') {
|
28
|
+
event = new Event("<%= event_name %>");
|
29
|
+
} else {
|
30
|
+
event = document.createEvent('Event');
|
31
|
+
event.initEvent('<%= event_name %>', true, true);
|
32
|
+
}
|
33
|
+
document.dispatchEvent(event);
|
34
|
+
<% end %>
|
35
|
+
} else {
|
36
|
+
var container = document.getElementById('<%= container_id %>');
|
37
|
+
container.outerHTML = '<%= error_message.try(:html_safe) %>';
|
38
|
+
|
39
|
+
<% if error_event_name.present? %>
|
40
|
+
var event = undefined;
|
41
|
+
if (typeof(Event) === 'function') {
|
42
|
+
event = new Event("<%= error_event_name %>");
|
43
|
+
} else {
|
44
|
+
event = document.createEvent('Event');
|
45
|
+
event.initEvent('<%= error_event_name %>', true, true);
|
46
|
+
}
|
47
|
+
document.dispatchEvent(event);
|
48
|
+
<% end %>
|
49
|
+
}
|
50
|
+
}
|
51
|
+
};
|
52
|
+
|
53
|
+
var body = "<%= escape_javascript(data.to_s.html_safe) %>";
|
54
|
+
request.send(body);
|
55
|
+
});
|
56
|
+
})();
|
data/lib/render_async.rb
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
require "render_async/version"
|
2
2
|
require "render_async/view_helper"
|
3
3
|
require "render_async/engine" if defined? Rails
|
4
|
+
require "render_async/configuration"
|
4
5
|
|
5
6
|
ActionView::Base.send :include, RenderAsync::ViewHelper if defined? ActionView::Base
|
7
|
+
|
8
|
+
module RenderAsync
|
9
|
+
class << self
|
10
|
+
attr_accessor :configuration
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.configuration
|
14
|
+
@configuration ||= RenderAsync::Configuration.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.reset
|
18
|
+
@configuration = RenderAsync::Configuration.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.configure
|
22
|
+
yield(configuration)
|
23
|
+
end
|
24
|
+
end
|
data/lib/render_async/version.rb
CHANGED
@@ -19,23 +19,34 @@ module RenderAsync
|
|
19
19
|
|
20
20
|
def render_async(path, options = {}, &placeholder)
|
21
21
|
html_element_name = options.delete(:html_element_name) || 'div'
|
22
|
-
container_id =
|
22
|
+
container_id = options.delete(:container_id) || generate_container_id
|
23
|
+
container_class = options.delete(:container_class)
|
23
24
|
event_name = options.delete(:event_name)
|
24
25
|
placeholder = capture(&placeholder) if block_given?
|
25
26
|
method = options.delete(:method) || 'GET'
|
26
27
|
data = options.delete(:data)
|
27
28
|
headers = options.delete(:headers) || {}
|
29
|
+
error_message = options.delete(:error_message)
|
30
|
+
error_event_name = options.delete(:error_event_name)
|
28
31
|
|
29
32
|
render 'render_async/render_async', html_element_name: html_element_name,
|
30
33
|
container_id: container_id,
|
34
|
+
container_class: container_class,
|
31
35
|
path: path,
|
32
36
|
html_options: options,
|
33
37
|
event_name: event_name,
|
34
38
|
placeholder: placeholder,
|
35
39
|
method: method,
|
36
40
|
data: data,
|
37
|
-
headers: headers
|
41
|
+
headers: headers,
|
42
|
+
error_message: error_message,
|
43
|
+
error_event_name: error_event_name
|
38
44
|
end
|
39
45
|
|
46
|
+
private
|
47
|
+
|
48
|
+
def generate_container_id
|
49
|
+
"render_async_#{SecureRandom.hex(5)}#{Time.now.to_i}"
|
50
|
+
end
|
40
51
|
end
|
41
52
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: render_async
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kasper Grubbe
|
@@ -83,11 +83,13 @@ files:
|
|
83
83
|
- README.md
|
84
84
|
- Rakefile
|
85
85
|
- app/views/render_async/_render_async.html.erb
|
86
|
-
- app/views/render_async/
|
86
|
+
- app/views/render_async/_request_jquery.js.erb
|
87
|
+
- app/views/render_async/_request_vanilla.js.erb
|
87
88
|
- bin/console
|
88
89
|
- bin/integration-tests
|
89
90
|
- bin/setup
|
90
91
|
- lib/render_async.rb
|
92
|
+
- lib/render_async/configuration.rb
|
91
93
|
- lib/render_async/engine.rb
|
92
94
|
- lib/render_async/version.rb
|
93
95
|
- lib/render_async/view_helper.rb
|
@@ -1,57 +0,0 @@
|
|
1
|
-
if (window.jQuery) {
|
2
|
-
(function($) {
|
3
|
-
$(document).ready(function() {
|
4
|
-
var headers = <%= headers.to_json.html_safe %>;
|
5
|
-
var csrfTokenElement = document.querySelector('meta[name="csrf-token"]')
|
6
|
-
if (csrfTokenElement)
|
7
|
-
headers['X-CSRF-Token'] = csrfTokenElement.content
|
8
|
-
|
9
|
-
$.ajax({
|
10
|
-
url: '<%= path.html_safe %>',
|
11
|
-
method: '<%= method %>',
|
12
|
-
data: "<%= escape_javascript(data.to_s.html_safe) %>",
|
13
|
-
headers: headers
|
14
|
-
}).always(function(response) {
|
15
|
-
$("#<%= container_id %>").replaceWith(response);
|
16
|
-
|
17
|
-
<% if event_name.present? %>
|
18
|
-
document.dispatchEvent(new Event("<%= event_name %>"));
|
19
|
-
<% end %>
|
20
|
-
});
|
21
|
-
});
|
22
|
-
}(jQuery));
|
23
|
-
} else {
|
24
|
-
(function() {
|
25
|
-
document.addEventListener("DOMContentLoaded", function() {
|
26
|
-
var request = new XMLHttpRequest();
|
27
|
-
var asyncRequest = true;
|
28
|
-
var SUCCESS = 200;
|
29
|
-
var ERROR = 400;
|
30
|
-
|
31
|
-
request.open('<%= method %>', '<%= path.html_safe %>', asyncRequest);
|
32
|
-
|
33
|
-
var headers = <%= headers.to_json.html_safe %>;
|
34
|
-
var csrfTokenElement = document.querySelector('meta[name="csrf-token"]')
|
35
|
-
if (csrfTokenElement)
|
36
|
-
headers['X-CSRF-Token'] = csrfTokenElement.content
|
37
|
-
|
38
|
-
Object.keys(headers).map(function(key) {
|
39
|
-
request.setRequestHeader(key, headers[key]);
|
40
|
-
});
|
41
|
-
|
42
|
-
request.onload = function() {
|
43
|
-
if (request.status >= SUCCESS && request.status < ERROR) {
|
44
|
-
var container = document.getElementById('<%= container_id %>');
|
45
|
-
container.outerHTML = request.response;
|
46
|
-
|
47
|
-
<% if event_name.present? %>
|
48
|
-
document.dispatchEvent(new Event("<%= event_name %>"));
|
49
|
-
<% end %>
|
50
|
-
}
|
51
|
-
};
|
52
|
-
|
53
|
-
var body = "<%= escape_javascript(data.to_s.html_safe) %>";
|
54
|
-
request.send(body);
|
55
|
-
});
|
56
|
-
})();
|
57
|
-
}
|