turbolinks-form 0.0.8 → 0.1.1
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 +5 -5
- data/.ruby-version +1 -1
- data/README.md +21 -4
- data/app/assets/javascripts/turbolinks-form-core.js +102 -29
- data/app/assets/javascripts/turbolinks-form.js +0 -2
- data/lib/turbolinks/form/version.rb +1 -1
- data/turbolinks-form.gemspec +2 -3
- metadata +7 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8b77ba89542729448f2aadebe15d0c9670177eb3b4e3536bacc952b95e265760
|
4
|
+
data.tar.gz: 86e38d90648bd666b48d9e764bbde9e1cbbc70a6459baa56f0593ec5b06417d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e02c2aee43939ae74fe3909ad88ae82c5a358347931c138e78c54eb374dc59077ded68c924ea14527591c5b4864c838f305183a20dca1dbc0805326c33df5949
|
7
|
+
data.tar.gz: 8a9ad6b6dc562279c648fab5e387a17d66553dd07d6aac381561a4a76ced10cab3f9b3436b437ee809adaec7ed8e685c74fbb61c72cacc22382d1920ddd5ef16
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.4.
|
1
|
+
ruby-2.4.4
|
data/README.md
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
# turbolinks-form
|
2
2
|
|
3
|
-
[](https://gemnasium.com/github.com/hsgubert/turbolinks-form)
|
4
3
|
[](https://badge.fury.io/rb/turbolinks-form)
|
5
4
|
|
6
5
|
Turbolinks 5 extension to render form errors after a submit.
|
7
6
|
|
7
|
+
## Requirements
|
8
|
+
|
9
|
+
* Rails >= 4.3 (tested with 4.3, 5.0 and 5.1)
|
10
|
+
* [Turbolinks 5](https://github.com/turbolinks/turbolinks)
|
11
|
+
* Either [rails-ujs](https://github.com/rails/rails-ujs) (included in Rails 5.1) or [jquery-ujs](https://github.com/rails/jquery-ujs)
|
12
|
+
|
8
13
|
## Installation
|
9
14
|
|
10
15
|
Add the gem to your `Gemfile`
|
@@ -21,8 +26,15 @@ Add the javascript to your `application.js` or to your `vendor.js`
|
|
21
26
|
//= require turbolinks-form
|
22
27
|
```
|
23
28
|
|
24
|
-
This will automatically include
|
29
|
+
This will automatically include Turbolinks if not included already.
|
25
30
|
|
31
|
+
You must have included either rails-ujs or jquery-ujs in your assets. This gem does not include any of them as to let you choose your preference.
|
32
|
+
``` javascript
|
33
|
+
//= require jquery_ujs
|
34
|
+
```
|
35
|
+
``` javascript
|
36
|
+
//= require rails-ujs
|
37
|
+
```
|
26
38
|
|
27
39
|
## Basic Usage
|
28
40
|
|
@@ -100,9 +112,14 @@ Turbolinks-form will trigger only a subset of the (Turbolink events)[https://git
|
|
100
112
|
#### Graceful Degradation
|
101
113
|
When the request is not `xhr`, `turbolinks-form` degrades gracefully to regular rendering (with full page load).
|
102
114
|
|
103
|
-
#### Browser
|
115
|
+
#### Browser History
|
104
116
|
Turbolinks-form ignores browser history. It does not push any new state nor replaces the last state.
|
105
117
|
|
106
|
-
|
118
|
+
#### Error Handling
|
119
|
+
When your server responds with an error 500 or 404, turbolinks-form replaces the whole page (head
|
120
|
+
and body). The reason we do this is that applications usually have a whole different set of styles
|
121
|
+
for error pages and probably need the head of the page to be replaced as well as the body. This
|
122
|
+
behavior is consistent with Turbolinks.
|
107
123
|
|
124
|
+
## License
|
108
125
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
@@ -13,15 +13,46 @@
|
|
13
13
|
// This doesn't mean it does ALL what turbolinks does. For example, we don't
|
14
14
|
// merge script tags from old and new page <head> elements.
|
15
15
|
// This also doesn't change the browser history or does any change to the URL.
|
16
|
-
// The reason we don't do such things is simply that this is a solution to
|
17
|
-
// render errors in forms, and usually we render the same page/form rendered
|
16
|
+
// The reason we don't do such things is simply that this gem is a solution to
|
17
|
+
// render errors in forms, and usually we render the same page/form we had rendered
|
18
18
|
// before the submit.
|
19
19
|
|
20
20
|
var TurbolinksForm = function(){};
|
21
21
|
|
22
|
-
|
22
|
+
// Attach an event handler function for one or more events to the selected elements.
|
23
|
+
// This method is inspired by JQuery on() and was created so that we could remove the dependency
|
24
|
+
// on JQuery.
|
25
|
+
// Ref: https://stackoverflow.com/questions/25248286/native-js-equivalent-to-jquery-delegation#answer-46595740
|
26
|
+
TurbolinksForm.on = function(eventHandlerOwner, event, delegateSelector, handler) {
|
27
|
+
// handles call with 3 arguments
|
28
|
+
if (!handler && delegateSelector) {
|
29
|
+
handler = delegateSelector;
|
30
|
+
delegateSelector = undefined;
|
31
|
+
}
|
32
|
+
|
33
|
+
$(eventHandlerOwner).on(event, function(e) {
|
34
|
+
if (delegateSelector) {
|
35
|
+
// goes up the dom tree searching for the delegate
|
36
|
+
var currentTarget = e.target;
|
37
|
+
while (!currentTarget.matches(delegateSelector) && currentTarget !== this) {
|
38
|
+
currentTarget = currentTarget.parentElement;
|
39
|
+
}
|
40
|
+
|
41
|
+
// if delegate found, call the handler there
|
42
|
+
if (currentTarget.matches(delegateSelector)) {
|
43
|
+
handler.apply(currentTarget, arguments);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
// if there is no delegation, just call the handler directly
|
47
|
+
else {
|
48
|
+
handler.apply(eventHandlerOwner, arguments);
|
49
|
+
}
|
50
|
+
});
|
51
|
+
}
|
52
|
+
|
53
|
+
TurbolinksForm.handleResponse = function(xhr, renderingError) {
|
23
54
|
// parses response
|
24
|
-
var newDom = new DOMParser().parseFromString(
|
55
|
+
var newDom = new DOMParser().parseFromString(xhr.responseText, "text/html");
|
25
56
|
|
26
57
|
// Some browsers (PhantomJS and earlier versions of Firefox and IE) don't implement
|
27
58
|
// parsing from string for "text/html" format. So we use an alternative method
|
@@ -29,7 +60,7 @@ TurbolinksForm.handleResponse = function(response, renderingError) {
|
|
29
60
|
// https://developer.mozilla.org/en-US/Add-ons/Code_snippets/HTML_to_DOM#Parsing_Complete_HTML_to_DOM
|
30
61
|
if (newDom == null) {
|
31
62
|
newDom = document.implementation.createHTMLDocument("document");
|
32
|
-
newDom.documentElement.innerHTML =
|
63
|
+
newDom.documentElement.innerHTML = xhr.responseText;
|
33
64
|
}
|
34
65
|
|
35
66
|
if (newDom == null) {
|
@@ -63,16 +94,25 @@ TurbolinksForm.handleResponse = function(response, renderingError) {
|
|
63
94
|
|
64
95
|
// if there is no target, replaces whole body
|
65
96
|
var target;
|
66
|
-
if (!
|
97
|
+
if (!xhr.getResponseHeader('turbolinks-form-render-target') || renderingError) {
|
67
98
|
document.body = newDom.body;
|
68
99
|
target = document.body;
|
69
|
-
}
|
70
|
-
|
71
|
-
|
72
|
-
|
100
|
+
}
|
101
|
+
// if there is a specific target
|
102
|
+
else {
|
103
|
+
target = document.body.querySelector(xhr.getResponseHeader('turbolinks-form-render-target'));
|
104
|
+
if (target) {
|
105
|
+
// clears target contents
|
106
|
+
while (target.firstChild) {
|
107
|
+
target.removeChild(target.firstChild);
|
108
|
+
}
|
109
|
+
// fills target with new content
|
110
|
+
while (newDom.body.firstChild) {
|
111
|
+
target.appendChild(newDom.body.removeChild(newDom.body.firstChild));
|
112
|
+
}
|
73
113
|
}
|
74
|
-
|
75
|
-
|
114
|
+
else {
|
115
|
+
console.warn('[turbolinks-form] target not found for selector: ' + xhr.getResponseHeader('turbolinks-form-render-target'));
|
76
116
|
}
|
77
117
|
}
|
78
118
|
|
@@ -101,22 +141,35 @@ TurbolinksForm.handleResponse = function(response, renderingError) {
|
|
101
141
|
//
|
102
142
|
// PS: it is also activated on errors with code 500 or 404, so that we can know the
|
103
143
|
// error is happening and not that the site is unresponsive
|
104
|
-
|
144
|
+
TurbolinksForm.on(document, "ajax:error", function(e, xhr) {
|
145
|
+
// When using rails-ujs (instead of jquery-ujs) this handler receives a single event parameter
|
146
|
+
// and other parameters must be extracted from e.detail
|
147
|
+
// Ref: https://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html#rails-ujs-event-handlers
|
148
|
+
if (!xhr && e.detail)
|
149
|
+
var xhr = e.detail[2];
|
150
|
+
|
151
|
+
// Replaces whole body and whole head when a true error occurs (same behavior as turbolinks)
|
152
|
+
// This is done even when there is no turbolinks-form-render header (this affects all AJAX requests)
|
153
|
+
// because when an error occurrs this header is not added by the server
|
154
|
+
var isError500 = (xhr.status == 500)
|
155
|
+
var isError404 = (xhr.status == 404)
|
156
|
+
if (isError500 || isError404) {
|
157
|
+
console.info("Error Response handled by turbolinks-form");
|
158
|
+
TurbolinksForm.handleResponse(xhr, true);
|
159
|
+
return;
|
160
|
+
}
|
161
|
+
|
162
|
+
// does not intercept unrelated AJAX responses
|
163
|
+
if (!xhr || !xhr.getResponseHeader('turbolinks-form-render'))
|
164
|
+
return;
|
165
|
+
|
105
166
|
// dispatches turbolinks event
|
106
|
-
Turbolinks.dispatch('turbolinks:request-end', {data: {xhr:
|
167
|
+
Turbolinks.dispatch('turbolinks:request-end', {data: {xhr: xhr}});
|
107
168
|
|
108
169
|
// handles form error (replaces body/target only, does not touch head)
|
109
|
-
var isFormErrorResponse = (
|
170
|
+
var isFormErrorResponse = (xhr.status == 422);
|
110
171
|
if (isFormErrorResponse) {
|
111
|
-
TurbolinksForm.handleResponse(
|
112
|
-
return;
|
113
|
-
}
|
114
|
-
|
115
|
-
// replaces whole body and whole head when a true error occurs
|
116
|
-
var isError500 = (response.status == 500)
|
117
|
-
var isError404 = (response.status == 404)
|
118
|
-
if (isError500 || isError404) {
|
119
|
-
TurbolinksForm.handleResponse(response, true);
|
172
|
+
TurbolinksForm.handleResponse(xhr);
|
120
173
|
return;
|
121
174
|
}
|
122
175
|
});
|
@@ -126,18 +179,38 @@ $(document).on("ajax:error", function(e, response) {
|
|
126
179
|
// 2) Response has 'turbolinks-form-render' header and 'turbolinks-form-render-when-success' header
|
127
180
|
//
|
128
181
|
// This handling is useful when we dont want a redirect after a successful submit
|
129
|
-
|
182
|
+
TurbolinksForm.on(document, "ajax:success", function(e, data, status, xhr) {
|
183
|
+
// When using rails-ujs (instead of jquery-ujs) this handler receives a single event parameter
|
184
|
+
// and other parameters must be extracted from e.detail
|
185
|
+
// Ref: https://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html#rails-ujs-event-handlers
|
186
|
+
if (!status && e.detail)
|
187
|
+
var status = e.detail[1];
|
188
|
+
if (!xhr && e.detail)
|
189
|
+
var xhr = e.detail[2];
|
190
|
+
|
191
|
+
// does not intercept unrelated AJAX responses
|
192
|
+
if (!xhr || !xhr.getResponseHeader('turbolinks-form-render'))
|
193
|
+
return;
|
194
|
+
|
130
195
|
// dispatches turbolinks event
|
131
|
-
Turbolinks.dispatch('turbolinks:request-end', {data: {xhr:
|
196
|
+
Turbolinks.dispatch('turbolinks:request-end', {data: {xhr: xhr}});
|
132
197
|
|
133
|
-
var isFormSuccessResponse = (
|
198
|
+
var isFormSuccessResponse = (xhr.status == 200 && xhr.getResponseHeader('turbolinks-form-render-when-success'));
|
134
199
|
if (isFormSuccessResponse) {
|
135
|
-
TurbolinksForm.handleResponse(
|
200
|
+
TurbolinksForm.handleResponse(xhr);
|
136
201
|
}
|
137
202
|
});
|
138
203
|
|
139
204
|
// Sets up event delegation to forms with data-turbolinks-form attribute
|
140
|
-
|
205
|
+
TurbolinksForm.on(document, "ajax:beforeSend", "[data-turbolinks-form]", function(e, xhr, options) {
|
206
|
+
// When using rails-ujs (instead of jquery-ujs) this handler receives a single event parameter
|
207
|
+
// and other parameters must be extracted from e.detail
|
208
|
+
// Ref: https://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html#rails-ujs-event-handlers
|
209
|
+
if (!xhr && e.detail)
|
210
|
+
var xhr = e.detail[0];
|
211
|
+
if (!options && e.detail)
|
212
|
+
var options = e.detail[1];
|
213
|
+
|
141
214
|
// adds the turbolinks-form-submit header for forms with data-turbolinks-form attribute being submitted,
|
142
215
|
// so the controller knows it has to put the turbolinks-form-render header on the response
|
143
216
|
xhr.setRequestHeader('turbolinks-form-submit', '1');
|
data/turbolinks-form.gemspec
CHANGED
@@ -23,10 +23,9 @@ Gem::Specification.new do |spec|
|
|
23
23
|
|
24
24
|
spec.add_runtime_dependency 'rails', '>= 4.2'
|
25
25
|
spec.add_runtime_dependency 'turbolinks', '~> 5.0'
|
26
|
-
spec.add_runtime_dependency 'jquery-rails', '~> 4.3'
|
27
26
|
|
28
|
-
spec.add_development_dependency 'bundler', '~> 1.
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.17'
|
29
28
|
spec.add_development_dependency 'rake', '~> 12.0'
|
30
29
|
spec.add_development_dependency "rspec", "~> 3.0"
|
31
|
-
spec.add_development_dependency "byebug", '~>
|
30
|
+
spec.add_development_dependency "byebug", '~> 11'
|
32
31
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbolinks-form
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henrique Gubert
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -38,34 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '5.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: jquery-rails
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '4.3'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '4.3'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: bundler
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
45
|
- - "~>"
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version: '1.
|
47
|
+
version: '1.17'
|
62
48
|
type: :development
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
52
|
- - "~>"
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version: '1.
|
54
|
+
version: '1.17'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: rake
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,14 +86,14 @@ dependencies:
|
|
100
86
|
requirements:
|
101
87
|
- - "~>"
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
89
|
+
version: '11'
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
94
|
- - "~>"
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
96
|
+
version: '11'
|
111
97
|
description: Turbolinks 5 extension to render form errors after a submit
|
112
98
|
email:
|
113
99
|
- guberthenrique@hotmail.com
|
@@ -152,8 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
152
138
|
- !ruby/object:Gem::Version
|
153
139
|
version: '0'
|
154
140
|
requirements: []
|
155
|
-
|
156
|
-
rubygems_version: 2.6.11
|
141
|
+
rubygems_version: 3.0.4
|
157
142
|
signing_key:
|
158
143
|
specification_version: 4
|
159
144
|
summary: Turbolinks-form extends Turbolinks 5 to allow a controller to render any
|