pcai_client_side_validations 3.1.5
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.
- data/client_side_validations.gemspec +42 -0
- data/lib/client_side_validations.rb +13 -0
- data/lib/client_side_validations/action_view.rb +14 -0
- data/lib/client_side_validations/action_view/form_builder.rb +157 -0
- data/lib/client_side_validations/action_view/form_helper.rb +86 -0
- data/lib/client_side_validations/action_view/form_tag_helper.rb +12 -0
- data/lib/client_side_validations/active_model.rb +60 -0
- data/lib/client_side_validations/active_model/acceptance.rb +10 -0
- data/lib/client_side_validations/active_model/exclusion.rb +15 -0
- data/lib/client_side_validations/active_model/format.rb +10 -0
- data/lib/client_side_validations/active_model/inclusion.rb +15 -0
- data/lib/client_side_validations/active_model/length.rb +24 -0
- data/lib/client_side_validations/active_model/numericality.rb +31 -0
- data/lib/client_side_validations/active_model/presence.rb +10 -0
- data/lib/client_side_validations/active_record.rb +11 -0
- data/lib/client_side_validations/active_record/middleware.rb +33 -0
- data/lib/client_side_validations/active_record/uniqueness.rb +28 -0
- data/lib/client_side_validations/core_ext.rb +3 -0
- data/lib/client_side_validations/core_ext/range.rb +10 -0
- data/lib/client_side_validations/core_ext/regexp.rb +14 -0
- data/lib/client_side_validations/engine.rb +6 -0
- data/lib/client_side_validations/files.rb +8 -0
- data/lib/client_side_validations/formtastic.rb +21 -0
- data/lib/client_side_validations/middleware.rb +81 -0
- data/lib/client_side_validations/mongo_mapper.rb +9 -0
- data/lib/client_side_validations/mongo_mapper/middleware.rb +20 -0
- data/lib/client_side_validations/mongo_mapper/uniqueness.rb +28 -0
- data/lib/client_side_validations/mongoid.rb +9 -0
- data/lib/client_side_validations/mongoid/middleware.rb +20 -0
- data/lib/client_side_validations/mongoid/uniqueness.rb +28 -0
- data/lib/client_side_validations/simple_form.rb +24 -0
- data/lib/client_side_validations/version.rb +3 -0
- data/lib/generators/client_side_validations/copy_asset_generator.rb +36 -0
- data/lib/generators/client_side_validations/install_generator.rb +45 -0
- data/lib/generators/templates/client_side_validations/README.rails.3.0 +6 -0
- data/lib/generators/templates/client_side_validations/README.rails.3.1 +7 -0
- data/lib/generators/templates/client_side_validations/initializer.rb +14 -0
- data/vendor/assets/javascripts/rails.validations.js +410 -0
- metadata +226 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
module ClientSideValidations
|
2
|
+
module Generators
|
3
|
+
class CopyAssetGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path('../../../../vendor/assets/javascripts', __FILE__)
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def self.asset_pipeline_enabled?
|
9
|
+
(Rails.configuration.respond_to?(:assets) ? (Rails.configuration.assets || {}) : {})[:enabled]
|
10
|
+
end
|
11
|
+
|
12
|
+
def asset_pipeline_enabled?
|
13
|
+
self.class.asset_pipeline_enabled?
|
14
|
+
end
|
15
|
+
|
16
|
+
public
|
17
|
+
|
18
|
+
if asset_pipeline_enabled?
|
19
|
+
desc 'Creates a ClientSideValidations initializer and copies rails.validations.js to app/assets/javascripts.'
|
20
|
+
else
|
21
|
+
desc 'Creates a ClientSideValidations initializer and copies rails.validations.js to public/javascripts.'
|
22
|
+
end
|
23
|
+
|
24
|
+
def copy_javascript_asset
|
25
|
+
if asset_pipeline_enabled?
|
26
|
+
destination = 'app/assets/javascripts'
|
27
|
+
else
|
28
|
+
destination = 'public/javascripts'
|
29
|
+
end
|
30
|
+
|
31
|
+
copy_file 'rails.validations.js', "#{destination}/rails.validations.js"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ClientSideValidations
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path('../../templates/client_side_validations', __FILE__)
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def self.asset_pipeline_enabled?
|
9
|
+
(Rails.configuration.respond_to?(:assets) ? (Rails.configuration.assets || {}) : {})[:enabled]
|
10
|
+
end
|
11
|
+
|
12
|
+
def asset_pipeline_enabled?
|
13
|
+
self.class.asset_pipeline_enabled?
|
14
|
+
end
|
15
|
+
|
16
|
+
public
|
17
|
+
|
18
|
+
if asset_pipeline_enabled?
|
19
|
+
desc 'Creates a ClientSideValidations initializer.'
|
20
|
+
else
|
21
|
+
desc 'Creates a ClientSideValidations initializer and copies rails.validations.js to public/javascripts.'
|
22
|
+
end
|
23
|
+
|
24
|
+
def copy_initializer
|
25
|
+
copy_file 'initializer.rb', 'config/initializers/client_side_validations.rb'
|
26
|
+
end
|
27
|
+
|
28
|
+
def copy_javascript_asset
|
29
|
+
unless asset_pipeline_enabled?
|
30
|
+
copy_file '../../../../vendor/assets/javascripts/rails.validations.js', 'public/javascripts/rails.validations.js'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def show_readme
|
35
|
+
if Rails.version >= '3.1'
|
36
|
+
readme 'README.rails.3.1' if behavior == :invoke
|
37
|
+
else
|
38
|
+
readme 'README.rails.3.0' if behavior == :invoke
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# ClientSideValidations Initializer
|
2
|
+
|
3
|
+
require 'client_side_validations/simple_form' if defined?(::SimpleForm)
|
4
|
+
require 'client_side_validations/formtastic' if defined?(::Formtastic)
|
5
|
+
|
6
|
+
# Uncomment the following block if you want each input field to have the validation messages attached.
|
7
|
+
# ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
|
8
|
+
# unless html_tag =~ /^<label/
|
9
|
+
# %{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first}</label></div>}.html_safe
|
10
|
+
# else
|
11
|
+
# %{<div class="field_with_errors">#{html_tag}</div>}.html_safe
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
|
@@ -0,0 +1,410 @@
|
|
1
|
+
/*!
|
2
|
+
* Rails 3 Client Side Validations - v3.1.4
|
3
|
+
* https://github.com/bcardarlela/client_side_validations
|
4
|
+
*
|
5
|
+
* Copyright (c) 2011 Brian Cardarella
|
6
|
+
* Licensed under the MIT license
|
7
|
+
* http://www.opensource.org/licenses/mit-license.php
|
8
|
+
*/
|
9
|
+
|
10
|
+
(function($) {
|
11
|
+
$.fn.validate = function() {
|
12
|
+
return this.filter('form[data-validate]').each(function() {
|
13
|
+
var form = $(this);
|
14
|
+
var settings = window[form.attr('id')];
|
15
|
+
|
16
|
+
// Set up the events for the form
|
17
|
+
form
|
18
|
+
.submit( function() { return form.isValid(settings.validators); })
|
19
|
+
.bind('ajax:beforeSend', function(eventData) { if(eventData.target == this) return form.isValid(settings.validators); })
|
20
|
+
// Callbacks
|
21
|
+
.bind('form:validate:after', function(eventData) { clientSideValidations.callbacks.form.after( form, eventData); })
|
22
|
+
.bind('form:validate:before', function(eventData) { clientSideValidations.callbacks.form.before(form, eventData); })
|
23
|
+
.bind('form:validate:fail', function(eventData) { clientSideValidations.callbacks.form.fail( form, eventData); })
|
24
|
+
.bind('form:validate:pass', function(eventData) { clientSideValidations.callbacks.form.pass( form, eventData); })
|
25
|
+
|
26
|
+
// Set up the events for each validatable form element
|
27
|
+
.find('[data-validate]:input:not(:radio)')
|
28
|
+
.live('focusout', function() { $(this).isValid(settings.validators); })
|
29
|
+
.live('change', function() { $(this).data('changed', true); })
|
30
|
+
// Callbacks
|
31
|
+
.live('element:validate:after', function(eventData) { clientSideValidations.callbacks.element.after( $(this), eventData); })
|
32
|
+
.live('element:validate:before', function(eventData) { clientSideValidations.callbacks.element.before($(this), eventData); })
|
33
|
+
.live('element:validate:fail', function(eventData, message) {
|
34
|
+
var element = $(this);
|
35
|
+
clientSideValidations.callbacks.element.fail(element, message, function() {
|
36
|
+
addError(element, message);
|
37
|
+
}, eventData) })
|
38
|
+
.live('element:validate:pass', function(eventData) {
|
39
|
+
var element = $(this);
|
40
|
+
clientSideValidations.callbacks.element.pass(element, function() {
|
41
|
+
removeError(element);
|
42
|
+
}, eventData) })
|
43
|
+
// Checkboxes - Live events don't support filter
|
44
|
+
.end().find('[data-validate]:checkbox')
|
45
|
+
.live('click', function() { $(this).isValid(settings.validators); })
|
46
|
+
// Inputs for confirmations
|
47
|
+
.end().find('[id*=_confirmation]').each(function() {
|
48
|
+
var confirmationElement = $(this),
|
49
|
+
element = form.find('#' + this.id.match(/(.+)_confirmation/)[1] + '[data-validate]:input');
|
50
|
+
|
51
|
+
if (element[0]) {
|
52
|
+
$('#' + confirmationElement.attr('id'))
|
53
|
+
.live('focusout', function() {
|
54
|
+
element.data('changed', true).isValid(settings.validators);
|
55
|
+
})
|
56
|
+
.live('keyup', function() {
|
57
|
+
element.data('changed', true).isValid(settings.validators);
|
58
|
+
})
|
59
|
+
}
|
60
|
+
});
|
61
|
+
|
62
|
+
var addError = function(element, message) {
|
63
|
+
clientSideValidations.formBuilders[settings.type].add(element, settings, message);
|
64
|
+
}
|
65
|
+
|
66
|
+
var removeError = function(element) {
|
67
|
+
clientSideValidations.formBuilders[settings.type].remove(element, settings);
|
68
|
+
}
|
69
|
+
});
|
70
|
+
}
|
71
|
+
|
72
|
+
$.fn.isValid = function(validators) {
|
73
|
+
if ($(this[0]).is('form')) {
|
74
|
+
return validateForm($(this[0]), validators);
|
75
|
+
} else {
|
76
|
+
return validateElement($(this[0]), validators[this[0].name]);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
var validateForm = function(form, validators) {
|
81
|
+
var valid = true;
|
82
|
+
|
83
|
+
form.trigger('form:validate:before').find('[data-validate]:input').each(function() {
|
84
|
+
if (!$(this).isValid(validators)) { valid = false; }
|
85
|
+
});
|
86
|
+
|
87
|
+
if (valid) {
|
88
|
+
form.trigger('form:validate:pass');
|
89
|
+
} else {
|
90
|
+
form.trigger('form:validate:fail');
|
91
|
+
}
|
92
|
+
|
93
|
+
form.trigger('form:validate:after');
|
94
|
+
return valid;
|
95
|
+
}
|
96
|
+
|
97
|
+
var validateElement = function(element, validators) {
|
98
|
+
element.trigger('element:validate:before');
|
99
|
+
|
100
|
+
if (element.data('changed') !== false) {
|
101
|
+
var valid = true;
|
102
|
+
element.data('changed', false);
|
103
|
+
|
104
|
+
// Because 'length' is defined on the list of validators we cannot call jQuery.each on
|
105
|
+
// the clientSideValidations.validators.all() object
|
106
|
+
for (kind in clientSideValidations.validators.all()) {
|
107
|
+
if (validators[kind] && (message = clientSideValidations.validators.all()[kind](element, validators[kind]))) {
|
108
|
+
element.trigger('element:validate:fail', message).data('valid', false);
|
109
|
+
valid = false;
|
110
|
+
break;
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
if (valid) { element.data('valid', null); element.trigger('element:validate:pass'); }
|
115
|
+
}
|
116
|
+
|
117
|
+
element.trigger('element:validate:after');
|
118
|
+
return element.data('valid') === false ? false : true;
|
119
|
+
}
|
120
|
+
|
121
|
+
// Main hook
|
122
|
+
// If new forms are dynamically introduced into the DOM the .validate() method
|
123
|
+
// must be invoked on that form
|
124
|
+
$(function() { $('form[data-validate]').validate(); })
|
125
|
+
})(jQuery);
|
126
|
+
|
127
|
+
var clientSideValidations = {
|
128
|
+
validators: {
|
129
|
+
all: function() { return jQuery.extend({}, clientSideValidations.validators.local, clientSideValidations.validators.remote) },
|
130
|
+
local: {
|
131
|
+
presence: function(element, options) {
|
132
|
+
if (/^\s*$/.test(element.val() || "")) {
|
133
|
+
return options.message;
|
134
|
+
}
|
135
|
+
},
|
136
|
+
acceptance: function(element, options) {
|
137
|
+
switch (element.attr('type')) {
|
138
|
+
case 'checkbox':
|
139
|
+
if (!element.attr('checked')) {
|
140
|
+
return options.message;
|
141
|
+
}
|
142
|
+
break;
|
143
|
+
case 'text':
|
144
|
+
if (element.val() != (options.accept || '1')) {
|
145
|
+
return options.message;
|
146
|
+
}
|
147
|
+
break;
|
148
|
+
}
|
149
|
+
},
|
150
|
+
format: function(element, options) {
|
151
|
+
if ((message = this.presence(element, options)) && options.allow_blank == true) {
|
152
|
+
return;
|
153
|
+
} else if (message) {
|
154
|
+
return message;
|
155
|
+
} else {
|
156
|
+
if (options['with'] && !options['with'].test(element.val())) {
|
157
|
+
return options.message;
|
158
|
+
} else if (options['without'] && options['without'].test(element.val())) {
|
159
|
+
return options.message;
|
160
|
+
}
|
161
|
+
}
|
162
|
+
},
|
163
|
+
numericality: function(element, options) {
|
164
|
+
if (!/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d*)?$/.test(element.val()) && element.val() != '') {
|
165
|
+
return options.messages.numericality;
|
166
|
+
}
|
167
|
+
|
168
|
+
if (options.only_integer && !/^[+-]?\d+$/.test(element.val())) {
|
169
|
+
return options.messages.only_integer;
|
170
|
+
}
|
171
|
+
|
172
|
+
var CHECKS = { greater_than: '>', greater_than_or_equal_to: '>=',
|
173
|
+
equal_to: '==', less_than: '<', less_than_or_equal_to: '<=' }
|
174
|
+
|
175
|
+
for (var check in CHECKS) {
|
176
|
+
if (options[check] != undefined && !(new Function("return " + element.val() + CHECKS[check] + options[check])())) {
|
177
|
+
return options.messages[check];
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
if (options.odd && !(parseInt(element.val()) % 2)) {
|
182
|
+
return options.messages.odd;
|
183
|
+
}
|
184
|
+
|
185
|
+
if (options.even && (parseInt(element.val()) % 2)) {
|
186
|
+
return options.messages.even;
|
187
|
+
}
|
188
|
+
},
|
189
|
+
length: function(element, options) {
|
190
|
+
var blankOptions = {};
|
191
|
+
if (options.is) {
|
192
|
+
blankOptions.message = options.messages.is;
|
193
|
+
} else if (options.minimum) {
|
194
|
+
blankOptions.message = options.messages.minimum;
|
195
|
+
}
|
196
|
+
if ((message = this.presence(element, blankOptions)) && options.allow_blank == true) {
|
197
|
+
return;
|
198
|
+
} else if (message) {
|
199
|
+
return message;
|
200
|
+
} else {
|
201
|
+
var CHECKS = { is: '==', minimum: '>=', maximum: '<=' }
|
202
|
+
var tokenizer = options.js_tokenizer || "split('')";
|
203
|
+
var tokenized_length = new Function("element", "return (element.val()." + tokenizer + " || '').length;")(element);
|
204
|
+
|
205
|
+
for (var check in CHECKS) {
|
206
|
+
if (options[check] && !(new Function("return " + tokenized_length + CHECKS[check] + options[check])())) {
|
207
|
+
return options.messages[check];
|
208
|
+
}
|
209
|
+
}
|
210
|
+
}
|
211
|
+
},
|
212
|
+
exclusion: function(element, options) {
|
213
|
+
if ((message = this.presence(element, options)) && options.allow_blank == true) {
|
214
|
+
return;
|
215
|
+
} else if (message) {
|
216
|
+
return message;
|
217
|
+
} else {
|
218
|
+
if (options['in']) {
|
219
|
+
for (var i = 0; i < options['in'].length; i++) {
|
220
|
+
if (options['in'][i] == element.val()) {
|
221
|
+
return options.message;
|
222
|
+
}
|
223
|
+
}
|
224
|
+
} else if (options['range']) {
|
225
|
+
var lower = options['range'][0],
|
226
|
+
upper = options['range'][1];
|
227
|
+
if (element.val() >= lower && element.val() <= upper) {
|
228
|
+
return options.message;
|
229
|
+
}
|
230
|
+
}
|
231
|
+
}
|
232
|
+
},
|
233
|
+
inclusion: function(element, options) {
|
234
|
+
if ((message = this.presence(element, options)) && options.allow_blank == true) {
|
235
|
+
return;
|
236
|
+
} else if (message) {
|
237
|
+
return message;
|
238
|
+
} else {
|
239
|
+
if (options['in']) {
|
240
|
+
for (var i = 0; i < options['in'].length; i++) {
|
241
|
+
if (options['in'][i] == element.val()) {
|
242
|
+
return;
|
243
|
+
}
|
244
|
+
}
|
245
|
+
return options.message;
|
246
|
+
} else if (options['range']) {
|
247
|
+
var lower = options['range'][0],
|
248
|
+
upper = options['range'][1];
|
249
|
+
|
250
|
+
if (element.val() >= lower && element.val() <= upper) {
|
251
|
+
return;
|
252
|
+
} else {
|
253
|
+
return options.message;
|
254
|
+
}
|
255
|
+
}
|
256
|
+
}
|
257
|
+
},
|
258
|
+
confirmation: function(element, options) {
|
259
|
+
if (element.val() != jQuery('#' + element.attr('id') + '_confirmation').val()) {
|
260
|
+
return options.message;
|
261
|
+
}
|
262
|
+
}
|
263
|
+
},
|
264
|
+
remote: {
|
265
|
+
uniqueness: function(element, options) {
|
266
|
+
if ((message = clientSideValidations.validators.local.presence(element, options)) && options.allow_blank === true) {
|
267
|
+
return;
|
268
|
+
} else if (message) {
|
269
|
+
return message;
|
270
|
+
} else {
|
271
|
+
var data = {};
|
272
|
+
data['case_sensitive'] = !!options.case_sensitive;
|
273
|
+
if (options.id) {
|
274
|
+
data['id'] = options.id;
|
275
|
+
}
|
276
|
+
|
277
|
+
if (options.scope) {
|
278
|
+
data.scope = {}
|
279
|
+
for (key in options.scope) {
|
280
|
+
var scoped_element = jQuery('[name="' + element.attr('name').replace(/\[\w+]$/, '[' + key + ']' + '"]'));
|
281
|
+
if (scoped_element[0] && scoped_element.val() != options.scope[key]) {
|
282
|
+
data.scope[key] = scoped_element.val();
|
283
|
+
scoped_element.unbind('change.' + element.id).bind('change.' + element.id, function() { element.trigger('change'); element.trigger('focusout'); });
|
284
|
+
} else {
|
285
|
+
data.scope[key] = options.scope[key];
|
286
|
+
}
|
287
|
+
}
|
288
|
+
}
|
289
|
+
|
290
|
+
// Kind of a hack but this will isolate the resource name and attribute.
|
291
|
+
// e.g. user[records_attributes][0][title] => records[title]
|
292
|
+
// e.g. user[record_attributes][title] => record[title]
|
293
|
+
// Server side handles classifying the resource properly
|
294
|
+
if (/_attributes]/.test(element.attr('name'))) {
|
295
|
+
var name = element.attr('name').match(/\[\w+_attributes]/g).pop().match(/\[(\w+)_attributes]/).pop();
|
296
|
+
name += /(\[\w+])$/.exec(element.attr('name'))[1];
|
297
|
+
} else {
|
298
|
+
var name = element.attr('name');
|
299
|
+
}
|
300
|
+
|
301
|
+
// Override the name if a nested module class is passed
|
302
|
+
if (options['class']) {
|
303
|
+
name = options['class'] + '[' + name.split('[')[1]
|
304
|
+
}
|
305
|
+
data[name] = element.val();
|
306
|
+
|
307
|
+
if (jQuery.ajax({
|
308
|
+
url: '/validators/uniqueness',
|
309
|
+
data: data,
|
310
|
+
async: false
|
311
|
+
}).status == 200) {
|
312
|
+
return options.message;
|
313
|
+
}
|
314
|
+
}
|
315
|
+
}
|
316
|
+
}
|
317
|
+
},
|
318
|
+
formBuilders: {
|
319
|
+
'ActionView::Helpers::FormBuilder': {
|
320
|
+
add: function(element, settings, message) {
|
321
|
+
if (element.data('valid') !== false && jQuery('label.message[for="' + element.attr('id') + '"]')[0] == undefined) {
|
322
|
+
var inputErrorField = jQuery(settings.input_tag),
|
323
|
+
labelErrorField = jQuery(settings.label_tag),
|
324
|
+
label = jQuery('label[for="' + element.attr('id') + '"]:not(.message)');
|
325
|
+
|
326
|
+
if (element.attr('autofocus')) { element.attr('autofocus', false) };
|
327
|
+
element.before(inputErrorField);
|
328
|
+
inputErrorField.find('span#input_tag').replaceWith(element);
|
329
|
+
inputErrorField.find('label.message').attr('for', element.attr('id'));
|
330
|
+
labelErrorField.find('label.message').attr('for', element.attr('id'));
|
331
|
+
label.replaceWith(labelErrorField);
|
332
|
+
labelErrorField.find('label#label_tag').replaceWith(label);
|
333
|
+
}
|
334
|
+
jQuery('label.message[for="' + element.attr('id') + '"]').text(message);
|
335
|
+
},
|
336
|
+
remove: function(element, settings) {
|
337
|
+
var errorFieldClass = jQuery(settings.input_tag).attr('class'),
|
338
|
+
inputErrorField = element.closest('.' + errorFieldClass),
|
339
|
+
label = jQuery('label[for="' + element.attr('id') + '"]:not(.message)'),
|
340
|
+
labelErrorField = label.closest('.' + errorFieldClass);
|
341
|
+
|
342
|
+
if (inputErrorField[0]) {
|
343
|
+
inputErrorField.find('#' + element.attr('id')).detach();
|
344
|
+
inputErrorField.replaceWith(element);
|
345
|
+
label.detach();
|
346
|
+
labelErrorField.replaceWith(label);
|
347
|
+
}
|
348
|
+
}
|
349
|
+
},
|
350
|
+
'SimpleForm::FormBuilder': {
|
351
|
+
add: function(element, settings, message) {
|
352
|
+
if (element.data('valid') !== false) {
|
353
|
+
var wrapper = element.closest(settings.wrapper_tag);
|
354
|
+
wrapper.addClass(settings.wrapper_error_class);
|
355
|
+
var errorElement = $('<' + settings.error_tag + ' class="' + settings.error_class + '">' + message + '</' + settings.error_tag + '>');
|
356
|
+
wrapper.append(errorElement);
|
357
|
+
} else {
|
358
|
+
element.parent().find(settings.error_tag + '.' + settings.error_class).text(message);
|
359
|
+
}
|
360
|
+
},
|
361
|
+
remove: function(element, settings) {
|
362
|
+
var wrapper = element.closest(settings.wrapper_tag + '.' + settings.wrapper_error_class);
|
363
|
+
wrapper.removeClass(settings.wrapper_error_class);
|
364
|
+
var errorElement = wrapper.find(settings.error_tag + '.' + settings.error_class);
|
365
|
+
errorElement.remove();
|
366
|
+
}
|
367
|
+
|
368
|
+
},
|
369
|
+
'Formtastic::FormBuilder': {
|
370
|
+
add: function(element, settings, message) {
|
371
|
+
if (element.data('valid') !== false) {
|
372
|
+
var wrapper = element.closest('li');
|
373
|
+
wrapper.addClass('error');
|
374
|
+
var errorElement = $('<p class="' + settings.inline_error_class + '">' + message + '</p>');
|
375
|
+
wrapper.append(errorElement);
|
376
|
+
} else {
|
377
|
+
element.parent().find('p.' + settings.inline_error_class).text(message);
|
378
|
+
}
|
379
|
+
},
|
380
|
+
remove: function(element, settings) {
|
381
|
+
var wrapper = element.closest('li.error');
|
382
|
+
wrapper.removeClass('error');
|
383
|
+
var errorElement = wrapper.find('p.' + settings.inline_error_class);
|
384
|
+
errorElement.remove();
|
385
|
+
}
|
386
|
+
},
|
387
|
+
'NestedForm::Builder': {
|
388
|
+
add: function(element, settings, message) {
|
389
|
+
clientSideValidations.formBuilders['ActionView::Helpers::FormBuilder'].add(element, settings, message);
|
390
|
+
},
|
391
|
+
remove: function(element, settings, message) {
|
392
|
+
clientSideValidations.formBuilders['ActionView::Helpers::FormBuilder'].remove(element, settings, message);
|
393
|
+
}
|
394
|
+
}
|
395
|
+
},
|
396
|
+
callbacks: {
|
397
|
+
element: {
|
398
|
+
after: function(element, eventData) { },
|
399
|
+
before: function(element, eventData) { },
|
400
|
+
fail: function(element, message, addError, eventData) { addError() },
|
401
|
+
pass: function(element, removeError, eventData) { removeError() }
|
402
|
+
},
|
403
|
+
form: {
|
404
|
+
after: function(form, eventData) { },
|
405
|
+
before: function(form, eventData) { },
|
406
|
+
fail: function(form, eventData) { },
|
407
|
+
pass: function(form, eventData) { }
|
408
|
+
}
|
409
|
+
}
|
410
|
+
};
|