client_side_validations 8.0.2 → 9.0.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/CHANGELOG.md +4 -0
- data/README.md +5 -27
- data/lib/client_side_validations/action_view.rb +0 -2
- data/lib/client_side_validations/action_view/form_helper.rb +53 -41
- data/lib/client_side_validations/version.rb +1 -1
- data/vendor/assets/javascripts/rails.validations.js +387 -422
- metadata +1 -2
- data/lib/client_side_validations/action_view/form_tag_helper.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9517f4c6685202d257a67fed4948d6ddc6663104
|
4
|
+
data.tar.gz: 2a185c425e483fc2b2776da0715c9312bb6abf0c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 746dabde16b38f4b5941016d38ada3108ea3884b1c20ae655bf24aa3dddcc4cfd752403c77dfd09beba577180df71ff696f1809b1ac8d12c71d2c24364453f3d
|
7
|
+
data.tar.gz: 7a6527a1c051063414572982dac3c3372e301a04f94b766d56f26b396214110deeda09e7947ea1bbdc1c0a5df81f2277642abe193b17c3ef897b0203c44e4214
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -72,9 +72,7 @@ Rails `FormBuilders`. Please see the [Plugin wiki page](https://github.com/DavyJ
|
|
72
72
|
(feel free to add your own)
|
73
73
|
|
74
74
|
* [SimpleForm](https://github.com/DavyJonesLocker/client_side_validations-simple_form)
|
75
|
-
* [Formtastic](https://github.com/DavyJonesLocker/client_side_validations-formtastic)
|
76
75
|
* [Mongoid](https://github.com/DavyJonesLocker/client_side_validations-mongoid)
|
77
|
-
* [MongoMapper](https://github.com/DavyJonesLocker/client_side_validations-mongo_mapper)
|
78
76
|
|
79
77
|
## Usage ##
|
80
78
|
|
@@ -98,21 +96,6 @@ In your `FormBuilder` you only need to enable validations:
|
|
98
96
|
|
99
97
|
That should be enough to get you going.
|
100
98
|
|
101
|
-
By default the validators will be serialized and embedded in a
|
102
|
-
`<script>` tag following the `<form>` tag. If you would like to render
|
103
|
-
that `<script>` tag elsewhere you can do this by passing a name to
|
104
|
-
`:validate`
|
105
|
-
|
106
|
-
```erb
|
107
|
-
<%= form_for @user, validate: :user_validators do |f| %>
|
108
|
-
```
|
109
|
-
|
110
|
-
The `<script`> tag is added to `content_for()` with the name you passed,
|
111
|
-
so you can simply render that anywhere you like:
|
112
|
-
|
113
|
-
```erb
|
114
|
-
<%= yield(:user_validators) %>
|
115
|
-
```
|
116
99
|
|
117
100
|
## Conditional Validators ##
|
118
101
|
|
@@ -187,20 +170,15 @@ You can even turn them off per fieldset:
|
|
187
170
|
...
|
188
171
|
```
|
189
172
|
|
190
|
-
## Understanding the
|
173
|
+
## Understanding the client side validations data attribute ##
|
191
174
|
|
192
|
-
A rendered form with validations will always have a
|
193
|
-
directly after:
|
194
|
-
|
195
|
-
```html
|
196
|
-
<script>//<![CDATA[if(window.ClientSideValidations==undefined)window.ClientSideValidations={};if(window.ClientSideValidations.forms==undefined)window.ClientSideValidations.forms={};window.ClientSideValidations.forms['new_person'] = {"type":"ActionView::Helpers::FormBuilder","input_tag":"<div class=\"field_with_errors\"><span id=\"input_tag\" /><label for=\"\" class=\"message\"></label></div>","label_tag":"<div class=\"field_with_errors\"><label id=\"label_tag\" /></div>","validators":{"person[name]":{"inclusion":[{"message":"is not included in the list","in":["Happy"]}]}}};//]]></script>
|
197
|
-
```
|
175
|
+
A rendered form with validations will always have a `data-client-side-validations` attribute.
|
198
176
|
|
199
|
-
|
177
|
+
The objects it contains will have different keys depending upon the `FormBuilder` being used. However, `html_settings` and `validators` will always be present.
|
200
178
|
|
201
|
-
### `
|
179
|
+
### `html_settings` ###
|
202
180
|
|
203
|
-
This will always
|
181
|
+
This will always contain the type to the class of the `FormBuilder` that did the rendering. The type will be used by the JavaScript to determine how to `add` and `remove` the error messages. If you create a new `FormBuilder`, you will need to write your own handlers for adding and removing.
|
204
182
|
|
205
183
|
### `validators` ###
|
206
184
|
|
@@ -7,9 +7,7 @@ end
|
|
7
7
|
|
8
8
|
require 'client_side_validations/core_ext'
|
9
9
|
require 'client_side_validations/action_view/form_helper'
|
10
|
-
require 'client_side_validations/action_view/form_tag_helper'
|
11
10
|
require 'client_side_validations/action_view/form_builder'
|
12
11
|
|
13
12
|
ActionView::Base.send(:include, ClientSideValidations::ActionView::Helpers::FormHelper)
|
14
|
-
ActionView::Base.send(:include, ClientSideValidations::ActionView::Helpers::FormTagHelper)
|
15
13
|
ActionView::Helpers::FormBuilder.send(:prepend, ClientSideValidations::ActionView::Helpers::FormBuilder)
|
@@ -9,40 +9,29 @@ module ClientSideValidations
|
|
9
9
|
def form_for(record, options = {}, &block)
|
10
10
|
return super unless options[:validate]
|
11
11
|
|
12
|
-
|
12
|
+
# We are not going to use super here, because we need
|
13
|
+
# to inject the csv options in a data attribute in a clean way.
|
14
|
+
# So we basically reimplement the whole form_for method
|
15
|
+
raise ArgumentError, 'Missing block' unless block_given?
|
16
|
+
html_options = options[:html] ||= {}
|
13
17
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
else
|
18
|
-
object = record.is_a?(Array) ? record.last : record
|
19
|
-
object_name = options[:as] || model_name_from_record_or_class(object).param_key
|
20
|
-
end
|
18
|
+
# Moving the switch statement to another method to
|
19
|
+
# lower complexity
|
20
|
+
object, object_name = check_record(record, options)
|
21
21
|
|
22
22
|
@validators = {}
|
23
23
|
|
24
|
-
|
25
|
-
form = super
|
24
|
+
apply_html_options! options, html_options
|
26
25
|
|
27
|
-
build_bound_validators! options
|
28
26
|
builder = instantiate_builder(object_name, object, options)
|
29
|
-
|
27
|
+
output = capture(builder, &block)
|
28
|
+
html_options[:multipart] ||= builder.multipart?
|
30
29
|
|
31
|
-
|
32
|
-
form
|
33
|
-
else
|
34
|
-
form << script
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def assign_script_to_content_for(name, script)
|
39
|
-
return false if name == true
|
40
|
-
|
41
|
-
# rubocop:disable OutputSafety
|
42
|
-
content_for name, script.html_safe
|
43
|
-
# rubocop:enable OutputSafety
|
30
|
+
build_bound_validators! options
|
44
31
|
|
45
|
-
|
32
|
+
apply_csv_html_options! html_options, options, builder
|
33
|
+
html_options = html_options_for_form(options[:url] || {}, html_options)
|
34
|
+
form_tag_with_body(html_options, output)
|
46
35
|
end
|
47
36
|
|
48
37
|
def apply_form_for_options!(record, object, options)
|
@@ -61,6 +50,20 @@ module ClientSideValidations
|
|
61
50
|
|
62
51
|
private
|
63
52
|
|
53
|
+
def check_record(record, options)
|
54
|
+
case record
|
55
|
+
when String, Symbol
|
56
|
+
raise ClientSideValidations::ActionView::Helpers::FormHelper::Error, 'Using form_for(:name, @resource) is not supported with ClientSideValidations. Please use form_for(@resource, as: :name) instead.'
|
57
|
+
else
|
58
|
+
object = record.is_a?(Array) ? record.last : record
|
59
|
+
raise ArgumentError, 'First argument in form cannot contain nil or be empty' unless object
|
60
|
+
object_name = options[:as] || model_name_from_record_or_class(object).param_key
|
61
|
+
apply_form_for_options!(record, object, options)
|
62
|
+
end
|
63
|
+
|
64
|
+
[object, object_name]
|
65
|
+
end
|
66
|
+
|
64
67
|
def build_bound_validators!(options)
|
65
68
|
return unless @validators
|
66
69
|
|
@@ -90,26 +93,35 @@ module ClientSideValidations
|
|
90
93
|
end
|
91
94
|
end
|
92
95
|
|
93
|
-
def client_side_form_settings(options, builder)
|
94
|
-
javascript_tag "if(window.ClientSideValidations===undefined)window.ClientSideValidations={};window.ClientSideValidations.disabled_validators=#{ClientSideValidations::Config.disabled_validators.to_json};window.ClientSideValidations.number_format=#{number_format.to_json};if(window.ClientSideValidations.patterns===undefined)window.ClientSideValidations.patterns = {};window.ClientSideValidations.patterns.numericality=#{numericality_patterns};#{"if(window.ClientSideValidations.remote_validators_prefix===undefined)window.ClientSideValidations.remote_validators_prefix='#{ClientSideValidations::Config.root_path.sub(%r{/+\Z}, '')}';" if ClientSideValidations::Config.root_path.present?}if(window.ClientSideValidations.forms===undefined)window.ClientSideValidations.forms={};window.ClientSideValidations.forms['#{options[:html]['id']}'] = #{builder.client_side_form_settings(options, self).merge(validators: construct_validators).to_json};"
|
95
|
-
end
|
96
|
-
|
97
96
|
def number_format
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
97
|
+
if ClientSideValidations::Config.number_format_with_locale && defined?(I18n)
|
98
|
+
I18n.t('number.format').slice :separator, :delimiter
|
99
|
+
else
|
100
|
+
{ separator: '.', delimiter: ',' }
|
101
|
+
end
|
104
102
|
end
|
105
103
|
|
106
|
-
def
|
107
|
-
|
104
|
+
def apply_html_options!(options, html_options)
|
105
|
+
# Turn off HTML5 validations
|
106
|
+
html_options[:novalidate] = 'novalidate'
|
107
|
+
|
108
|
+
html_options[:data] = options.delete(:data) if options.key?(:data)
|
109
|
+
html_options[:remote] = options.delete(:remote) if options.key?(:remote)
|
110
|
+
html_options[:method] = options.delete(:method) if options.key?(:method)
|
111
|
+
html_options[:enforce_utf8] = options.delete(:enforce_utf8) if options.key?(:enforce_utf8)
|
112
|
+
html_options[:authenticity_token] = options.delete(:authenticity_token)
|
108
113
|
end
|
109
114
|
|
110
|
-
def
|
111
|
-
|
112
|
-
|
115
|
+
def apply_csv_html_options!(html_options, options, builder)
|
116
|
+
html_options.delete :validate
|
117
|
+
|
118
|
+
csv_options = {
|
119
|
+
html_settings: builder.client_side_form_settings(options, self),
|
120
|
+
number_format: number_format,
|
121
|
+
validators: construct_validators
|
122
|
+
}
|
123
|
+
|
124
|
+
html_options['data-client-side-validations'] = csv_options.to_json
|
113
125
|
end
|
114
126
|
end
|
115
127
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
|
2
2
|
/*!
|
3
|
-
* Client Side Validations -
|
3
|
+
* Client Side Validations - v9.0.0 (https://github.com/DavyJonesLocker/client_side_validations)
|
4
4
|
* Copyright (c) 2017 Geremia Taglialatela, Brian Cardarella
|
5
5
|
* Licensed under MIT (http://opensource.org/licenses/mit-license.php)
|
6
6
|
*/
|
7
7
|
|
8
8
|
(function() {
|
9
|
-
var $, validateElement, validateForm, validatorsFor,
|
9
|
+
var $, ClientSideValidations, initializeOnEvent, validateElement, validateForm, validatorsFor,
|
10
10
|
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
11
11
|
|
12
12
|
$ = jQuery;
|
@@ -50,6 +50,8 @@
|
|
50
50
|
}
|
51
51
|
};
|
52
52
|
|
53
|
+
initializeOnEvent = (window.Turbolinks != null) && window.Turbolinks.supported ? window.Turbolinks.EVENTS != null ? 'page:change' : 'turbolinks:load' : 'ready';
|
54
|
+
|
53
55
|
validatorsFor = function(name, validators) {
|
54
56
|
var captures, validator, validator_name;
|
55
57
|
if (captures = name.match(/\[(\w+_attributes)\].*\[(\w+)\]$/)) {
|
@@ -135,471 +137,434 @@
|
|
135
137
|
return afterValidate();
|
136
138
|
};
|
137
139
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
window.ClientSideValidations.selectors = {
|
147
|
-
inputs: ':input:not(button):not([type="submit"])[name]:visible:enabled',
|
148
|
-
validate_inputs: ':input:enabled:visible[data-validate]',
|
149
|
-
forms: 'form[data-validate]'
|
150
|
-
};
|
151
|
-
|
152
|
-
window.ClientSideValidations.reset = function(form) {
|
153
|
-
var $form, key;
|
154
|
-
$form = $(form);
|
155
|
-
ClientSideValidations.disable(form);
|
156
|
-
for (key in form.ClientSideValidations.settings.validators) {
|
157
|
-
form.ClientSideValidations.removeError($form.find("[name='" + key + "']"));
|
158
|
-
}
|
159
|
-
return ClientSideValidations.enablers.form(form);
|
160
|
-
};
|
161
|
-
|
162
|
-
window.ClientSideValidations.disable = function(target) {
|
163
|
-
var $target;
|
164
|
-
$target = $(target);
|
165
|
-
$target.off('.ClientSideValidations');
|
166
|
-
if ($target.is('form')) {
|
167
|
-
return ClientSideValidations.disable($target.find(':input'));
|
168
|
-
} else {
|
169
|
-
$target.removeData('valid');
|
170
|
-
$target.removeData('changed');
|
171
|
-
return $target.filter(':input').each(function() {
|
172
|
-
return $(this).removeAttr('data-validate');
|
173
|
-
});
|
174
|
-
}
|
175
|
-
};
|
176
|
-
|
177
|
-
window.ClientSideValidations.enablers = {
|
178
|
-
form: function(form) {
|
179
|
-
var $form, binding, event, ref;
|
180
|
-
$form = $(form);
|
181
|
-
form.ClientSideValidations = {
|
182
|
-
settings: window.ClientSideValidations.forms[$form.attr('id')],
|
183
|
-
addError: function(element, message) {
|
184
|
-
return ClientSideValidations.formBuilders[form.ClientSideValidations.settings.type].add(element, form.ClientSideValidations.settings, message);
|
140
|
+
ClientSideValidations = {
|
141
|
+
callbacks: {
|
142
|
+
element: {
|
143
|
+
after: function(element, eventData) {},
|
144
|
+
before: function(element, eventData) {},
|
145
|
+
fail: function(element, message, addError, eventData) {
|
146
|
+
return addError();
|
185
147
|
},
|
186
|
-
|
187
|
-
return
|
148
|
+
pass: function(element, removeError, eventData) {
|
149
|
+
return removeError();
|
188
150
|
}
|
189
|
-
}
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
151
|
+
},
|
152
|
+
form: {
|
153
|
+
after: function(form, eventData) {},
|
154
|
+
before: function(form, eventData) {},
|
155
|
+
fail: function(form, eventData) {},
|
156
|
+
pass: function(form, eventData) {}
|
157
|
+
}
|
158
|
+
},
|
159
|
+
enablers: {
|
160
|
+
form: function(form) {
|
161
|
+
var $form, binding, event, ref;
|
162
|
+
$form = $(form);
|
163
|
+
form.ClientSideValidations = {
|
164
|
+
settings: $form.data('clientSideValidations'),
|
165
|
+
addError: function(element, message) {
|
166
|
+
return ClientSideValidations.formBuilders[form.ClientSideValidations.settings.html_settings.type].add(element, form.ClientSideValidations.settings.html_settings, message);
|
167
|
+
},
|
168
|
+
removeError: function(element) {
|
169
|
+
return ClientSideValidations.formBuilders[form.ClientSideValidations.settings.html_settings.type].remove(element, form.ClientSideValidations.settings.html_settings);
|
195
170
|
}
|
196
|
-
}
|
197
|
-
|
198
|
-
|
199
|
-
|
171
|
+
};
|
172
|
+
ref = {
|
173
|
+
'submit.ClientSideValidations': function(eventData) {
|
174
|
+
if (!$form.isValid(form.ClientSideValidations.settings.validators)) {
|
175
|
+
eventData.preventDefault();
|
176
|
+
eventData.stopImmediatePropagation();
|
177
|
+
}
|
178
|
+
},
|
179
|
+
'ajax:beforeSend.ClientSideValidations': function(eventData) {
|
180
|
+
if (eventData.target === this) {
|
181
|
+
$form.isValid(form.ClientSideValidations.settings.validators);
|
182
|
+
}
|
183
|
+
},
|
184
|
+
'form:validate:after.ClientSideValidations': function(eventData) {
|
185
|
+
ClientSideValidations.callbacks.form.after($form, eventData);
|
186
|
+
},
|
187
|
+
'form:validate:before.ClientSideValidations': function(eventData) {
|
188
|
+
ClientSideValidations.callbacks.form.before($form, eventData);
|
189
|
+
},
|
190
|
+
'form:validate:fail.ClientSideValidations': function(eventData) {
|
191
|
+
ClientSideValidations.callbacks.form.fail($form, eventData);
|
192
|
+
},
|
193
|
+
'form:validate:pass.ClientSideValidations': function(eventData) {
|
194
|
+
ClientSideValidations.callbacks.form.pass($form, eventData);
|
200
195
|
}
|
201
|
-
}
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
196
|
+
};
|
197
|
+
for (event in ref) {
|
198
|
+
binding = ref[event];
|
199
|
+
$form.on(event, binding);
|
200
|
+
}
|
201
|
+
return $form.find(ClientSideValidations.selectors.inputs).each(function() {
|
202
|
+
return ClientSideValidations.enablers.input(this);
|
203
|
+
});
|
204
|
+
},
|
205
|
+
input: function(input) {
|
206
|
+
var $form, $input, binding, event, form, ref;
|
207
|
+
$input = $(input);
|
208
|
+
form = input.form;
|
209
|
+
$form = $(form);
|
210
|
+
ref = {
|
211
|
+
'focusout.ClientSideValidations': function() {
|
212
|
+
$(this).isValid(form.ClientSideValidations.settings.validators);
|
213
|
+
},
|
214
|
+
'change.ClientSideValidations': function() {
|
215
|
+
$(this).data('changed', true);
|
216
|
+
},
|
217
|
+
'element:validate:after.ClientSideValidations': function(eventData) {
|
218
|
+
ClientSideValidations.callbacks.element.after($(this), eventData);
|
219
|
+
},
|
220
|
+
'element:validate:before.ClientSideValidations': function(eventData) {
|
221
|
+
ClientSideValidations.callbacks.element.before($(this), eventData);
|
222
|
+
},
|
223
|
+
'element:validate:fail.ClientSideValidations': function(eventData, message) {
|
224
|
+
var element;
|
225
|
+
element = $(this);
|
226
|
+
ClientSideValidations.callbacks.element.fail(element, message, function() {
|
227
|
+
return form.ClientSideValidations.addError(element, message);
|
228
|
+
}, eventData);
|
229
|
+
},
|
230
|
+
'element:validate:pass.ClientSideValidations': function(eventData) {
|
231
|
+
var element;
|
232
|
+
element = $(this);
|
233
|
+
ClientSideValidations.callbacks.element.pass(element, function() {
|
234
|
+
return form.ClientSideValidations.removeError(element);
|
235
|
+
}, eventData);
|
236
|
+
}
|
237
|
+
};
|
238
|
+
for (event in ref) {
|
239
|
+
binding = ref[event];
|
240
|
+
$input.filter(':not(:radio):not([id$=_confirmation])').each(function() {
|
241
|
+
return $(this).attr('data-validate', true);
|
242
|
+
}).on(event, binding);
|
213
243
|
}
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
$
|
244
|
+
$input.filter(':checkbox').on('change.ClientSideValidations', function() {
|
245
|
+
$(this).isValid(form.ClientSideValidations.settings.validators);
|
246
|
+
});
|
247
|
+
return $input.filter('[id$=_confirmation]').each(function() {
|
248
|
+
var confirmationElement, element, ref1, results;
|
249
|
+
confirmationElement = $(this);
|
250
|
+
element = $form.find("#" + (this.id.match(/(.+)_confirmation/)[1]) + ":input");
|
251
|
+
if (element[0]) {
|
252
|
+
ref1 = {
|
253
|
+
'focusout.ClientSideValidations': function() {
|
254
|
+
element.data('changed', true).isValid(form.ClientSideValidations.settings.validators);
|
255
|
+
},
|
256
|
+
'keyup.ClientSideValidations': function() {
|
257
|
+
element.data('changed', true).isValid(form.ClientSideValidations.settings.validators);
|
258
|
+
}
|
259
|
+
};
|
260
|
+
results = [];
|
261
|
+
for (event in ref1) {
|
262
|
+
binding = ref1[event];
|
263
|
+
results.push($("#" + (confirmationElement.attr('id'))).on(event, binding));
|
264
|
+
}
|
265
|
+
return results;
|
266
|
+
}
|
267
|
+
});
|
218
268
|
}
|
219
|
-
return $form.find(ClientSideValidations.selectors.inputs).each(function() {
|
220
|
-
return ClientSideValidations.enablers.input(this);
|
221
|
-
});
|
222
269
|
},
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
270
|
+
formBuilders: {
|
271
|
+
'ActionView::Helpers::FormBuilder': {
|
272
|
+
add: function(element, settings, message) {
|
273
|
+
var form, inputErrorField, label, labelErrorField;
|
274
|
+
form = $(element[0].form);
|
275
|
+
if (element.data('valid') !== false && (form.find("label.message[for='" + (element.attr('id')) + "']")[0] == null)) {
|
276
|
+
inputErrorField = $(settings.input_tag);
|
277
|
+
labelErrorField = $(settings.label_tag);
|
278
|
+
label = form.find("label[for='" + (element.attr('id')) + "']:not(.message)");
|
279
|
+
if (element.attr('autofocus')) {
|
280
|
+
element.attr('autofocus', false);
|
281
|
+
}
|
282
|
+
element.before(inputErrorField);
|
283
|
+
inputErrorField.find('span#input_tag').replaceWith(element);
|
284
|
+
inputErrorField.find('label.message').attr('for', element.attr('id'));
|
285
|
+
labelErrorField.find('label.message').attr('for', element.attr('id'));
|
286
|
+
labelErrorField.insertAfter(label);
|
287
|
+
labelErrorField.find('label#label_tag').replaceWith(label);
|
288
|
+
}
|
289
|
+
return form.find("label.message[for='" + (element.attr('id')) + "']").text(message);
|
231
290
|
},
|
232
|
-
|
233
|
-
|
291
|
+
remove: function(element, settings) {
|
292
|
+
var errorFieldClass, form, inputErrorField, label, labelErrorField;
|
293
|
+
form = $(element[0].form);
|
294
|
+
errorFieldClass = $(settings.input_tag).attr('class');
|
295
|
+
inputErrorField = element.closest("." + (errorFieldClass.replace(/\ /g, ".")));
|
296
|
+
label = form.find("label[for='" + (element.attr('id')) + "']:not(.message)");
|
297
|
+
labelErrorField = label.closest("." + errorFieldClass);
|
298
|
+
if (inputErrorField[0]) {
|
299
|
+
inputErrorField.find("#" + (element.attr('id'))).detach();
|
300
|
+
inputErrorField.replaceWith(element);
|
301
|
+
label.detach();
|
302
|
+
return labelErrorField.replaceWith(label);
|
303
|
+
}
|
304
|
+
}
|
305
|
+
}
|
306
|
+
},
|
307
|
+
patterns: {
|
308
|
+
numericality: function(number_format) {
|
309
|
+
return new RegExp("^(-|\\+)?(?:\\d+|\\d{1,3}(?:\\" + number_format.delimiter + "\\d{3})+)(?:\\" + number_format.separator + "\\d*)?$");
|
310
|
+
}
|
311
|
+
},
|
312
|
+
selectors: {
|
313
|
+
inputs: ':input:not(button):not([type="submit"])[name]:visible:enabled',
|
314
|
+
validate_inputs: ':input:enabled:visible[data-validate]',
|
315
|
+
forms: 'form[data-client-side-validations]'
|
316
|
+
},
|
317
|
+
validators: {
|
318
|
+
all: function() {
|
319
|
+
return $.extend({}, local, remote);
|
320
|
+
},
|
321
|
+
local: {
|
322
|
+
absence: function(element, options) {
|
323
|
+
if (!/^\s*$/.test(element.val() || '')) {
|
324
|
+
return options.message;
|
325
|
+
}
|
234
326
|
},
|
235
|
-
|
236
|
-
|
327
|
+
presence: function(element, options) {
|
328
|
+
if (/^\s*$/.test(element.val() || '')) {
|
329
|
+
return options.message;
|
330
|
+
}
|
237
331
|
},
|
238
|
-
|
239
|
-
|
332
|
+
acceptance: function(element, options) {
|
333
|
+
var ref;
|
334
|
+
switch (element.attr('type')) {
|
335
|
+
case 'checkbox':
|
336
|
+
if (!element.prop('checked')) {
|
337
|
+
return options.message;
|
338
|
+
}
|
339
|
+
break;
|
340
|
+
case 'text':
|
341
|
+
if (element.val() !== (((ref = options.accept) != null ? ref.toString() : void 0) || '1')) {
|
342
|
+
return options.message;
|
343
|
+
}
|
344
|
+
}
|
240
345
|
},
|
241
|
-
|
242
|
-
var
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
346
|
+
format: function(element, options) {
|
347
|
+
var message;
|
348
|
+
message = this.presence(element, options);
|
349
|
+
if (message) {
|
350
|
+
if (options.allow_blank === true) {
|
351
|
+
return;
|
352
|
+
}
|
353
|
+
return message;
|
354
|
+
}
|
355
|
+
if (options["with"] && !new RegExp(options["with"].source, options["with"].options).test(element.val())) {
|
356
|
+
return options.message;
|
357
|
+
}
|
358
|
+
if (options.without && new RegExp(options.without.source, options.without.options).test(element.val())) {
|
359
|
+
return options.message;
|
360
|
+
}
|
247
361
|
},
|
248
|
-
|
249
|
-
var
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
$input.filter(':not(:radio):not([id$=_confirmation])').each(function() {
|
259
|
-
return $(this).attr('data-validate', true);
|
260
|
-
}).on(event, binding);
|
261
|
-
}
|
262
|
-
$input.filter(':checkbox').on('change.ClientSideValidations', function() {
|
263
|
-
$(this).isValid(form.ClientSideValidations.settings.validators);
|
264
|
-
});
|
265
|
-
return $input.filter('[id$=_confirmation]').each(function() {
|
266
|
-
var confirmationElement, element, ref1, results;
|
267
|
-
confirmationElement = $(this);
|
268
|
-
element = $form.find("#" + (this.id.match(/(.+)_confirmation/)[1]) + ":input");
|
269
|
-
if (element[0]) {
|
270
|
-
ref1 = {
|
271
|
-
'focusout.ClientSideValidations': function() {
|
272
|
-
element.data('changed', true).isValid(form.ClientSideValidations.settings.validators);
|
273
|
-
},
|
274
|
-
'keyup.ClientSideValidations': function() {
|
275
|
-
element.data('changed', true).isValid(form.ClientSideValidations.settings.validators);
|
362
|
+
numericality: function(element, options) {
|
363
|
+
var $form, CHECKS, check, checkValue, fn, number_format, operator, val;
|
364
|
+
$form = $(element[0].form);
|
365
|
+
val = $.trim(element.val());
|
366
|
+
number_format = $form[0].ClientSideValidations.settings.number_format;
|
367
|
+
if (!ClientSideValidations.patterns.numericality(number_format).test(val)) {
|
368
|
+
if (options.allow_blank === true && this.presence(element, {
|
369
|
+
message: options.messages.numericality
|
370
|
+
})) {
|
371
|
+
return;
|
276
372
|
}
|
277
|
-
|
278
|
-
results = [];
|
279
|
-
for (event in ref1) {
|
280
|
-
binding = ref1[event];
|
281
|
-
results.push($("#" + (confirmationElement.attr('id'))).on(event, binding));
|
373
|
+
return options.messages.numericality;
|
282
374
|
}
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
},
|
299
|
-
presence: function(element, options) {
|
300
|
-
if (/^\s*$/.test(element.val() || '')) {
|
301
|
-
return options.message;
|
302
|
-
}
|
303
|
-
},
|
304
|
-
acceptance: function(element, options) {
|
305
|
-
var ref;
|
306
|
-
switch (element.attr('type')) {
|
307
|
-
case 'checkbox':
|
308
|
-
if (!element.prop('checked')) {
|
309
|
-
return options.message;
|
375
|
+
val = val.replace(new RegExp("\\" + number_format.delimiter, 'g'), '').replace(new RegExp("\\" + number_format.separator, 'g'), '.');
|
376
|
+
if (options.only_integer && !/^[+-]?\d+$/.test(val)) {
|
377
|
+
return options.messages.only_integer;
|
378
|
+
}
|
379
|
+
CHECKS = {
|
380
|
+
greater_than: '>',
|
381
|
+
greater_than_or_equal_to: '>=',
|
382
|
+
equal_to: '==',
|
383
|
+
less_than: '<',
|
384
|
+
less_than_or_equal_to: '<='
|
385
|
+
};
|
386
|
+
for (check in CHECKS) {
|
387
|
+
operator = CHECKS[check];
|
388
|
+
if (!(options[check] != null)) {
|
389
|
+
continue;
|
310
390
|
}
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
391
|
+
checkValue = !isNaN(parseFloat(options[check])) && isFinite(options[check]) ? options[check] : $form.find("[name*=" + options[check] + "]").length === 1 ? $form.find("[name*=" + options[check] + "]").val() : void 0;
|
392
|
+
if ((checkValue == null) || checkValue === '') {
|
393
|
+
return;
|
394
|
+
}
|
395
|
+
fn = new Function("return " + val + " " + operator + " " + checkValue);
|
396
|
+
if (!fn()) {
|
397
|
+
return options.messages[check];
|
315
398
|
}
|
316
|
-
}
|
317
|
-
},
|
318
|
-
format: function(element, options) {
|
319
|
-
var message;
|
320
|
-
message = this.presence(element, options);
|
321
|
-
if (message) {
|
322
|
-
if (options.allow_blank === true) {
|
323
|
-
return;
|
324
|
-
}
|
325
|
-
return message;
|
326
|
-
}
|
327
|
-
if (options["with"] && !new RegExp(options["with"].source, options["with"].options).test(element.val())) {
|
328
|
-
return options.message;
|
329
|
-
}
|
330
|
-
if (options.without && new RegExp(options.without.source, options.without.options).test(element.val())) {
|
331
|
-
return options.message;
|
332
|
-
}
|
333
|
-
},
|
334
|
-
numericality: function(element, options) {
|
335
|
-
var CHECKS, check, checkValue, fn, form, operator, val;
|
336
|
-
val = $.trim(element.val());
|
337
|
-
if (!ClientSideValidations.patterns.numericality.test(val)) {
|
338
|
-
if (options.allow_blank === true && this.presence(element, {
|
339
|
-
message: options.messages.numericality
|
340
|
-
})) {
|
341
|
-
return;
|
342
399
|
}
|
343
|
-
|
344
|
-
|
345
|
-
val = val.replace(new RegExp("\\" + ClientSideValidations.number_format.delimiter, 'g'), '').replace(new RegExp("\\" + ClientSideValidations.number_format.separator, 'g'), '.');
|
346
|
-
if (options.only_integer && !/^[+-]?\d+$/.test(val)) {
|
347
|
-
return options.messages.only_integer;
|
348
|
-
}
|
349
|
-
CHECKS = {
|
350
|
-
greater_than: '>',
|
351
|
-
greater_than_or_equal_to: '>=',
|
352
|
-
equal_to: '==',
|
353
|
-
less_than: '<',
|
354
|
-
less_than_or_equal_to: '<='
|
355
|
-
};
|
356
|
-
form = $(element[0].form);
|
357
|
-
for (check in CHECKS) {
|
358
|
-
operator = CHECKS[check];
|
359
|
-
if (!(options[check] != null)) {
|
360
|
-
continue;
|
400
|
+
if (options.odd && !(parseInt(val, 10) % 2)) {
|
401
|
+
return options.messages.odd;
|
361
402
|
}
|
362
|
-
|
363
|
-
|
364
|
-
return;
|
403
|
+
if (options.even && (parseInt(val, 10) % 2)) {
|
404
|
+
return options.messages.even;
|
365
405
|
}
|
366
|
-
|
367
|
-
|
368
|
-
|
406
|
+
},
|
407
|
+
length: function(element, options) {
|
408
|
+
var CHECKS, blankOptions, check, fn, message, operator, tokenized_length, tokenizer;
|
409
|
+
tokenizer = options.js_tokenizer || "split('')";
|
410
|
+
tokenized_length = new Function('element', "return (element.val()." + tokenizer + " || '').length")(element);
|
411
|
+
CHECKS = {
|
412
|
+
is: '==',
|
413
|
+
minimum: '>=',
|
414
|
+
maximum: '<='
|
415
|
+
};
|
416
|
+
blankOptions = {};
|
417
|
+
blankOptions.message = options.is ? options.messages.is : options.minimum ? options.messages.minimum : void 0;
|
418
|
+
message = this.presence(element, blankOptions);
|
419
|
+
if (message) {
|
420
|
+
if (options.allow_blank === true) {
|
421
|
+
return;
|
422
|
+
}
|
423
|
+
return message;
|
369
424
|
}
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
var CHECKS, blankOptions, check, fn, message, operator, tokenized_length, tokenizer;
|
380
|
-
tokenizer = options.js_tokenizer || "split('')";
|
381
|
-
tokenized_length = new Function('element', "return (element.val()." + tokenizer + " || '').length")(element);
|
382
|
-
CHECKS = {
|
383
|
-
is: '==',
|
384
|
-
minimum: '>=',
|
385
|
-
maximum: '<='
|
386
|
-
};
|
387
|
-
blankOptions = {};
|
388
|
-
blankOptions.message = options.is ? options.messages.is : options.minimum ? options.messages.minimum : void 0;
|
389
|
-
message = this.presence(element, blankOptions);
|
390
|
-
if (message) {
|
391
|
-
if (options.allow_blank === true) {
|
392
|
-
return;
|
425
|
+
for (check in CHECKS) {
|
426
|
+
operator = CHECKS[check];
|
427
|
+
if (!options[check]) {
|
428
|
+
continue;
|
429
|
+
}
|
430
|
+
fn = new Function("return " + tokenized_length + " " + operator + " " + options[check]);
|
431
|
+
if (!fn()) {
|
432
|
+
return options.messages[check];
|
433
|
+
}
|
393
434
|
}
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
if (
|
399
|
-
|
435
|
+
},
|
436
|
+
exclusion: function(element, options) {
|
437
|
+
var lower, message, option, ref, upper;
|
438
|
+
message = this.presence(element, options);
|
439
|
+
if (message) {
|
440
|
+
if (options.allow_blank === true) {
|
441
|
+
return;
|
442
|
+
}
|
443
|
+
return message;
|
400
444
|
}
|
401
|
-
|
402
|
-
|
403
|
-
|
445
|
+
if (options["in"]) {
|
446
|
+
if (ref = element.val(), indexOf.call((function() {
|
447
|
+
var i, len, ref1, results;
|
448
|
+
ref1 = options["in"];
|
449
|
+
results = [];
|
450
|
+
for (i = 0, len = ref1.length; i < len; i++) {
|
451
|
+
option = ref1[i];
|
452
|
+
results.push(option.toString());
|
453
|
+
}
|
454
|
+
return results;
|
455
|
+
})(), ref) >= 0) {
|
456
|
+
return options.message;
|
457
|
+
}
|
404
458
|
}
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
if (options.allow_blank === true) {
|
412
|
-
return;
|
459
|
+
if (options.range) {
|
460
|
+
lower = options.range[0];
|
461
|
+
upper = options.range[1];
|
462
|
+
if (element.val() >= lower && element.val() <= upper) {
|
463
|
+
return options.message;
|
464
|
+
}
|
413
465
|
}
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
for (i = 0, len = ref1.length; i < len; i++) {
|
422
|
-
option = ref1[i];
|
423
|
-
results.push(option.toString());
|
466
|
+
},
|
467
|
+
inclusion: function(element, options) {
|
468
|
+
var lower, message, option, ref, upper;
|
469
|
+
message = this.presence(element, options);
|
470
|
+
if (message) {
|
471
|
+
if (options.allow_blank === true) {
|
472
|
+
return;
|
424
473
|
}
|
425
|
-
return
|
426
|
-
})(), ref) >= 0) {
|
427
|
-
return options.message;
|
474
|
+
return message;
|
428
475
|
}
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
476
|
+
if (options["in"]) {
|
477
|
+
if (ref = element.val(), indexOf.call((function() {
|
478
|
+
var i, len, ref1, results;
|
479
|
+
ref1 = options["in"];
|
480
|
+
results = [];
|
481
|
+
for (i = 0, len = ref1.length; i < len; i++) {
|
482
|
+
option = ref1[i];
|
483
|
+
results.push(option.toString());
|
484
|
+
}
|
485
|
+
return results;
|
486
|
+
})(), ref) >= 0) {
|
487
|
+
return;
|
488
|
+
}
|
434
489
|
return options.message;
|
435
490
|
}
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
if (message) {
|
442
|
-
if (options.allow_blank === true) {
|
443
|
-
return;
|
444
|
-
}
|
445
|
-
return message;
|
446
|
-
}
|
447
|
-
if (options["in"]) {
|
448
|
-
if (ref = element.val(), indexOf.call((function() {
|
449
|
-
var i, len, ref1, results;
|
450
|
-
ref1 = options["in"];
|
451
|
-
results = [];
|
452
|
-
for (i = 0, len = ref1.length; i < len; i++) {
|
453
|
-
option = ref1[i];
|
454
|
-
results.push(option.toString());
|
491
|
+
if (options.range) {
|
492
|
+
lower = options.range[0];
|
493
|
+
upper = options.range[1];
|
494
|
+
if (element.val() >= lower && element.val() <= upper) {
|
495
|
+
return;
|
455
496
|
}
|
456
|
-
return
|
457
|
-
})(), ref) >= 0) {
|
458
|
-
return;
|
497
|
+
return options.message;
|
459
498
|
}
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
return;
|
499
|
+
},
|
500
|
+
confirmation: function(element, options) {
|
501
|
+
var regex;
|
502
|
+
regex = new RegExp("^" + (element.val()) + "$", options.case_sensitive ? '' : 'i');
|
503
|
+
if (!regex.test($("#" + (element.attr('id')) + "_confirmation").val())) {
|
504
|
+
return options.message;
|
467
505
|
}
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
form.find(":input[name^=\"" + name_prefix + "\"][name$=\"" + name_suffix + "\"]").each(function() {
|
490
|
-
if ($(this).attr('name') !== name) {
|
491
|
-
if ($(this).val() === value) {
|
492
|
-
valid = false;
|
493
|
-
return $(this).data('notLocallyUnique', true);
|
494
|
-
} else {
|
495
|
-
if ($(this).data('notLocallyUnique')) {
|
496
|
-
return $(this).removeData('notLocallyUnique').data('changed', true);
|
506
|
+
},
|
507
|
+
uniqueness: function(element, options) {
|
508
|
+
var form, matches, name, name_prefix, name_suffix, valid, value;
|
509
|
+
name = element.attr('name');
|
510
|
+
if (/_attributes\]\[\d/.test(name)) {
|
511
|
+
matches = name.match(/^(.+_attributes\])\[\d+\](.+)$/);
|
512
|
+
name_prefix = matches[1];
|
513
|
+
name_suffix = matches[2];
|
514
|
+
value = element.val();
|
515
|
+
if (name_prefix && name_suffix) {
|
516
|
+
form = element.closest('form');
|
517
|
+
valid = true;
|
518
|
+
form.find(":input[name^=\"" + name_prefix + "\"][name$=\"" + name_suffix + "\"]").each(function() {
|
519
|
+
if ($(this).attr('name') !== name) {
|
520
|
+
if ($(this).val() === value) {
|
521
|
+
valid = false;
|
522
|
+
return $(this).data('notLocallyUnique', true);
|
523
|
+
} else {
|
524
|
+
if ($(this).data('notLocallyUnique')) {
|
525
|
+
return $(this).removeData('notLocallyUnique').data('changed', true);
|
526
|
+
}
|
497
527
|
}
|
498
528
|
}
|
529
|
+
});
|
530
|
+
if (!valid) {
|
531
|
+
return options.message;
|
499
532
|
}
|
500
|
-
});
|
501
|
-
if (!valid) {
|
502
|
-
return options.message;
|
503
533
|
}
|
504
534
|
}
|
505
535
|
}
|
506
|
-
}
|
536
|
+
},
|
537
|
+
remote: {}
|
507
538
|
},
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
} else {
|
515
|
-
return "//" + window.location.host + "/validators/" + validator;
|
516
|
-
}
|
517
|
-
};
|
518
|
-
|
519
|
-
window.ClientSideValidations.disableValidators = function() {
|
520
|
-
var func, ref, results, validator;
|
521
|
-
if (window.ClientSideValidations.disabled_validators === void 0) {
|
522
|
-
return;
|
523
|
-
}
|
524
|
-
ref = window.ClientSideValidations.validators.remote;
|
525
|
-
results = [];
|
526
|
-
for (validator in ref) {
|
527
|
-
func = ref[validator];
|
528
|
-
if (indexOf.call(window.ClientSideValidations.disabled_validators, validator) >= 0) {
|
529
|
-
results.push(delete window.ClientSideValidations.validators.remote[validator]);
|
539
|
+
disable: function(target) {
|
540
|
+
var $target;
|
541
|
+
$target = $(target);
|
542
|
+
$target.off('.ClientSideValidations');
|
543
|
+
if ($target.is('form')) {
|
544
|
+
return ClientSideValidations.disable($target.find(':input'));
|
530
545
|
} else {
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
window.ClientSideValidations.formBuilders = {
|
538
|
-
'ActionView::Helpers::FormBuilder': {
|
539
|
-
add: function(element, settings, message) {
|
540
|
-
var form, inputErrorField, label, labelErrorField;
|
541
|
-
form = $(element[0].form);
|
542
|
-
if (element.data('valid') !== false && (form.find("label.message[for='" + (element.attr('id')) + "']")[0] == null)) {
|
543
|
-
inputErrorField = $(settings.input_tag);
|
544
|
-
labelErrorField = $(settings.label_tag);
|
545
|
-
label = form.find("label[for='" + (element.attr('id')) + "']:not(.message)");
|
546
|
-
if (element.attr('autofocus')) {
|
547
|
-
element.attr('autofocus', false);
|
548
|
-
}
|
549
|
-
element.before(inputErrorField);
|
550
|
-
inputErrorField.find('span#input_tag').replaceWith(element);
|
551
|
-
inputErrorField.find('label.message').attr('for', element.attr('id'));
|
552
|
-
labelErrorField.find('label.message').attr('for', element.attr('id'));
|
553
|
-
labelErrorField.insertAfter(label);
|
554
|
-
labelErrorField.find('label#label_tag').replaceWith(label);
|
555
|
-
}
|
556
|
-
return form.find("label.message[for='" + (element.attr('id')) + "']").text(message);
|
557
|
-
},
|
558
|
-
remove: function(element, settings) {
|
559
|
-
var errorFieldClass, form, inputErrorField, label, labelErrorField;
|
560
|
-
form = $(element[0].form);
|
561
|
-
errorFieldClass = $(settings.input_tag).attr('class');
|
562
|
-
inputErrorField = element.closest("." + (errorFieldClass.replace(/\ /g, ".")));
|
563
|
-
label = form.find("label[for='" + (element.attr('id')) + "']:not(.message)");
|
564
|
-
labelErrorField = label.closest("." + errorFieldClass);
|
565
|
-
if (inputErrorField[0]) {
|
566
|
-
inputErrorField.find("#" + (element.attr('id'))).detach();
|
567
|
-
inputErrorField.replaceWith(element);
|
568
|
-
label.detach();
|
569
|
-
return labelErrorField.replaceWith(label);
|
570
|
-
}
|
571
|
-
}
|
572
|
-
}
|
573
|
-
};
|
574
|
-
|
575
|
-
window.ClientSideValidations.patterns = {
|
576
|
-
numericality: /^(-|\+)?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d*)?$/
|
577
|
-
};
|
578
|
-
|
579
|
-
window.ClientSideValidations.callbacks = {
|
580
|
-
element: {
|
581
|
-
after: function(element, eventData) {},
|
582
|
-
before: function(element, eventData) {},
|
583
|
-
fail: function(element, message, addError, eventData) {
|
584
|
-
return addError();
|
585
|
-
},
|
586
|
-
pass: function(element, removeError, eventData) {
|
587
|
-
return removeError();
|
546
|
+
$target.removeData('valid');
|
547
|
+
$target.removeData('changed');
|
548
|
+
return $target.filter(':input').each(function() {
|
549
|
+
return $(this).removeAttr('data-validate');
|
550
|
+
});
|
588
551
|
}
|
589
552
|
},
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
553
|
+
reset: function(form) {
|
554
|
+
var $form, key;
|
555
|
+
$form = $(form);
|
556
|
+
ClientSideValidations.disable(form);
|
557
|
+
for (key in form.ClientSideValidations.settings.validators) {
|
558
|
+
form.ClientSideValidations.removeError($form.find("[name='" + key + "']"));
|
559
|
+
}
|
560
|
+
return ClientSideValidations.enablers.form(form);
|
595
561
|
}
|
596
562
|
};
|
597
563
|
|
598
|
-
|
599
|
-
|
600
|
-
$(document).on(window.ClientSideValidations.event, function() {
|
601
|
-
ClientSideValidations.disableValidators();
|
564
|
+
$(document).on(initializeOnEvent, function() {
|
602
565
|
return $(ClientSideValidations.selectors.forms).validate();
|
603
566
|
});
|
604
567
|
|
568
|
+
window.ClientSideValidations = ClientSideValidations;
|
569
|
+
|
605
570
|
}).call(this);
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: client_side_validations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 9.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geremia Taglialatela
|
@@ -270,7 +270,6 @@ files:
|
|
270
270
|
- lib/client_side_validations/action_view.rb
|
271
271
|
- lib/client_side_validations/action_view/form_builder.rb
|
272
272
|
- lib/client_side_validations/action_view/form_helper.rb
|
273
|
-
- lib/client_side_validations/action_view/form_tag_helper.rb
|
274
273
|
- lib/client_side_validations/active_model.rb
|
275
274
|
- lib/client_side_validations/active_model/absence.rb
|
276
275
|
- lib/client_side_validations/active_model/acceptance.rb
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module ClientSideValidations
|
2
|
-
module ActionView
|
3
|
-
module Helpers
|
4
|
-
module FormTagHelper
|
5
|
-
private
|
6
|
-
|
7
|
-
def html_options_for_form(url_for_options, options)
|
8
|
-
options.stringify_keys!
|
9
|
-
html_options = {}
|
10
|
-
html_options['data-validate'] = options.delete('validate') if options['validate']
|
11
|
-
html_options.merge!(super(url_for_options, options))
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|