client_side_validations 3.2.0.beta.3 → 3.2.0.beta.4

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.
@@ -24,9 +24,9 @@ module ClientSideValidations::ActionView::Helpers
24
24
  alias_method_chain :grouped_collection_select, :client_side_validations
25
25
  alias_method_chain :time_zone_select, :client_side_validations
26
26
 
27
- def self.client_side_form_settings(options, form_helper)
27
+ def client_side_form_settings(options, form_helper)
28
28
  {
29
- :type => self.to_s,
29
+ :type => self.class.to_s,
30
30
  :input_tag => form_helper.class.field_error_proc.call(%{<span id="input_tag" />}, Struct.new(:error_message, :tag_id).new([], "")),
31
31
  :label_tag => form_helper.class.field_error_proc.call(%{<label id="label_tag" />}, Struct.new(:error_message, :tag_id).new([], ""))
32
32
  }
@@ -81,7 +81,8 @@ module ClientSideValidations::ActionView::Helpers
81
81
  if @options[:validate] && options[:validate] != false && validators = filter_validators(method, options[:validate])
82
82
  options.merge!("data-validate" => true)
83
83
  name = options[:name] || "#{@object_name}[#{method}]"
84
-
84
+ child_index = @options[:child_index] ? "(\\d+|#{Regexp.escape(@options[:child_index])})" : "\\d+"
85
+ name = name.gsub(/_attributes\]\[#{child_index}\]/, '_attributes][]')
85
86
  @options[:validators].merge!("#{name}#{options[:multiple] ? "[]" : nil}" => validators)
86
87
  end
87
88
  end
@@ -97,8 +98,24 @@ module ClientSideValidations::ActionView::Helpers
97
98
  unfiltered_validators.delete(validator.first)
98
99
  end
99
100
  else
100
- if (conditional = (validator.last[:if] || validator.last[:unless])) && conditional.is_a?(Symbol) && !conditional_method_is_change_method?(conditional, method)
101
- unfiltered_validators.delete(validator.first)
101
+ if (conditional = (validator.last[:if] || validator.last[:unless]))
102
+ result = case conditional
103
+ when Symbol
104
+ if @object.respond_to?(conditional)
105
+ @object.send(conditional)
106
+ else
107
+ raise(ArgumentError, "unknown method called '#{conditional}'")
108
+ end
109
+ when String
110
+ eval(conditional)
111
+ when Proc
112
+ conditional.call(@object)
113
+ end
114
+
115
+ # :if was specified and result is false OR :unless was specified and result was true
116
+ if (validator.last[:if] && !result) || (validator.last[:unless] && result)
117
+ unfiltered_validators.delete(validator.first)
118
+ end
102
119
  end
103
120
  end
104
121
  unfiltered_validators[validator.first].delete(:if) if unfiltered_validators[validator.first]
@@ -23,8 +23,10 @@ module ClientSideValidations::ActionView::Helpers
23
23
  @validators = {}
24
24
 
25
25
  # Order matters here. Rails mutates the options object
26
- script = client_side_form_settings(object, options)
26
+ html_id = options[:html][:id] if options[:html]
27
27
  form = super(record_or_name_or_array, *(args << options), &proc)
28
+ options[:id] = html_id if html_id
29
+ script = client_side_form_settings(object, options)
28
30
 
29
31
  # Because of the load order requirement above this sub is necessary
30
32
  # Would be nice to not do this
@@ -70,10 +72,10 @@ module ClientSideValidations::ActionView::Helpers
70
72
 
71
73
  def client_side_form_settings(object, options)
72
74
  if options[:validate]
73
- builder = options[:builder] || ActionView::Base.default_form_builder
75
+ builder = options[:parent_builder]
74
76
 
75
- if options[:html] && options[:html][:id]
76
- var_name = options[:html][:id]
77
+ if options[:id]
78
+ var_name = options[:id]
77
79
  else
78
80
  if Rails.version >= '3.2.0'
79
81
  var_name = if object.respond_to?(:persisted?) && object.persisted?
@@ -90,14 +92,11 @@ module ClientSideValidations::ActionView::Helpers
90
92
  options[:as] ? "#{options[:as]}_new" : dom_id(object)
91
93
  end
92
94
  end
93
-
94
-
95
95
  end
96
96
 
97
97
  content_tag(:script) do
98
- "window.ClientSideValidations.forms['#{var_name}'] = #{builder.client_side_form_settings(options, self).merge(:validators => 'validator_hash').to_json};".html_safe
98
+ "//<![CDATA[\nwindow.ClientSideValidations.forms['#{var_name}'] = #{builder.client_side_form_settings(options, self).merge(:validators => 'validator_hash').to_json};\n//]]>".html_safe
99
99
  end
100
-
101
100
  end
102
101
  end
103
102
 
@@ -8,6 +8,10 @@ module ClientSideValidations::ActiveModel
8
8
  { :message => model.errors.generate_message(attribute, message_type, options) }.merge(options.except(*::ActiveModel::Errors::CALLBACKS_OPTIONS - [:allow_blank, :if, :unless]))
9
9
  end
10
10
 
11
+ def copy_conditional_attributes(to, from)
12
+ [:if, :unless].each { |key| to[key] = from[key] if from[key].present? }
13
+ end
14
+
11
15
  private
12
16
 
13
17
  def message_type
@@ -16,6 +16,8 @@ module ClientSideValidations::ActiveModel
16
16
  end
17
17
  end
18
18
 
19
+ copy_conditional_attributes(hash, options)
20
+
19
21
  hash
20
22
  end
21
23
 
@@ -23,6 +23,8 @@ module ClientSideValidations::ActiveModel
23
23
  end
24
24
  end
25
25
 
26
+ copy_conditional_attributes(hash, options)
27
+
26
28
  hash
27
29
  end
28
30
 
@@ -30,7 +30,11 @@ module ClientSideValidations::ActiveRecord
30
30
 
31
31
  (params[:scope] || {}).each do |attribute, value|
32
32
  value = type_cast_value(klass, attribute, value)
33
- relation = relation.and(t[attribute].eq(value))
33
+ if relation.is_a?(Arel::Nodes::SqlLiteral)
34
+ relation = Arel::Nodes::SqlLiteral.new("#{relation} AND #{t[attribute].eq(value).to_sql}")
35
+ else
36
+ relation = relation.and(t[attribute].eq(value))
37
+ end
34
38
  end
35
39
 
36
40
  !klass.where(relation).exists?
@@ -1,3 +1,3 @@
1
1
  module ClientSideValidations
2
- VERSION = '3.2.0.beta.3'
2
+ VERSION = '3.2.0.beta.4'
3
3
  end
@@ -1,12 +1,12 @@
1
1
  (function() {
2
- var $, validateElement, validateForm,
3
- __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
2
+ var $, validateElement, validateForm, validatorsFor,
3
+ __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; };
4
4
 
5
5
  $ = jQuery;
6
6
 
7
7
  $.fn.validate = function() {
8
8
  return this.filter('form[data-validate]').each(function() {
9
- var addError, binding, event, form, removeError, settings, _ref, _ref2;
9
+ var addError, binding, event, form, removeError, settings, _ref, _ref1;
10
10
  form = $(this);
11
11
  settings = window.ClientSideValidations.forms[form.attr('id')];
12
12
  addError = function(element, message) {
@@ -20,7 +20,9 @@
20
20
  });
21
21
  _ref = {
22
22
  'ajax:beforeSend': function(eventData) {
23
- if (eventData.target === this) return form.isValid(settings.validators);
23
+ if (eventData.target === this) {
24
+ return form.isValid(settings.validators);
25
+ }
24
26
  },
25
27
  'form:validate:after': function(eventData) {
26
28
  return ClientSideValidations.callbacks.form.after(form, eventData);
@@ -39,7 +41,7 @@
39
41
  binding = _ref[event];
40
42
  form.bind(event, binding);
41
43
  }
42
- _ref2 = {
44
+ _ref1 = {
43
45
  'focusout': function() {
44
46
  return $(this).isValid(settings.validators);
45
47
  },
@@ -67,19 +69,20 @@
67
69
  }, eventData);
68
70
  }
69
71
  };
70
- for (event in _ref2) {
71
- binding = _ref2[event];
72
+ for (event in _ref1) {
73
+ binding = _ref1[event];
72
74
  form.find('[data-validate="true"]:input:enabled:not(:radio)').live(event, binding);
73
75
  }
74
76
  form.find('[data-validate="true"]:checkbox').live('click', function() {
75
- return $(this).isValid(settings.validators);
77
+ $(this).isValid(settings.validators);
78
+ return true;
76
79
  });
77
80
  return form.find('[id*=_confirmation]').each(function() {
78
- var binding, confirmationElement, element, event, _ref3, _results;
81
+ var confirmationElement, element, _ref2, _results;
79
82
  confirmationElement = $(this);
80
83
  element = form.find("#" + (this.id.match(/(.+)_confirmation/)[1]) + "[data-validate='true']:input");
81
84
  if (element[0]) {
82
- _ref3 = {
85
+ _ref2 = {
83
86
  'focusout': function() {
84
87
  return element.data('changed', true).isValid(settings.validators);
85
88
  },
@@ -88,8 +91,8 @@
88
91
  }
89
92
  };
90
93
  _results = [];
91
- for (event in _ref3) {
92
- binding = _ref3[event];
94
+ for (event in _ref2) {
95
+ binding = _ref2[event];
93
96
  _results.push($("#" + (confirmationElement.attr('id'))).live(event, binding));
94
97
  }
95
98
  return _results;
@@ -104,16 +107,23 @@
104
107
  if (obj.is('form')) {
105
108
  return validateForm(obj, validators);
106
109
  } else {
107
- return validateElement(obj, validators[this[0].name]);
110
+ return validateElement(obj, validatorsFor(this[0].name, validators));
108
111
  }
109
112
  };
110
113
 
114
+ validatorsFor = function(name, validators) {
115
+ name = name.replace(/_attributes\]\[\d+\]/g, "_attributes][]");
116
+ return validators[name];
117
+ };
118
+
111
119
  validateForm = function(form, validators) {
112
120
  var valid;
113
121
  form.trigger('form:validate:before');
114
122
  valid = true;
115
123
  form.find('[data-validate="true"]:input:enabled').each(function() {
116
- if ($(this).isValid(validators)) return valid = false;
124
+ if ($(this).isValid(validators)) {
125
+ return valid = false;
126
+ }
117
127
  });
118
128
  if (valid) {
119
129
  form.trigger('form:validate:pass');
@@ -173,13 +183,17 @@
173
183
  },
174
184
  local: {
175
185
  presence: function(element, options) {
176
- if (/^\s*$/.test(element.val() || '')) return options.message;
186
+ if (/^\s*$/.test(element.val() || '')) {
187
+ return options.message;
188
+ }
177
189
  },
178
190
  acceptance: function(element, options) {
179
191
  var _ref;
180
192
  switch (element.attr('type')) {
181
193
  case 'checkbox':
182
- if (!element.attr('checked')) return options.message;
194
+ if (!element.attr('checked')) {
195
+ return options.message;
196
+ }
183
197
  break;
184
198
  case 'text':
185
199
  if (element.val() !== (((_ref = options.accept) != null ? _ref.toString() : void 0) || '1')) {
@@ -191,7 +205,9 @@
191
205
  var message;
192
206
  message = this.presence(element, options);
193
207
  if (message) {
194
- if (options.allow_blank === true) return;
208
+ if (options.allow_blank === true) {
209
+ return;
210
+ }
195
211
  return message;
196
212
  }
197
213
  if (options["with"] && !options["with"].test(element.val())) {
@@ -203,7 +219,7 @@
203
219
  },
204
220
  numericality: function(element, options) {
205
221
  var CHECKS, check, fn, operator;
206
- if (!/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d*)?$/.test(element.val())) {
222
+ if (!ClientSideValidations.patterns.numericality.test(element.val())) {
207
223
  return options.messages.numericality;
208
224
  }
209
225
  if (options.only_integer && !/^[+-]?\d+$/.test(element.val())) {
@@ -218,9 +234,13 @@
218
234
  };
219
235
  for (check in CHECKS) {
220
236
  operator = CHECKS[check];
221
- if (!(options[check] != null)) continue;
237
+ if (!(options[check] != null)) {
238
+ continue;
239
+ }
222
240
  fn = new Function("return " + (element.val()) + " " + operator + " " + options[check]);
223
- if (!fn()) return options.messages[check];
241
+ if (!fn()) {
242
+ return options.messages[check];
243
+ }
224
244
  }
225
245
  if (options.odd && !(parseInt(element.val(), 10) % 2)) {
226
246
  return options.messages.odd;
@@ -242,30 +262,38 @@
242
262
  blankOptions.message = options.is ? options.messages.is : options.minimum ? options.messages.minimum : void 0;
243
263
  message = this.presence(element, blankOptions);
244
264
  if (message) {
245
- if (options.allow_blank === true) return;
265
+ if (options.allow_blank === true) {
266
+ return;
267
+ }
246
268
  return message;
247
269
  }
248
270
  for (check in CHECKS) {
249
271
  operator = CHECKS[check];
250
- if (!options[check]) continue;
272
+ if (!options[check]) {
273
+ continue;
274
+ }
251
275
  fn = new Function("return " + tokenized_length + " " + operator + " " + options[check]);
252
- if (!fn()) return options.messages[check];
276
+ if (!fn()) {
277
+ return options.messages[check];
278
+ }
253
279
  }
254
280
  },
255
281
  exclusion: function(element, options) {
256
282
  var lower, message, o, upper, _ref;
257
283
  message = this.presence(element, options);
258
284
  if (message) {
259
- if (options.allow_blank === true) return;
285
+ if (options.allow_blank === true) {
286
+ return;
287
+ }
260
288
  return message;
261
289
  }
262
290
  if (options["in"]) {
263
291
  if (_ref = element.val(), __indexOf.call((function() {
264
- var _i, _len, _ref2, _results;
265
- _ref2 = options["in"];
292
+ var _i, _len, _ref1, _results;
293
+ _ref1 = options["in"];
266
294
  _results = [];
267
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
268
- o = _ref2[_i];
295
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
296
+ o = _ref1[_i];
269
297
  _results.push(o.toString());
270
298
  }
271
299
  return _results;
@@ -285,16 +313,18 @@
285
313
  var lower, message, o, upper, _ref;
286
314
  message = this.presence(element, options);
287
315
  if (message) {
288
- if (options.allow_blank === true) return;
316
+ if (options.allow_blank === true) {
317
+ return;
318
+ }
289
319
  return message;
290
320
  }
291
321
  if (options["in"]) {
292
322
  if (_ref = element.val(), __indexOf.call((function() {
293
- var _i, _len, _ref2, _results;
294
- _ref2 = options["in"];
323
+ var _i, _len, _ref1, _results;
324
+ _ref1 = options["in"];
295
325
  _results = [];
296
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
297
- o = _ref2[_i];
326
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
327
+ o = _ref1[_i];
298
328
  _results.push(o.toString());
299
329
  }
300
330
  return _results;
@@ -306,7 +336,9 @@
306
336
  if (options.range) {
307
337
  lower = options.range[0];
308
338
  upper = options.range[1];
309
- if (element.val() >= lower && element.val() <= upper) return;
339
+ if (element.val() >= lower && element.val() <= upper) {
340
+ return;
341
+ }
310
342
  return options.message;
311
343
  }
312
344
  },
@@ -321,12 +353,16 @@
321
353
  var data, key, message, name, scope_value, scoped_element, scoped_name, _ref;
322
354
  message = ClientSideValidations.validators.local.presence(element, options);
323
355
  if (message) {
324
- if (options.allow_blank === true) return;
356
+ if (options.allow_blank === true) {
357
+ return;
358
+ }
325
359
  return message;
326
360
  }
327
361
  data = {};
328
362
  data.case_sensitive = !!options.case_sensitive;
329
- if (options.id) data.id = options.id;
363
+ if (options.id) {
364
+ data.id = options.id;
365
+ }
330
366
  if (options.scope) {
331
367
  data.scope = {};
332
368
  _ref = options.scope;
@@ -351,7 +387,9 @@
351
387
  } else {
352
388
  name = element.attr('name');
353
389
  }
354
- if (options['class']) name = options['class'] + '[' + name.split('[')[1];
390
+ if (options['class']) {
391
+ name = options['class'] + '[' + name.split('[')[1];
392
+ }
355
393
  data[name] = element.val();
356
394
  if (jQuery.ajax({
357
395
  url: '/validators/uniqueness',
@@ -371,7 +409,9 @@
371
409
  inputErrorField = jQuery(settings.input_tag);
372
410
  labelErrorField = jQuery(settings.label_tag);
373
411
  label = jQuery("label[for='" + (element.attr('id')) + "']:not(.message)");
374
- if (element.attr('autofocus')) element.attr('autofocus', false);
412
+ if (element.attr('autofocus')) {
413
+ element.attr('autofocus', false);
414
+ }
375
415
  element.before(inputErrorField);
376
416
  inputErrorField.find('span#input_tag').replaceWith(element);
377
417
  inputErrorField.find('label.message').attr('for', element.attr('id'));
@@ -384,7 +424,7 @@
384
424
  remove: function(element, settings) {
385
425
  var errorFieldClass, inputErrorField, label, labelErrorField;
386
426
  errorFieldClass = jQuery(settings.input_tag).attr('class');
387
- inputErrorField = element.closest("." + errorFieldClass);
427
+ inputErrorField = element.closest("." + (errorFieldClass.replace(" ", ".")));
388
428
  label = jQuery("label[for='" + (element.attr('id')) + "']:not(.message)");
389
429
  labelErrorField = label.closest("." + errorFieldClass);
390
430
  if (inputErrorField[0]) {
@@ -396,6 +436,9 @@
396
436
  }
397
437
  }
398
438
  },
439
+ patterns: {
440
+ numericality: /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d*)?$/
441
+ },
399
442
  callbacks: {
400
443
  element: {
401
444
  after: function(element, eventData) {},
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: 3.2.0.beta.3
4
+ version: 3.2.0.beta.4
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-04 00:00:00.000000000Z
12
+ date: 2012-07-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &70115631263420 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: 3.2.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70115631263420
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.0
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: sqlite3
27
- requirement: &70115631263000 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '0'
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *70115631263000
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: mocha
38
- requirement: &70115631262540 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: '0'
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *70115631262540
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: sinatra
49
- requirement: &70115631262040 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ~>
@@ -54,10 +69,15 @@ dependencies:
54
69
  version: '1.0'
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *70115631262040
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '1.0'
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: shotgun
60
- requirement: &70115631261620 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ! '>='
@@ -65,10 +85,15 @@ dependencies:
65
85
  version: '0'
66
86
  type: :development
67
87
  prerelease: false
68
- version_requirements: *70115631261620
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
69
94
  - !ruby/object:Gem::Dependency
70
95
  name: thin
71
- requirement: &70115651537880 !ruby/object:Gem::Requirement
96
+ requirement: !ruby/object:Gem::Requirement
72
97
  none: false
73
98
  requirements:
74
99
  - - ! '>='
@@ -76,10 +101,15 @@ dependencies:
76
101
  version: '0'
77
102
  type: :development
78
103
  prerelease: false
79
- version_requirements: *70115651537880
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
80
110
  - !ruby/object:Gem::Dependency
81
111
  name: json
82
- requirement: &70115651537460 !ruby/object:Gem::Requirement
112
+ requirement: !ruby/object:Gem::Requirement
83
113
  none: false
84
114
  requirements:
85
115
  - - ! '>='
@@ -87,10 +117,15 @@ dependencies:
87
117
  version: '0'
88
118
  type: :development
89
119
  prerelease: false
90
- version_requirements: *70115651537460
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
91
126
  - !ruby/object:Gem::Dependency
92
127
  name: coffee-script
93
- requirement: &70115651537040 !ruby/object:Gem::Requirement
128
+ requirement: !ruby/object:Gem::Requirement
94
129
  none: false
95
130
  requirements:
96
131
  - - ! '>='
@@ -98,7 +133,12 @@ dependencies:
98
133
  version: '0'
99
134
  type: :development
100
135
  prerelease: false
101
- version_requirements: *70115651537040
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
102
142
  description: Client Side Validations
103
143
  email:
104
144
  - bcardarella@gmail.com
@@ -156,7 +196,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
156
196
  version: 1.3.1
157
197
  requirements: []
158
198
  rubyforge_project:
159
- rubygems_version: 1.8.15
199
+ rubygems_version: 1.8.23
160
200
  signing_key:
161
201
  specification_version: 3
162
202
  summary: Client Side Validations