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

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