client_side_validations 2.9.9 → 3.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.
Files changed (113) hide show
  1. data/client_side_validations.gemspec +45 -0
  2. data/javascript/rails.validations.js +380 -0
  3. data/lib/client_side_validations.rb +5 -57
  4. data/lib/client_side_validations/action_view.rb +13 -0
  5. data/lib/client_side_validations/action_view/form_builder.rb +57 -0
  6. data/lib/client_side_validations/action_view/form_helper.rb +58 -0
  7. data/lib/client_side_validations/action_view/form_tag_helper.rb +12 -0
  8. data/lib/client_side_validations/active_model.rb +46 -0
  9. data/lib/client_side_validations/active_model/acceptance.rb +10 -0
  10. data/lib/client_side_validations/active_model/exclusion.rb +15 -0
  11. data/lib/client_side_validations/active_model/format.rb +10 -0
  12. data/lib/client_side_validations/active_model/inclusion.rb +15 -0
  13. data/lib/client_side_validations/active_model/length.rb +22 -0
  14. data/lib/client_side_validations/active_model/numericality.rb +26 -0
  15. data/lib/client_side_validations/active_model/presence.rb +10 -0
  16. data/lib/client_side_validations/active_record.rb +11 -0
  17. data/lib/client_side_validations/active_record/middleware.rb +25 -0
  18. data/lib/client_side_validations/active_record/uniqueness.rb +24 -0
  19. data/lib/client_side_validations/core_ext.rb +3 -0
  20. data/lib/client_side_validations/core_ext/range.rb +10 -0
  21. data/lib/client_side_validations/core_ext/regexp.rb +14 -0
  22. data/lib/client_side_validations/formtastic.rb +21 -0
  23. data/lib/client_side_validations/middleware.rb +83 -0
  24. data/lib/client_side_validations/mongoid.rb +9 -0
  25. data/lib/client_side_validations/mongoid/middleware.rb +20 -0
  26. data/lib/client_side_validations/mongoid/uniqueness.rb +24 -0
  27. data/lib/client_side_validations/simple_form.rb +24 -0
  28. data/lib/client_side_validations/version.rb +3 -0
  29. data/lib/generators/client_side_validations/install_generator.rb +22 -0
  30. data/lib/generators/templates/README +7 -0
  31. data/lib/generators/templates/client_side_validations.rb +14 -0
  32. data/test/action_view/cases/helper.rb +152 -0
  33. data/test/action_view/cases/test_helpers.rb +222 -0
  34. data/test/action_view/cases/test_legacy_helpers.rb +150 -0
  35. data/test/action_view/models.rb +3 -0
  36. data/test/action_view/models/comment.rb +35 -0
  37. data/test/action_view/models/post.rb +35 -0
  38. data/test/active_model/cases/helper.rb +4 -0
  39. data/test/active_model/cases/test_acceptance_validator.rb +16 -0
  40. data/test/active_model/cases/test_base.rb +11 -0
  41. data/test/active_model/cases/test_confirmation_validator.rb +16 -0
  42. data/test/active_model/cases/test_exclusion_validator.rb +20 -0
  43. data/test/active_model/cases/test_format_validator.rb +21 -0
  44. data/test/active_model/cases/test_inclusion_validator.rb +21 -0
  45. data/test/active_model/cases/test_length_validator.rb +61 -0
  46. data/test/active_model/cases/test_numericality_validator.rb +46 -0
  47. data/test/active_model/cases/test_presence_validator.rb +16 -0
  48. data/test/active_model/cases/test_validations.rb +132 -0
  49. data/test/active_model/models/person.rb +12 -0
  50. data/test/active_record/cases/helper.rb +12 -0
  51. data/test/active_record/cases/test_base.rb +11 -0
  52. data/test/active_record/cases/test_middleware.rb +150 -0
  53. data/test/active_record/cases/test_uniqueness_validator.rb +31 -0
  54. data/test/active_record/models/guid.rb +7 -0
  55. data/test/active_record/models/user.rb +10 -0
  56. data/test/base_helper.rb +6 -0
  57. data/test/core_ext/cases/test_core_ext.rb +45 -0
  58. data/test/formtastic/cases/helper.rb +2 -0
  59. data/test/formtastic/cases/test_form_builder.rb +11 -0
  60. data/test/formtastic/cases/test_form_helper.rb +22 -0
  61. data/test/generators/cases/test_install_generator.rb +15 -0
  62. data/test/javascript/config.ru +3 -0
  63. data/test/javascript/public/test/callbacks/elementAfter.js +53 -0
  64. data/test/javascript/public/test/callbacks/elementBefore.js +53 -0
  65. data/test/javascript/public/test/callbacks/elementFail.js +69 -0
  66. data/test/javascript/public/test/callbacks/elementPass.js +69 -0
  67. data/test/javascript/public/test/callbacks/formAfter.js +44 -0
  68. data/test/javascript/public/test/callbacks/formBefore.js +44 -0
  69. data/test/javascript/public/test/callbacks/formFail.js +50 -0
  70. data/test/javascript/public/test/callbacks/formPass.js +49 -0
  71. data/test/javascript/public/test/form_builders/validateForm.js +65 -0
  72. data/test/javascript/public/test/form_builders/validateFormtastic.js +51 -0
  73. data/test/javascript/public/test/form_builders/validateSimpleForm.js +54 -0
  74. data/test/javascript/public/test/settings.js +15 -0
  75. data/test/javascript/public/test/validateElement.js +138 -0
  76. data/test/javascript/public/test/validators/acceptance.js +42 -0
  77. data/test/javascript/public/test/validators/confirmation.js +25 -0
  78. data/test/javascript/public/test/validators/exclusion.js +41 -0
  79. data/test/javascript/public/test/validators/format.js +27 -0
  80. data/test/javascript/public/test/validators/inclusion.js +42 -0
  81. data/test/javascript/public/test/validators/length.js +70 -0
  82. data/test/javascript/public/test/validators/numericality.js +135 -0
  83. data/test/javascript/public/test/validators/presence.js +15 -0
  84. data/test/javascript/public/test/validators/uniqueness.js +88 -0
  85. data/test/javascript/public/vendor/jquery.metadata.js +122 -0
  86. data/test/javascript/public/vendor/qunit.css +196 -0
  87. data/test/javascript/public/vendor/qunit.js +1374 -0
  88. data/test/javascript/server.rb +78 -0
  89. data/test/javascript/views/index.erb +20 -0
  90. data/test/javascript/views/layout.erb +21 -0
  91. data/test/middleware/cases/helper.rb +15 -0
  92. data/test/middleware/cases/test_middleware.rb +8 -0
  93. data/test/mongoid/cases/helper.rb +16 -0
  94. data/test/mongoid/cases/test_base.rb +15 -0
  95. data/test/mongoid/cases/test_middleware.rb +68 -0
  96. data/test/mongoid/cases/test_uniqueness_validator.rb +31 -0
  97. data/test/mongoid/models/book.rb +8 -0
  98. data/test/simple_form/cases/helper.rb +2 -0
  99. data/test/simple_form/cases/test_form_builder.rb +14 -0
  100. data/test/simple_form/cases/test_form_helper.rb +22 -0
  101. metadata +230 -111
  102. data/LICENSE +0 -24
  103. data/README.markdown +0 -132
  104. data/generators/client_side_validations/client_side_validations_generator.rb +0 -17
  105. data/javascript/lib/client_side_validations.js +0 -93
  106. data/javascript/lib/jquery-validation.js +0 -1146
  107. data/lib/client_side_validations/adapters/action_view.rb +0 -153
  108. data/lib/client_side_validations/adapters/active_model.rb +0 -137
  109. data/lib/client_side_validations/adapters/orm_base.rb +0 -89
  110. data/lib/client_side_validations/orm.rb +0 -226
  111. data/lib/client_side_validations/rails.rb +0 -11
  112. data/lib/client_side_validations/template.rb +0 -3
  113. data/lib/generators/client_side_validations_generator.rb +0 -15
@@ -0,0 +1,45 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "client_side_validations/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "client_side_validations"
7
+ s.version = ClientSideValidations::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Brian Cardarella"]
10
+ s.email = ["bcardarella@gmail.com"]
11
+ s.homepage = "https://github.com/bcardarella/client_side_validations"
12
+ s.summary = %q{Client Side Validations}
13
+ s.description = %q{Client Side Validations}
14
+
15
+ s.rubyforge_project = "client_side_validations"
16
+
17
+ s.files = `git ls-files -- {lib/*,javascript/*,*.gemspec}`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency 'activesupport', '~> 3.0.0'
23
+
24
+ s.add_development_dependency 'rails', '~> 3.0.0'
25
+ s.add_development_dependency 'sqlite3'
26
+ s.add_development_dependency 'bson_ext'
27
+ s.add_development_dependency 'mongoid', '~> 2.0.0'
28
+ s.add_development_dependency 'mocha'
29
+ s.add_development_dependency 'simple_form'
30
+ s.add_development_dependency 'formtastic'
31
+
32
+ # For QUnit testing
33
+ s.add_development_dependency 'sinatra', '~> 1.0'
34
+ s.add_development_dependency 'shotgun'
35
+ s.add_development_dependency 'thin'
36
+ s.add_development_dependency 'json'
37
+
38
+ ruby_minor_version = RUBY_VERSION.split('.')[1].to_i
39
+ if ruby_minor_version == 8
40
+ s.add_development_dependency 'minitest'
41
+ s.add_development_dependency 'ruby-debug'
42
+ elsif ruby_minor_version == 9
43
+ s.add_development_dependency 'ruby-debug19'
44
+ end
45
+ end
@@ -0,0 +1,380 @@
1
+ (function($) {
2
+ $.fn.validate = function() {
3
+ return this.filter('form[data-validate]').each(function() {
4
+ var form = $(this);
5
+ var settings = window[form.attr('id')];
6
+
7
+ // Set up the events for the form
8
+ form
9
+ .submit(function() { return form.isValid(); })
10
+ .bind('ajax:beforeSend', function() { return form.isValid(); })
11
+ // Callbacks
12
+ .bind('form:validate:after', function(eventData) { clientSideValidations.callbacks.form.after( form, eventData); })
13
+ .bind('form:validate:before', function(eventData) { clientSideValidations.callbacks.form.before(form, eventData); })
14
+ .bind('form:validate:fail', function(eventData) { clientSideValidations.callbacks.form.fail( form, eventData); })
15
+ .bind('form:validate:pass', function(eventData) { clientSideValidations.callbacks.form.pass( form, eventData); })
16
+
17
+ // Set up the events for each validatable form element
18
+ .find('[data-validators]:input')
19
+ .live('focusout', function() { $(this).isValid(); })
20
+ .live('change', function() { $(this).data('changed', true); })
21
+ // Callbacks
22
+ .live('element:validate:after', function(eventData) { clientSideValidations.callbacks.element.after( $(this), eventData); })
23
+ .live('element:validate:before', function(eventData) { clientSideValidations.callbacks.element.before($(this), eventData); })
24
+ .live('element:validate:fail', function(eventData, message) {
25
+ var element = $(this);
26
+ clientSideValidations.callbacks.element.fail(element, message, function() {
27
+ addError(element, message);
28
+ }, eventData) })
29
+ .live('element:validate:pass', function(eventData) {
30
+ var element = $(this);
31
+ clientSideValidations.callbacks.element.pass(element, function() {
32
+ removeError(element);
33
+ }, eventData) })
34
+ // Checkboxes - Live events don't support filter
35
+ .end().find('[data-validators]:checkbox')
36
+ .live('click', function() { $(this).isValid(); })
37
+ // Inputs for confirmations
38
+ .end().find('[id*=_confirmation]').each(function() {
39
+ var confirmationElement = $(this),
40
+ element = form.find('#' + this.id.match(/(.+)_confirmation/)[1] + '[data-validators]:input');
41
+
42
+ $('#' + confirmationElement.attr('id'))
43
+ .live('focusout', function() {
44
+ element.data('changed', true).isValid();
45
+ })
46
+ .live('keyup', function() {
47
+ element.data('changed', true).isValid();
48
+ })
49
+ });
50
+
51
+ var addError = function(element, message) {
52
+ clientSideValidations.formBuilders[settings.type].add(element, settings, message);
53
+ }
54
+
55
+ var removeError = function(element) {
56
+ clientSideValidations.formBuilders[settings.type].remove(element, settings);
57
+ }
58
+ });
59
+ }
60
+
61
+ $.fn.isValid = function() {
62
+ if ($(this[0]).is('form')) {
63
+ return validateForm($(this[0]));
64
+ } else {
65
+ return validateElement($(this[0]));
66
+ }
67
+ }
68
+
69
+ var validateForm = function(form) {
70
+ var valid = true;
71
+
72
+ form.trigger('form:validate:before').find('[data-validators]:input').each(function() {
73
+ if (!validateElement($(this))) { valid = false; }
74
+ });
75
+
76
+ if (valid) {
77
+ form.trigger('form:validate:pass');
78
+ } else {
79
+ form.trigger('form:validate:fail');
80
+ }
81
+
82
+ form.trigger('form:validate:after');
83
+ return valid;
84
+ }
85
+
86
+ var validateElement = function(element) {
87
+ element.trigger('element:validate:before');
88
+
89
+ if (element.data('changed') !== false) {
90
+ var valid = true,
91
+ validators = new Function("return " + element.attr('data-validators'))();
92
+ element.data('changed', false);
93
+
94
+ // Because 'length' is defined on the list of validators we cannot call jQuery.each on
95
+ // the clientSideValidations.validators.all() object
96
+ for (kind in clientSideValidations.validators.all()) {
97
+ if (validators[kind] && (message = clientSideValidations.validators.all()[kind](element, validators[kind]))) {
98
+ element.trigger('element:validate:fail', message).data('valid', false);
99
+ valid = false;
100
+ break;
101
+ }
102
+ }
103
+
104
+ if (valid) { element.data('valid', null); element.trigger('element:validate:pass'); }
105
+ }
106
+
107
+ element.trigger('element:validate:after');
108
+ return element.data('valid') === false ? false : true;
109
+ }
110
+
111
+ // Main hook
112
+ // If new forms are dynamically introduced into the DOM the .validate() method
113
+ // must be invoked on that form
114
+ $(function() { $('form[data-validate]').validate(); })
115
+ })(jQuery);
116
+
117
+ var clientSideValidations = {
118
+ validators: {
119
+ all: function() { return jQuery.extend({}, clientSideValidations.validators.local, clientSideValidations.validators.remote) },
120
+ local: {
121
+ presence: function(element, options) {
122
+ if (/^\s*$/.test(element.val())) {
123
+ return options.message;
124
+ }
125
+ },
126
+ acceptance: function(element, options) {
127
+ switch (element.attr('type')) {
128
+ case 'checkbox':
129
+ if (!element.attr('checked')) {
130
+ return options.message;
131
+ }
132
+ break;
133
+ case 'text':
134
+ if (element.val() != (options.accept || '1')) {
135
+ return options.message;
136
+ }
137
+ break;
138
+ }
139
+ },
140
+ format: function(element, options) {
141
+ if ((message = this.presence(element, options)) && options.allow_blank == true) {
142
+ return;
143
+ } else if (message) {
144
+ return message;
145
+ } else {
146
+ if (options['with'] && !options['with'].test(element.val())) {
147
+ return options.message;
148
+ } else if (options['without'] && options['without'].test(element.val())) {
149
+ return options.message;
150
+ }
151
+ }
152
+ },
153
+ numericality: function(element, options) {
154
+ if (!/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d*)?$/.test(element.val())) {
155
+ return options.messages.numericality;
156
+ }
157
+
158
+ if (options.only_integer && !/^\d+$/.test(element.val())) {
159
+ return options.messages.only_integer;
160
+ }
161
+
162
+ var CHECKS = { greater_than: '>', greater_than_or_equal_to: '>=',
163
+ equal_to: '==', less_than: '<', less_than_or_equal_to: '<=' }
164
+
165
+ for (var check in CHECKS) {
166
+ if (options[check] && !(new Function("return " + element.val() + CHECKS[check] + options[check])())) {
167
+ return options.messages[check];
168
+ }
169
+ }
170
+
171
+ if (options.odd && !(parseInt(element.val()) % 2)) {
172
+ return options.messages.odd;
173
+ }
174
+
175
+ if (options.even && (parseInt(element.val()) % 2)) {
176
+ return options.messages.even;
177
+ }
178
+ },
179
+ length: function(element, options) {
180
+ var blankOptions = {};
181
+ if (options.is) {
182
+ blankOptions.message = options.messages.is;
183
+ } else if (options.minimum) {
184
+ blankOptions.message = options.messages.minimum;
185
+ }
186
+ if ((message = this.presence(element, blankOptions)) && options.allow_blank == true && !options.maximum) {
187
+ return;
188
+ } else if (message) {
189
+ return message;
190
+ } else {
191
+ var CHECKS = { is: '==', minimum: '>=', maximum: '<=' }
192
+ var tokenizer = options.js_tokenizer || "split('')";
193
+ var tokenized_length = new Function("element", "return (element.val()." + tokenizer + " || '').length;")(element);
194
+
195
+ for (var check in CHECKS) {
196
+ if (options[check] && !(new Function("return " + tokenized_length + CHECKS[check] + options[check])())) {
197
+ return options.messages[check];
198
+ }
199
+ }
200
+ }
201
+ },
202
+ exclusion: function(element, options) {
203
+ if ((message = this.presence(element, options)) && options.allow_blank == true) {
204
+ return;
205
+ } else if (message) {
206
+ return message;
207
+ } else {
208
+ if (options['in']) {
209
+ for (var i = 0; i < options['in'].length; i++) {
210
+ if (options['in'][i] == element.val()) {
211
+ return options.message;
212
+ }
213
+ }
214
+ } else if (options['range']) {
215
+ var lower = options['range'][0],
216
+ upper = options['range'][1];
217
+ if (element.val() >= lower && element.val() <= upper) {
218
+ return options.message;
219
+ }
220
+ }
221
+ }
222
+ },
223
+ inclusion: function(element, options) {
224
+ if ((message = this.presence(element, options)) && options.allow_blank == true) {
225
+ return;
226
+ } else if (message) {
227
+ return message;
228
+ } else {
229
+ if (options['in']) {
230
+ for (var i = 0; i < options['in'].length; i++) {
231
+ if (options['in'][i] == element.val()) {
232
+ return;
233
+ }
234
+ }
235
+ return options.message;
236
+ } else if (options['range']) {
237
+ var lower = options['range'][0],
238
+ upper = options['range'][1];
239
+
240
+ if (element.val() >= lower && element.val() <= upper) {
241
+ return;
242
+ } else {
243
+ return options.message;
244
+ }
245
+ }
246
+ }
247
+ },
248
+ confirmation: function(element, options) {
249
+ if (element.val() != jQuery('#' + element.attr('id') + '_confirmation').val()) {
250
+ return options.message;
251
+ }
252
+ }
253
+ },
254
+ remote: {
255
+ uniqueness: function(element, options) {
256
+ var data = {};
257
+ data['case_sensitive'] = !!options.case_sensitive;
258
+ if (options.id) {
259
+ data['id'] = options.id;
260
+ }
261
+
262
+ if (options.scope) {
263
+ data.scope = {}
264
+ for (key in options.scope) {
265
+ var scoped_element = jQuery('[name="' + element.attr('name').replace(/\[\w+]$/, '[' + key + ']' + '"]'));
266
+ if (scoped_element[0] && scoped_element.val() != options.scope[key]) {
267
+ data.scope[key] = scoped_element.val();
268
+ scoped_element.unbind('change.' + element.id).bind('change.' + element.id, function() { element.trigger('change'); element.trigger('focusout'); });
269
+ } else {
270
+ data.scope[key] = options.scope[key];
271
+ }
272
+ }
273
+ }
274
+
275
+ // Kind of a hack but this will isolate the resource name and attribute.
276
+ // e.g. user[records_attributes][0][title] => records[title]
277
+ // e.g. user[record_attributes][title] => record[title]
278
+ // Server side handles classifying the resource properly
279
+ if (/_attributes]/.test(element.attr('name'))) {
280
+ var name = element.attr('name').match(/\[\w+_attributes]/g).pop().match(/\[(\w+)_attributes]/).pop();
281
+ name += /(\[\w+])$/.exec(element.attr('name'))[1];
282
+ } else {
283
+ var name = element.attr('name');
284
+ }
285
+ data[name] = element.val();
286
+
287
+ if (jQuery.ajax({
288
+ url: '/validators/uniqueness.json',
289
+ data: data,
290
+ async: false
291
+ }).status == 200) {
292
+ return options.message;
293
+ }
294
+ }
295
+ }
296
+ },
297
+ formBuilders: {
298
+ 'ActionView::Helpers::FormBuilder': {
299
+ add: function(element, settings, message) {
300
+ if (element.data('valid') !== false) {
301
+ var inputErrorField = jQuery(settings.input_tag),
302
+ labelErrorField = jQuery(settings.label_tag),
303
+ label = jQuery('label[for="' + element.attr('id') + '"]:not(.message)');
304
+
305
+ element.before(inputErrorField);
306
+ inputErrorField.find('span#input_tag').replaceWith(element);
307
+ inputErrorField.find('label.message').attr('for', element.attr('id'));
308
+ label.replaceWith(labelErrorField);
309
+ labelErrorField.find('label#label_tag').replaceWith(label);
310
+ }
311
+ jQuery('label.message[for="' + element.attr('id') + '"]').text(message);
312
+ },
313
+ remove: function(element, settings) {
314
+ var errorFieldClass = jQuery(settings.input_tag).attr('class'),
315
+ inputErrorField = element.closest('.' + errorFieldClass),
316
+ label = jQuery('label[for="' + element.attr('id') + '"]:not(.message)'),
317
+ labelErrorField = label.closest('.' + errorFieldClass);
318
+
319
+ if (inputErrorField[0]) {
320
+ inputErrorField.find('#' + element.attr('id')).detach();
321
+ inputErrorField.replaceWith(element);
322
+ label.detach();
323
+ labelErrorField.replaceWith(label);
324
+ }
325
+ }
326
+ },
327
+ 'SimpleForm::FormBuilder': {
328
+ add: function(element, settings, message) {
329
+ if (element.data('valid') !== false) {
330
+ var wrapper = element.closest(settings.wrapper_tag);
331
+ wrapper.addClass(settings.wrapper_error_class);
332
+ var errorElement = $('<' + settings.error_tag + ' class="' + settings.error_class + '">' + message + '</' + settings.error_tag + '>');
333
+ wrapper.append(errorElement);
334
+ } else {
335
+ element.parent().find(settings.error_tag + '.' + settings.error_class).text(message);
336
+ }
337
+ },
338
+ remove: function(element, settings) {
339
+ var wrapper = element.closest(settings.wrapper_tag + '.' + settings.wrapper_error_class);
340
+ wrapper.removeClass(settings.wrapper_error_class);
341
+ var errorElement = wrapper.find(settings.error_tag + '.' + settings.error_class);
342
+ errorElement.remove();
343
+ }
344
+
345
+ },
346
+ 'Formtastic::SemanticFormBuilder': {
347
+ add: function(element, settings, message) {
348
+ if (element.data('valid') !== false) {
349
+ var wrapper = element.closest('li');
350
+ wrapper.addClass('error');
351
+ var errorElement = $('<p class="' + settings.inline_error_class + '">' + message + '</p>');
352
+ wrapper.append(errorElement);
353
+ } else {
354
+ element.parent().find('p.' + settings.inline_error_class).text(message);
355
+ }
356
+ },
357
+ remove: function(element, settings) {
358
+ var wrapper = element.closest('li.error');
359
+ wrapper.removeClass('error');
360
+ var errorElement = wrapper.find('p.' + settings.inline_error_class);
361
+ errorElement.remove();
362
+ }
363
+
364
+ }
365
+ },
366
+ callbacks: {
367
+ element: {
368
+ after: function(element, eventData) { },
369
+ before: function(element, eventData) { },
370
+ fail: function(element, message, addError, eventData) { addError() },
371
+ pass: function(element, removeError, eventData) { removeError() }
372
+ },
373
+ form: {
374
+ after: function(form, eventData) { },
375
+ before: function(form, eventData) { },
376
+ fail: function(form, eventData) { },
377
+ pass: function(form, eventData) { }
378
+ }
379
+ }
380
+ }
@@ -1,60 +1,8 @@
1
- require 'rubygems'
2
- require 'json'
3
- require 'cgi'
4
-
5
1
  module ClientSideValidations
6
- def self.default_options=(options)
7
- @default_options = options
8
- end
9
-
10
- def self.default_options
11
- @default_options
12
- end
13
-
14
- class Uniqueness
15
- def initialize(app)
16
- @app = app
17
- end
18
-
19
- def call(env)
20
- # By default CGI::parse will instantize a hash that defaults nil elements to [].
21
- # We need to override this
22
- case env['PATH_INFO']
23
- when %r{^/validations/uniqueness.json}
24
- params = {}.merge!(CGI::parse(env['QUERY_STRING']))
25
- field = params.keys.first
26
- resource, attribute = field.split(/[^\w]/)
27
- value = params[field][0]
28
- # Because params returns an array for each field value we want to always grab
29
- # the first element of the array for id, even if it is nil
30
- id = [params["#{resource}[id]"]].flatten.first
31
- body = is_unique?(resource, attribute, value, id).to_s
32
- [200, {'Content-Type' => 'application/json', 'Content-Length' => "#{body.length}"}, [body]]
33
- else
34
- @app.call(env)
35
- end
36
- end
37
-
38
- private
39
-
40
- def is_unique?(resource, attribute, value, id = nil)
41
- klass = constantize_resource(resource)
42
- instance = nil
43
- instance = klass.send("find_by_#{attribute}", value)
44
-
45
- if instance
46
- return instance.id.to_i == id.to_i
47
- else
48
- return true
49
- end
50
- end
51
-
52
- def constantize_resource(resource)
53
- eval(resource.split('_').map{ |word| word.capitalize}.join)
54
- end
55
- end
56
2
  end
57
3
 
58
- require 'client_side_validations/orm'
59
- require 'client_side_validations/template'
60
- require 'client_side_validations/rails' if defined?(Rails)
4
+ require 'client_side_validations/active_record' if defined?(::ActiveRecord)
5
+ require 'client_side_validations/mongoid' if defined?(::Mongoid)
6
+ require 'client_side_validations/action_view'
7
+ require 'client_side_validations/middleware' if defined?(::Rails)
8
+