client_side_validations 2.9.9 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+