client_side_validations 21.0.0 → 22.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1fde76e476a73b701937d5106237ac4525233bb70f3fe6cacbc8367b66cc85e
4
- data.tar.gz: 561af4b98912431057feb7eec2ef1ce8493f8a92e741b9f42c5f13ea8c608164
3
+ metadata.gz: 554a084e86ce5067b6072f503c4e7814a90502054b1cb282bda8fda183507c8d
4
+ data.tar.gz: f4e3365207572aaf71e947c2cb536b8c971eb2b90d18978a3dba3512bd4ede25
5
5
  SHA512:
6
- metadata.gz: f596d52b77b55949970f9bc4bed5a2086fafc8f4130f65d925587389e45d223382cba6ee0dd4d0debef1cf13d8814ffab29a5a3ea5252925c87649f10fd8f9c0
7
- data.tar.gz: 8647fa1b7f8e79a8510f71fd7f0e94f0f60aaf948c67925f026f83d6f0c9fed2faefb98d936ee7bcbcb6dc84780f9a5a2b0a44bea04c9d96892714e4a5535d3e
6
+ metadata.gz: '09319f96ff691d0295e19d499ff1ed43e85bdc5d9f453fb61d86e4c116e178357d19ea7293f2407b6c25d61ed9cdf5f748f44879816eea74f9637ef7ba098373'
7
+ data.tar.gz: 1b79190bed239d7454d8343eec3e61b295d4566e56e34980b19f507450bb592f213948ee7f1415859d1d5f641eefd5feef36773077fabd304571dd1cc50490f8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 22.0.0 / 2023-09-02
4
+
5
+ * [FEATURE] Drop Rails 5.2 and 6.0 support
6
+ * [FEATURE] Drop Ruby 2.6 support
7
+ * [ENHANCEMENT] Test against Ruby 3.2
8
+ * [ENHANCEMENT] Test against jQuery 3.7.1 by default
9
+ * [ENHANCEMENT] Update QUnit to 2.19.4
10
+ * [ENHANCEMENT] Do not use jQuery in validators
11
+
3
12
  ## 21.0.0 / 2022-09-18
4
13
 
5
14
  * [FEATURE] Drop Ruby 2.5 support
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2022 Geremia Taglialatela, Brian Cardarella
3
+ Copyright (c) 2023 Geremia Taglialatela, Brian Cardarella
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  [![Coverage Status](https://coveralls.io/repos/github/DavyJonesLocker/client_side_validations/badge.svg?branch=main)](https://coveralls.io/github/DavyJonesLocker/client_side_validations?branch=main)
9
9
 
10
10
 
11
- `ClientSideValidations` made easy for your Rails 5.2 / 6.x / 7.0 applications!
11
+ `ClientSideValidations` made easy for your Rails 6.1 / 7.x applications!
12
12
 
13
13
  ## Project Goals ##
14
14
 
@@ -543,7 +543,7 @@ on how to properly submit issues and pull requests.
543
543
 
544
544
  ## Legal ##
545
545
 
546
- [DockYard](https://dockyard.com/), LLC © 2012-2022
546
+ [DockYard](https://dockyard.com/), LLC © 2012-2023
547
547
 
548
548
  [@dockyard](https://twitter.com/dockyard)
549
549
 
@@ -40,6 +40,7 @@ module ClientSideValidations
40
40
  options[:html][:validate] = true if options[:validate]
41
41
  options[:html][:method] ||= options[:method]
42
42
 
43
+ # TODO: remove else branch when minimum compatible version when dropping 6.1 support
43
44
  if method(:apply_form_for_options!).arity == 2
44
45
  apply_form_for_options! object, options
45
46
  else
@@ -6,12 +6,7 @@ module ClientSideValidations
6
6
  @@option_map = {}
7
7
 
8
8
  def self.included(base)
9
- checks =
10
- if base.const_defined?(:RESERVED_OPTIONS)
11
- base::RESERVED_OPTIONS - [:only_integer]
12
- else
13
- base::CHECKS.keys
14
- end
9
+ checks = base::RESERVED_OPTIONS - [:only_integer]
15
10
 
16
11
  @@option_map.merge!(checks.inject({}) { |acc, elem| acc.merge!(elem => elem) })
17
12
  super
@@ -26,11 +26,7 @@ module ClientSideValidations
26
26
  end
27
27
 
28
28
  def callbacks_options
29
- if defined?(::ActiveModel::Errors::CALLBACKS_OPTIONS)
30
- ::ActiveModel::Errors::CALLBACKS_OPTIONS
31
- else
32
- ::ActiveModel::Error::CALLBACKS_OPTIONS
33
- end
29
+ ::ActiveModel::Error::CALLBACKS_OPTIONS
34
30
  end
35
31
  end
36
32
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClientSideValidations
4
- VERSION = '21.0.0'
4
+ VERSION = '22.0.0'
5
5
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'client_side_validations/config'
4
- require 'client_side_validations/active_model' if defined?(::ActiveModel)
5
- require 'client_side_validations/active_record' if defined?(::ActiveRecord)
6
- require 'client_side_validations/action_view' if defined?(::ActionView)
4
+ require 'client_side_validations/active_model' if defined?(ActiveModel)
5
+ require 'client_side_validations/active_record' if defined?(ActiveRecord)
6
+ require 'client_side_validations/action_view' if defined?(ActionView)
7
7
 
8
- if defined?(::Rails)
8
+ if defined?(Rails)
9
9
  require 'client_side_validations/engine'
10
10
  require 'client_side_validations/generators'
11
11
  end
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * Client Side Validations JS - v0.3.0 (https://github.com/DavyJonesLocker/client_side_validations)
3
- * Copyright (c) 2022 Geremia Taglialatela, Brian Cardarella
2
+ * Client Side Validations JS - v0.4.0 (https://github.com/DavyJonesLocker/client_side_validations)
3
+ * Copyright (c) 2023 Geremia Taglialatela, Brian Cardarella
4
4
  * Licensed under MIT (https://opensource.org/licenses/mit-license.php)
5
5
  */
6
6
 
@@ -10,20 +10,33 @@
10
10
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ClientSideValidations = factory(global.jQuery));
11
11
  })(this, (function (jQuery) { 'use strict';
12
12
 
13
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
14
-
15
- var jQuery__default = /*#__PURE__*/_interopDefaultLegacy(jQuery);
16
-
17
- function _typeof(obj) {
13
+ function _typeof(o) {
18
14
  "@babel/helpers - typeof";
19
15
 
20
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
21
- return typeof obj;
22
- } : function (obj) {
23
- return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
24
- }, _typeof(obj);
16
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
17
+ return typeof o;
18
+ } : function (o) {
19
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
20
+ }, _typeof(o);
25
21
  }
26
22
 
23
+ var arrayHasValue = function arrayHasValue(value, otherValues) {
24
+ for (var i = 0, l = otherValues.length; i < l; i++) {
25
+ if (value === otherValues[i]) {
26
+ return true;
27
+ }
28
+ }
29
+ return false;
30
+ };
31
+ var createElementFromHTML = function createElementFromHTML(html) {
32
+ var element = document.createElement('div');
33
+ element.innerHTML = html;
34
+ return element.firstChild;
35
+ };
36
+ var isValuePresent = function isValuePresent(value) {
37
+ return !/^\s*$/.test(value || '');
38
+ };
39
+
27
40
  var ClientSideValidations = {
28
41
  callbacks: {
29
42
  element: {
@@ -74,25 +87,25 @@
74
87
  input: function input(form) {
75
88
  return {
76
89
  'focusout.ClientSideValidations': function focusoutClientSideValidations() {
77
- jQuery__default["default"](this).isValid(form.ClientSideValidations.settings.validators);
90
+ jQuery(this).isValid(form.ClientSideValidations.settings.validators);
78
91
  },
79
92
  'change.ClientSideValidations': function changeClientSideValidations() {
80
- jQuery__default["default"](this).data('changed', true);
93
+ jQuery(this).data('changed', true);
81
94
  },
82
95
  'element:validate:after.ClientSideValidations': function elementValidateAfterClientSideValidations(eventData) {
83
- ClientSideValidations.callbacks.element.after(jQuery__default["default"](this), eventData);
96
+ ClientSideValidations.callbacks.element.after(jQuery(this), eventData);
84
97
  },
85
98
  'element:validate:before.ClientSideValidations': function elementValidateBeforeClientSideValidations(eventData) {
86
- ClientSideValidations.callbacks.element.before(jQuery__default["default"](this), eventData);
99
+ ClientSideValidations.callbacks.element.before(jQuery(this), eventData);
87
100
  },
88
101
  'element:validate:fail.ClientSideValidations': function elementValidateFailClientSideValidations(eventData, message) {
89
- var $element = jQuery__default["default"](this);
102
+ var $element = jQuery(this);
90
103
  ClientSideValidations.callbacks.element.fail($element, message, function () {
91
104
  form.ClientSideValidations.addError($element, message);
92
105
  }, eventData);
93
106
  },
94
107
  'element:validate:pass.ClientSideValidations': function elementValidatePassClientSideValidations(eventData) {
95
- var $element = jQuery__default["default"](this);
108
+ var $element = jQuery(this);
96
109
  ClientSideValidations.callbacks.element.pass($element, function () {
97
110
  form.ClientSideValidations.removeError($element);
98
111
  }, eventData);
@@ -112,7 +125,7 @@
112
125
  },
113
126
  enablers: {
114
127
  form: function form(_form2) {
115
- var $form = jQuery__default["default"](_form2);
128
+ var $form = jQuery(_form2);
116
129
  _form2.ClientSideValidations = {
117
130
  settings: $form.data('clientSideValidations'),
118
131
  addError: function addError($element, message) {
@@ -123,42 +136,36 @@
123
136
  }
124
137
  };
125
138
  var eventsToBind = ClientSideValidations.eventsToBind.form(_form2, $form);
126
-
127
139
  for (var eventName in eventsToBind) {
128
140
  var eventFunction = eventsToBind[eventName];
129
141
  $form.on(eventName, eventFunction);
130
142
  }
131
-
132
143
  $form.find(ClientSideValidations.selectors.inputs).each(function () {
133
144
  ClientSideValidations.enablers.input(this);
134
145
  });
135
146
  },
136
147
  input: function input(_input) {
137
- var $input = jQuery__default["default"](_input);
148
+ var $input = jQuery(_input);
138
149
  var form = _input.form;
139
- var $form = jQuery__default["default"](form);
150
+ var $form = jQuery(form);
140
151
  var eventsToBind = ClientSideValidations.eventsToBind.input(form);
141
-
142
152
  for (var eventName in eventsToBind) {
143
153
  var eventFunction = eventsToBind[eventName];
144
154
  $input.filter(':not(:radio):not([id$=_confirmation])').each(function () {
145
- jQuery__default["default"](this).attr('data-validate', true);
155
+ jQuery(this).attr('data-validate', true);
146
156
  }).on(eventName, eventFunction);
147
157
  }
148
-
149
158
  $input.filter(':checkbox').on('change.ClientSideValidations', function () {
150
- jQuery__default["default"](this).isValid(form.ClientSideValidations.settings.validators);
159
+ jQuery(this).isValid(form.ClientSideValidations.settings.validators);
151
160
  });
152
161
  $input.filter('[id$=_confirmation]').each(function () {
153
- var $element = jQuery__default["default"](this);
162
+ var $element = jQuery(this);
154
163
  var $elementToConfirm = $form.find("#".concat(this.id.match(/(.+)_confirmation/)[1], ":input"));
155
-
156
164
  if ($elementToConfirm.length) {
157
165
  var _eventsToBind = ClientSideValidations.eventsToBind.inputConfirmation($elementToConfirm, form);
158
-
159
166
  for (var _eventName in _eventsToBind) {
160
167
  var _eventFunction = _eventsToBind[_eventName];
161
- jQuery__default["default"]("#".concat($element.attr('id'))).on(_eventName, _eventFunction);
168
+ jQuery("#".concat($element.attr('id'))).on(_eventName, _eventFunction);
162
169
  }
163
170
  }
164
171
  });
@@ -167,40 +174,56 @@
167
174
  formBuilders: {
168
175
  'ActionView::Helpers::FormBuilder': {
169
176
  add: function add($element, settings, message) {
170
- var $form = jQuery__default["default"]($element[0].form);
171
-
172
- if ($element.data('valid') !== false && $form.find("label.message[for=\"".concat($element.attr('id'), "\"]"))[0] == null) {
173
- var $inputErrorField = jQuery__default["default"](settings.input_tag);
174
- var $labelErrorField = jQuery__default["default"](settings.label_tag);
175
- var $label = $form.find("label[for=\"".concat($element.attr('id'), "\"]:not(.message)"));
176
-
177
- if ($element.attr('autofocus')) {
178
- $element.attr('autofocus', false);
177
+ var element = $element[0];
178
+ var form = element.form;
179
+ var inputErrorTemplate = createElementFromHTML(settings.input_tag);
180
+ var inputErrorElement = element.closest(".".concat(inputErrorTemplate.getAttribute('class').replace(/ /g, '.')));
181
+ if (!inputErrorElement) {
182
+ inputErrorElement = inputErrorTemplate;
183
+ if (element.getAttribute('autofocus')) {
184
+ element.setAttribute('autofocus', false);
185
+ }
186
+ element.before(inputErrorElement);
187
+ inputErrorElement.querySelector('span#input_tag').replaceWith(element);
188
+ var inputErrorLabelMessageElement = inputErrorElement.querySelector('label.message');
189
+ if (inputErrorLabelMessageElement) {
190
+ inputErrorLabelMessageElement.setAttribute('for', element.id);
179
191
  }
180
-
181
- $element.before($inputErrorField);
182
- $inputErrorField.find('span#input_tag').replaceWith($element);
183
- $inputErrorField.find('label.message').attr('for', $element.attr('id'));
184
- $labelErrorField.find('label.message').attr('for', $element.attr('id'));
185
- $labelErrorField.insertAfter($label);
186
- $labelErrorField.find('label#label_tag').replaceWith($label);
187
192
  }
188
-
189
- $form.find("label.message[for=\"".concat($element.attr('id'), "\"]")).text(message);
193
+ var labelElement = form.querySelector("label[for=\"".concat(element.id, "\"]:not(.message)"));
194
+ if (labelElement) {
195
+ var labelErrorTemplate = createElementFromHTML(settings.label_tag);
196
+ var labelErrorContainer = labelElement.closest(".".concat(labelErrorTemplate.getAttribute('class').replace(/ /g, '.')));
197
+ if (!labelErrorContainer) {
198
+ labelElement.after(labelErrorTemplate);
199
+ labelErrorTemplate.querySelector('label#label_tag').replaceWith(labelElement);
200
+ }
201
+ }
202
+ var labelMessageElement = form.querySelector("label.message[for=\"".concat(element.id, "\"]"));
203
+ if (labelMessageElement) {
204
+ labelMessageElement.textContent = message;
205
+ }
190
206
  },
191
207
  remove: function remove($element, settings) {
192
- var $form = jQuery__default["default"]($element[0].form);
193
- var $inputErrorFieldClass = jQuery__default["default"](settings.input_tag).attr('class');
194
- var $inputErrorField = $element.closest(".".concat($inputErrorFieldClass.replace(/ /g, '.')));
195
- var $label = $form.find("label[for=\"".concat($element.attr('id'), "\"]:not(.message)"));
196
- var $labelErrorFieldClass = jQuery__default["default"](settings.label_tag).attr('class');
197
- var $labelErrorField = $label.closest(".".concat($labelErrorFieldClass.replace(/ /g, '.')));
198
-
199
- if ($inputErrorField[0]) {
200
- $inputErrorField.find("#".concat($element.attr('id'))).detach();
201
- $inputErrorField.replaceWith($element);
202
- $label.detach();
203
- $labelErrorField.replaceWith($label);
208
+ var element = $element[0];
209
+ var form = element.form;
210
+ var inputErrorClass = createElementFromHTML(settings.input_tag).getAttribute('class');
211
+ var inputErrorElement = element.closest(".".concat(inputErrorClass.replace(/ /g, '.')));
212
+ if (inputErrorElement) {
213
+ inputErrorElement.querySelector("#".concat(element.id)).remove();
214
+ inputErrorElement.replaceWith(element);
215
+ }
216
+ var labelElement = form.querySelector("label[for=\"".concat(element.id, "\"]:not(.message)"));
217
+ if (labelElement) {
218
+ var labelErrorClass = createElementFromHTML(settings.label_tag).getAttribute('class');
219
+ var labelErrorElement = labelElement.closest(".".concat(labelErrorClass.replace(/ /g, '.')));
220
+ if (labelErrorElement) {
221
+ labelErrorElement.replaceWith(labelElement);
222
+ }
223
+ }
224
+ var labelMessageElement = form.querySelector("label.message[for=\"".concat(element.id, "\"]"));
225
+ if (labelMessageElement) {
226
+ labelMessageElement.remove();
204
227
  }
205
228
  }
206
229
  }
@@ -218,32 +241,29 @@
218
241
  },
219
242
  validators: {
220
243
  all: function all() {
221
- return jQuery__default["default"].extend({}, ClientSideValidations.validators.local, ClientSideValidations.validators.remote);
244
+ return jQuery.extend({}, ClientSideValidations.validators.local, ClientSideValidations.validators.remote);
222
245
  },
223
246
  local: {},
224
247
  remote: {}
225
248
  },
226
249
  disable: function disable(target) {
227
- var $target = jQuery__default["default"](target);
250
+ var $target = jQuery(target);
228
251
  $target.off('.ClientSideValidations');
229
-
230
252
  if ($target.is('form')) {
231
253
  ClientSideValidations.disable($target.find(':input'));
232
254
  } else {
233
255
  $target.removeData(['changed', 'valid']);
234
256
  $target.filter(':input').each(function () {
235
- jQuery__default["default"](this).removeAttr('data-validate');
257
+ jQuery(this).removeAttr('data-validate');
236
258
  });
237
259
  }
238
260
  },
239
261
  reset: function reset(form) {
240
- var $form = jQuery__default["default"](form);
262
+ var $form = jQuery(form);
241
263
  ClientSideValidations.disable(form);
242
-
243
264
  for (var key in form.ClientSideValidations.settings.validators) {
244
265
  form.ClientSideValidations.removeError($form.find("[name=\"".concat(key, "\"]")));
245
266
  }
246
-
247
267
  ClientSideValidations.enablers.form(form);
248
268
  },
249
269
  initializeOnEvent: function initializeOnEvent() {
@@ -255,68 +275,50 @@
255
275
  },
256
276
  start: function start() {
257
277
  var initializeOnEvent = ClientSideValidations.initializeOnEvent();
258
-
259
278
  if (initializeOnEvent != null) {
260
- jQuery__default["default"](document).on(initializeOnEvent, function () {
261
- return jQuery__default["default"](ClientSideValidations.selectors.forms).validate();
279
+ jQuery(document).on(initializeOnEvent, function () {
280
+ return jQuery(ClientSideValidations.selectors.forms).validate();
262
281
  });
263
282
  } else {
264
- jQuery__default["default"](function () {
265
- return jQuery__default["default"](ClientSideValidations.selectors.forms).validate();
283
+ jQuery(function () {
284
+ return jQuery(ClientSideValidations.selectors.forms).validate();
266
285
  });
267
286
  }
268
287
  }
269
288
  };
270
289
 
271
- var arrayHasValue = function arrayHasValue(value, otherValues) {
272
- for (var i = 0, l = otherValues.length; i < l; i++) {
273
- if (value === otherValues[i]) {
274
- return true;
275
- }
276
- }
277
-
278
- return false;
279
- };
280
- var isValuePresent = function isValuePresent(value) {
281
- return !/^\s*$/.test(value || '');
282
- };
283
-
284
290
  var absenceLocalValidator = function absenceLocalValidator($element, options) {
285
- if (isValuePresent($element.val())) {
291
+ var element = $element[0];
292
+ if (isValuePresent(element.value)) {
286
293
  return options.message;
287
294
  }
288
295
  };
289
296
  var presenceLocalValidator = function presenceLocalValidator($element, options) {
290
- if (!isValuePresent($element.val())) {
297
+ var element = $element[0];
298
+ if (!isValuePresent(element.value)) {
291
299
  return options.message;
292
300
  }
293
301
  };
294
302
 
295
303
  var DEFAULT_ACCEPT_OPTION = ['1', true];
296
-
297
304
  var isTextAccepted = function isTextAccepted(value, acceptOption) {
298
305
  if (!acceptOption) {
299
306
  acceptOption = DEFAULT_ACCEPT_OPTION;
300
307
  }
301
-
302
308
  if (Array.isArray(acceptOption)) {
303
309
  return arrayHasValue(value, acceptOption);
304
310
  }
305
-
306
311
  return value === acceptOption;
307
312
  };
308
-
309
313
  var acceptanceLocalValidator = function acceptanceLocalValidator($element, options) {
314
+ var element = $element[0];
310
315
  var valid = true;
311
-
312
- if ($element.attr('type') === 'checkbox') {
313
- valid = $element.prop('checked');
316
+ if (element.type === 'checkbox') {
317
+ valid = element.checked;
314
318
  }
315
-
316
- if ($element.attr('type') === 'text') {
317
- valid = isTextAccepted($element.val(), options.accept);
319
+ if (element.type === 'text') {
320
+ valid = isTextAccepted(element.value, options.accept);
318
321
  }
319
-
320
322
  if (!valid) {
321
323
  return options.message;
322
324
  }
@@ -325,18 +327,15 @@
325
327
  var isMatching = function isMatching(value, regExpOptions) {
326
328
  return new RegExp(regExpOptions.source, regExpOptions.options).test(value);
327
329
  };
328
-
329
330
  var hasValidFormat = function hasValidFormat(value, withOptions, withoutOptions) {
330
331
  return withOptions && isMatching(value, withOptions) || withoutOptions && !isMatching(value, withoutOptions);
331
332
  };
332
-
333
333
  var formatLocalValidator = function formatLocalValidator($element, options) {
334
- var value = $element.val();
335
-
334
+ var element = $element[0];
335
+ var value = element.value;
336
336
  if (options.allow_blank && !isValuePresent(value)) {
337
337
  return;
338
338
  }
339
-
340
339
  if (!hasValidFormat(value, options.with, options.without)) {
341
340
  return options.message;
342
341
  }
@@ -368,71 +367,64 @@
368
367
  return parseFloat(a) !== parseFloat(b);
369
368
  }
370
369
  };
371
-
372
- var getOtherValue = function getOtherValue(validationOption, $form) {
370
+ var formatValue = function formatValue(element) {
371
+ var value = element.value || '';
372
+ var numberFormat = element.form.ClientSideValidations.settings.number_format;
373
+ return value.trim().replace(new RegExp("\\".concat(numberFormat.separator), 'g'), '.');
374
+ };
375
+ var getOtherValue = function getOtherValue(validationOption, form) {
373
376
  if (!isNaN(parseFloat(validationOption))) {
374
377
  return validationOption;
375
378
  }
376
-
377
- var validationElement = $form.find("[name*=\"".concat(validationOption, "\"]"));
378
-
379
- if (validationElement.length === 1) {
380
- var numberFormat = $form[0].ClientSideValidations.settings.number_format;
381
- var otherFormattedValue = jQuery__default["default"].trim(validationElement.val()).replace(new RegExp("\\".concat(numberFormat.separator), 'g'), '.');
382
-
379
+ var validationElements = form.querySelectorAll("[name*=\"".concat(validationOption, "\"]"));
380
+ if (validationElements.length === 1) {
381
+ var validationElement = validationElements[0];
382
+ var otherFormattedValue = formatValue(validationElement);
383
383
  if (!isNaN(parseFloat(otherFormattedValue))) {
384
384
  return otherFormattedValue;
385
385
  }
386
386
  }
387
387
  };
388
-
389
- var isValid = function isValid(validationFunction, validationOption, formattedValue, $form) {
388
+ var isValid = function isValid(validationFunction, validationOption, formattedValue, form) {
390
389
  if (validationFunction.length === 2) {
391
- var otherValue = getOtherValue(validationOption, $form);
390
+ var otherValue = getOtherValue(validationOption, form);
392
391
  return otherValue == null || otherValue === '' || validationFunction(formattedValue, otherValue);
393
392
  } else {
394
393
  return validationFunction(formattedValue);
395
394
  }
396
395
  };
397
-
398
- var runFunctionValidations = function runFunctionValidations(formattedValue, $form, options) {
396
+ var runFunctionValidations = function runFunctionValidations(formattedValue, form, options) {
399
397
  for (var validation in VALIDATIONS$1) {
400
398
  var validationOption = options[validation];
401
- var validationFunction = VALIDATIONS$1[validation]; // Must check for null because this could be 0
399
+ var validationFunction = VALIDATIONS$1[validation];
402
400
 
401
+ // Must check for null because this could be 0
403
402
  if (validationOption == null) {
404
403
  continue;
405
404
  }
406
-
407
- if (!isValid(validationFunction, validationOption, formattedValue, $form)) {
405
+ if (!isValid(validationFunction, validationOption, formattedValue, form)) {
408
406
  return options.messages[validation];
409
407
  }
410
408
  }
411
409
  };
412
-
413
- var runValidations$1 = function runValidations(formattedValue, $form, options) {
410
+ var runValidations$1 = function runValidations(formattedValue, form, options) {
414
411
  if (options.only_integer && !ClientSideValidations.patterns.numericality.only_integer.test(formattedValue)) {
415
412
  return options.messages.only_integer;
416
413
  }
417
-
418
414
  if (!ClientSideValidations.patterns.numericality.default.test(formattedValue)) {
419
415
  return options.messages.numericality;
420
416
  }
421
-
422
- return runFunctionValidations(formattedValue, $form, options);
417
+ return runFunctionValidations(formattedValue, form, options);
423
418
  };
424
-
425
419
  var numericalityLocalValidator = function numericalityLocalValidator($element, options) {
426
- var value = $element.val();
427
-
420
+ var element = $element[0];
421
+ var value = element.value;
428
422
  if (options.allow_blank && !isValuePresent(value)) {
429
423
  return;
430
424
  }
431
-
432
- var $form = jQuery__default["default"]($element[0].form);
433
- var numberFormat = $form[0].ClientSideValidations.settings.number_format;
434
- var formattedValue = jQuery__default["default"].trim(value).replace(new RegExp("\\".concat(numberFormat.separator), 'g'), '.');
435
- return runValidations$1(formattedValue, $form, options);
425
+ var form = element.form;
426
+ var formattedValue = formatValue(element);
427
+ return runValidations$1(formattedValue, form, options);
436
428
  };
437
429
 
438
430
  var VALIDATIONS = {
@@ -446,121 +438,107 @@
446
438
  return a <= parseInt(b, 10);
447
439
  }
448
440
  };
449
-
450
441
  var runValidations = function runValidations(valueLength, options) {
451
442
  for (var validation in VALIDATIONS) {
452
443
  var validationOption = options[validation];
453
444
  var validationFunction = VALIDATIONS[validation];
454
-
455
445
  if (validationOption && !validationFunction(valueLength, validationOption)) {
456
446
  return options.messages[validation];
457
447
  }
458
448
  }
459
449
  };
460
-
461
450
  var lengthLocalValidator = function lengthLocalValidator($element, options) {
462
- var value = $element.val();
463
-
451
+ var element = $element[0];
452
+ var value = element.value;
464
453
  if (options.allow_blank && !isValuePresent(value)) {
465
454
  return;
466
455
  }
467
-
468
456
  return runValidations(value.length, options);
469
457
  };
470
458
 
471
459
  var isInList = function isInList(value, otherValues) {
472
460
  var normalizedOtherValues = [];
473
-
474
461
  for (var otherValueIndex in otherValues) {
475
462
  normalizedOtherValues.push(otherValues[otherValueIndex].toString());
476
463
  }
477
-
478
464
  return arrayHasValue(value, normalizedOtherValues);
479
465
  };
480
-
481
466
  var isInRange = function isInRange(value, range) {
482
467
  return value >= range[0] && value <= range[1];
483
468
  };
484
-
485
469
  var isIncluded = function isIncluded(value, options, allowBlank) {
486
470
  if ((options.allow_blank && !isValuePresent(value)) === allowBlank) {
487
471
  return true;
488
472
  }
489
-
490
473
  return options.in && isInList(value, options.in) || options.range && isInRange(value, options.range);
491
474
  };
492
-
493
475
  var exclusionLocalValidator = function exclusionLocalValidator($element, options) {
494
- var value = $element.val();
495
-
476
+ var element = $element[0];
477
+ var value = element.value;
496
478
  if (isIncluded(value, options, false) || !options.allow_blank && !isValuePresent(value)) {
497
479
  return options.message;
498
480
  }
499
481
  };
500
482
  var inclusionLocalValidator = function inclusionLocalValidator($element, options) {
501
- var value = $element.val();
502
-
483
+ var element = $element[0];
484
+ var value = element.value;
503
485
  if (!isIncluded(value, options, true)) {
504
486
  return options.message;
505
487
  }
506
488
  };
507
489
 
508
490
  var confirmationLocalValidator = function confirmationLocalValidator($element, options) {
509
- var value = $element.val();
510
- var confirmationValue = jQuery__default["default"]("#".concat($element.attr('id'), "_confirmation")).val();
511
-
491
+ var element = $element[0];
492
+ var value = element.value;
493
+ var confirmationValue = document.getElementById("".concat(element.id, "_confirmation")).value;
512
494
  if (!options.case_sensitive) {
513
495
  value = value.toLowerCase();
514
496
  confirmationValue = confirmationValue.toLowerCase();
515
497
  }
516
-
517
498
  if (value !== confirmationValue) {
518
499
  return options.message;
519
500
  }
520
501
  };
521
502
 
522
- var isLocallyUnique = function isLocallyUnique(currentElement, value, otherValue, caseSensitive) {
503
+ var isLocallyUnique = function isLocallyUnique(element, value, otherValue, caseSensitive) {
523
504
  if (!caseSensitive) {
524
505
  value = value.toLowerCase();
525
506
  otherValue = otherValue.toLowerCase();
526
507
  }
527
-
528
508
  if (otherValue === value) {
529
- jQuery__default["default"](currentElement).data('notLocallyUnique', true);
509
+ element.dataset.notLocallyUnique = true;
530
510
  return false;
531
511
  }
532
-
533
- if (jQuery__default["default"](currentElement).data('notLocallyUnique')) {
534
- jQuery__default["default"](currentElement).removeData('notLocallyUnique').data('changed', true);
512
+ if (element.dataset.notLocallyUnique) {
513
+ delete element.dataset.notLocallyUnique;
514
+ element.dataset.changed = true;
535
515
  }
536
-
537
516
  return true;
538
517
  };
539
-
540
518
  var uniquenessLocalValidator = function uniquenessLocalValidator($element, options) {
541
- var elementName = $element.attr('name');
519
+ var element = $element[0];
520
+ var elementName = element.name;
542
521
  var matches = elementName.match(/^(.+_attributes\])\[\d+\](.+)$/);
543
-
544
522
  if (!matches) {
545
523
  return;
546
524
  }
547
-
548
- var $form = jQuery__default["default"]($element[0].form);
549
- var value = $element.val();
525
+ var form = element.form;
526
+ var value = element.value;
550
527
  var valid = true;
551
- $form.find(":input[name^=\"".concat(matches[1], "\"][name$=\"").concat(matches[2], "\"]")).not($element).each(function () {
552
- var otherValue = jQuery__default["default"](this).val();
553
-
554
- if (!isLocallyUnique(this, value, otherValue, options.case_sensitive)) {
528
+ var query = "[name^=\"".concat(matches[1], "\"][name$=\"").concat(matches[2], "\"]:not([name=\"").concat(elementName, "\"])");
529
+ var otherElements = form.querySelectorAll(query);
530
+ Array.prototype.slice.call(otherElements).forEach(function (otherElement) {
531
+ var otherValue = otherElement.value;
532
+ if (!isLocallyUnique(otherElement, value, otherValue, options.case_sensitive)) {
555
533
  valid = false;
556
534
  }
557
535
  });
558
-
559
536
  if (!valid) {
560
537
  return options.message;
561
538
  }
562
539
  };
563
540
 
541
+ // Validators will run in the following order
564
542
  ClientSideValidations.validators.local = {
565
543
  absence: absenceLocalValidator,
566
544
  presence: presenceLocalValidator,
@@ -573,196 +551,152 @@
573
551
  confirmation: confirmationLocalValidator,
574
552
  uniqueness: uniquenessLocalValidator
575
553
  };
576
-
577
- jQuery__default["default"].fn.disableClientSideValidations = function () {
554
+ jQuery.fn.disableClientSideValidations = function () {
578
555
  ClientSideValidations.disable(this);
579
556
  return this;
580
557
  };
581
-
582
- jQuery__default["default"].fn.enableClientSideValidations = function () {
558
+ jQuery.fn.enableClientSideValidations = function () {
583
559
  var _this = this;
584
-
585
560
  var selectors = {
586
561
  forms: 'form',
587
562
  inputs: 'input'
588
563
  };
589
-
590
- var _loop = function _loop(selector) {
564
+ var _loop = function _loop() {
591
565
  var enablers = selectors[selector];
592
-
593
566
  _this.filter(ClientSideValidations.selectors[selector]).each(function () {
594
567
  ClientSideValidations.enablers[enablers](this);
595
568
  });
596
569
  };
597
-
598
570
  for (var selector in selectors) {
599
- _loop(selector);
571
+ _loop();
600
572
  }
601
-
602
573
  return this;
603
574
  };
604
-
605
- jQuery__default["default"].fn.resetClientSideValidations = function () {
575
+ jQuery.fn.resetClientSideValidations = function () {
606
576
  this.filter(ClientSideValidations.selectors.forms).each(function () {
607
577
  ClientSideValidations.reset(this);
608
578
  });
609
579
  return this;
610
580
  };
611
-
612
- jQuery__default["default"].fn.validate = function () {
581
+ jQuery.fn.validate = function () {
613
582
  this.filter(ClientSideValidations.selectors.forms).each(function () {
614
- jQuery__default["default"](this).enableClientSideValidations();
583
+ jQuery(this).enableClientSideValidations();
615
584
  });
616
585
  return this;
617
586
  };
618
-
619
- jQuery__default["default"].fn.isValid = function (validators) {
620
- var obj = jQuery__default["default"](this[0]);
621
-
587
+ jQuery.fn.isValid = function (validators) {
588
+ var obj = jQuery(this[0]);
622
589
  if (obj.is('form')) {
623
590
  return validateForm(obj, validators);
624
591
  } else {
625
592
  return validateElement(obj, validatorsFor(this[0].name, validators));
626
593
  }
627
594
  };
628
-
629
595
  var cleanNestedElementName = function cleanNestedElementName(elementName, nestedMatches, validators) {
630
596
  for (var validatorName in validators) {
631
597
  if (validatorName.match("\\[".concat(nestedMatches[1], "\\].*\\[\\]\\[").concat(nestedMatches[2], "\\]$"))) {
632
598
  elementName = elementName.replace(/\[[\da-z_]+\]\[(\w+)\]$/g, '[][$1]');
633
599
  }
634
600
  }
635
-
636
601
  return elementName;
637
602
  };
638
-
639
603
  var cleanElementName = function cleanElementName(elementName, validators) {
640
604
  elementName = elementName.replace(/\[(\w+_attributes)\]\[[\da-z_]+\](?=\[(?:\w+_attributes)\])/g, '[$1][]');
641
605
  var nestedMatches = elementName.match(/\[(\w+_attributes)\].*\[(\w+)\]$/);
642
-
643
606
  if (nestedMatches) {
644
607
  elementName = cleanNestedElementName(elementName, nestedMatches, validators);
645
608
  }
646
-
647
609
  return elementName;
648
610
  };
649
-
650
611
  var validatorsFor = function validatorsFor(elementName, validators) {
651
612
  if (Object.prototype.hasOwnProperty.call(validators, elementName)) {
652
613
  return validators[elementName];
653
614
  }
654
-
655
615
  return validators[cleanElementName(elementName, validators)] || {};
656
616
  };
657
-
658
617
  var validateForm = function validateForm($form, validators) {
659
618
  var valid = true;
660
619
  $form.trigger('form:validate:before.ClientSideValidations');
661
620
  $form.find(ClientSideValidations.selectors.validate_inputs).each(function () {
662
- if (!jQuery__default["default"](this).isValid(validators)) {
621
+ if (!jQuery(this).isValid(validators)) {
663
622
  valid = false;
664
623
  }
665
-
666
624
  return true;
667
625
  });
668
-
669
626
  if (valid) {
670
627
  $form.trigger('form:validate:pass.ClientSideValidations');
671
628
  } else {
672
629
  $form.trigger('form:validate:fail.ClientSideValidations');
673
630
  }
674
-
675
631
  $form.trigger('form:validate:after.ClientSideValidations');
676
632
  return valid;
677
633
  };
678
-
679
634
  var passElement = function passElement($element) {
680
635
  $element.trigger('element:validate:pass.ClientSideValidations').data('valid', null);
681
636
  };
682
-
683
637
  var failElement = function failElement($element, message) {
684
638
  $element.trigger('element:validate:fail.ClientSideValidations', message).data('valid', false);
685
639
  };
686
-
687
640
  var afterValidate = function afterValidate($element) {
688
641
  return $element.trigger('element:validate:after.ClientSideValidations').data('valid') !== false;
689
642
  };
690
-
691
643
  var executeValidator = function executeValidator(validatorFunctions, validatorFunction, validatorOptions, $element) {
692
644
  for (var validatorOption in validatorOptions) {
693
645
  if (!validatorOptions[validatorOption]) {
694
646
  continue;
695
647
  }
696
-
697
648
  var message = validatorFunction.call(validatorFunctions, $element, validatorOptions[validatorOption]);
698
-
699
649
  if (message) {
700
650
  failElement($element, message);
701
651
  return false;
702
652
  }
703
653
  }
704
-
705
654
  return true;
706
655
  };
707
-
708
656
  var executeValidators = function executeValidators(validatorFunctions, $element, validators) {
709
657
  for (var validator in validators) {
710
658
  if (!validatorFunctions[validator]) {
711
659
  continue;
712
660
  }
713
-
714
661
  if (!executeValidator(validatorFunctions, validatorFunctions[validator], validators[validator], $element)) {
715
662
  return false;
716
663
  }
717
664
  }
718
-
719
665
  return true;
720
666
  };
721
-
722
667
  var isMarkedForDestroy = function isMarkedForDestroy($element) {
723
668
  if ($element.attr('name').search(/\[([^\]]*?)\]$/) >= 0) {
724
669
  var destroyInputName = $element.attr('name').replace(/\[([^\]]*?)\]$/, '[_destroy]');
725
-
726
- if (jQuery__default["default"]("input[name=\"".concat(destroyInputName, "\"]")).val() === '1') {
670
+ if (jQuery("input[name=\"".concat(destroyInputName, "\"]")).val() === '1') {
727
671
  return true;
728
672
  }
729
673
  }
730
-
731
674
  return false;
732
675
  };
733
-
734
676
  var executeAllValidators = function executeAllValidators($element, validators) {
735
677
  if ($element.data('changed') === false || $element.prop('disabled')) {
736
678
  return;
737
679
  }
738
-
739
680
  $element.data('changed', false);
740
-
741
681
  if (executeValidators(ClientSideValidations.validators.all(), $element, validators)) {
742
682
  passElement($element);
743
683
  }
744
684
  };
745
-
746
685
  var validateElement = function validateElement($element, validators) {
747
686
  $element.trigger('element:validate:before.ClientSideValidations');
748
-
749
687
  if (isMarkedForDestroy($element)) {
750
688
  passElement($element);
751
689
  } else {
752
690
  executeAllValidators($element, validators);
753
691
  }
754
-
755
692
  return afterValidate($element);
756
693
  };
757
-
758
694
  if (!window.ClientSideValidations) {
759
695
  window.ClientSideValidations = ClientSideValidations;
760
-
761
696
  if (!isAMD() && !isCommonJS()) {
762
697
  ClientSideValidations.start();
763
698
  }
764
699
  }
765
-
766
700
  function isAMD() {
767
701
  return typeof define === 'function' && define.amd; // eslint-disable-line no-undef
768
702
  }
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: 21.0.0
4
+ version: 22.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geremia Taglialatela
@@ -9,28 +9,8 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-09-18 00:00:00.000000000 Z
12
+ date: 2023-09-02 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: rails
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ">="
19
- - !ruby/object:Gem::Version
20
- version: '5.2'
21
- - - "<"
22
- - !ruby/object:Gem::Version
23
- version: '7.1'
24
- type: :runtime
25
- prerelease: false
26
- version_requirements: !ruby/object:Gem::Requirement
27
- requirements:
28
- - - ">="
29
- - !ruby/object:Gem::Version
30
- version: '5.2'
31
- - - "<"
32
- - !ruby/object:Gem::Version
33
- version: '7.1'
34
14
  - !ruby/object:Gem::Dependency
35
15
  name: js_regex
36
16
  requirement: !ruby/object:Gem::Requirement
@@ -46,173 +26,25 @@ dependencies:
46
26
  - !ruby/object:Gem::Version
47
27
  version: '3.7'
48
28
  - !ruby/object:Gem::Dependency
49
- name: appraisal
50
- requirement: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '2.4'
55
- type: :development
56
- prerelease: false
57
- version_requirements: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '2.4'
62
- - !ruby/object:Gem::Dependency
63
- name: byebug
64
- requirement: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '11.1'
69
- type: :development
70
- prerelease: false
71
- version_requirements: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '11.1'
76
- - !ruby/object:Gem::Dependency
77
- name: m
78
- requirement: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '1.6'
83
- type: :development
84
- prerelease: false
85
- version_requirements: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '1.6'
90
- - !ruby/object:Gem::Dependency
91
- name: minitest
92
- requirement: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '5.16'
97
- type: :development
98
- prerelease: false
99
- version_requirements: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '5.16'
104
- - !ruby/object:Gem::Dependency
105
- name: mocha
106
- requirement: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '1.14'
111
- type: :development
112
- prerelease: false
113
- version_requirements: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '1.14'
118
- - !ruby/object:Gem::Dependency
119
- name: rake
120
- requirement: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '13.0'
125
- type: :development
126
- prerelease: false
127
- version_requirements: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '13.0'
132
- - !ruby/object:Gem::Dependency
133
- name: simplecov
134
- requirement: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: 0.21.2
139
- type: :development
140
- prerelease: false
141
- version_requirements: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: 0.21.2
146
- - !ruby/object:Gem::Dependency
147
- name: simplecov-lcov
148
- requirement: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: 0.8.0
153
- type: :development
154
- prerelease: false
155
- version_requirements: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - "~>"
158
- - !ruby/object:Gem::Version
159
- version: 0.8.0
160
- - !ruby/object:Gem::Dependency
161
- name: sqlite3
162
- requirement: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: '1.5'
167
- type: :development
168
- prerelease: false
169
- version_requirements: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: '1.5'
174
- - !ruby/object:Gem::Dependency
175
- name: shotgun
29
+ name: rails
176
30
  requirement: !ruby/object:Gem::Requirement
177
31
  requirements:
178
- - - "~>"
179
- - !ruby/object:Gem::Version
180
- version: 0.9.2
181
- type: :development
182
- prerelease: false
183
- version_requirements: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - "~>"
32
+ - - ">="
186
33
  - !ruby/object:Gem::Version
187
- version: 0.9.2
188
- - !ruby/object:Gem::Dependency
189
- name: sinatra
190
- requirement: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - "~>"
34
+ version: '6.1'
35
+ - - "<"
193
36
  - !ruby/object:Gem::Version
194
- version: '2.2'
195
- type: :development
37
+ version: '7.1'
38
+ type: :runtime
196
39
  prerelease: false
197
40
  version_requirements: !ruby/object:Gem::Requirement
198
41
  requirements:
199
- - - "~>"
200
- - !ruby/object:Gem::Version
201
- version: '2.2'
202
- - !ruby/object:Gem::Dependency
203
- name: webrick
204
- requirement: !ruby/object:Gem::Requirement
205
- requirements:
206
- - - "~>"
42
+ - - ">="
207
43
  - !ruby/object:Gem::Version
208
- version: '1.7'
209
- type: :development
210
- prerelease: false
211
- version_requirements: !ruby/object:Gem::Requirement
212
- requirements:
213
- - - "~>"
44
+ version: '6.1'
45
+ - - "<"
214
46
  - !ruby/object:Gem::Version
215
- version: '1.7'
47
+ version: '7.1'
216
48
  description: Client Side Validations made easy for your Rails 5 applications
217
49
  email:
218
50
  - tagliala.dev@gmail.com
@@ -271,14 +103,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
271
103
  requirements:
272
104
  - - ">="
273
105
  - !ruby/object:Gem::Version
274
- version: '2.6'
106
+ version: '2.7'
275
107
  required_rubygems_version: !ruby/object:Gem::Requirement
276
108
  requirements:
277
109
  - - ">="
278
110
  - !ruby/object:Gem::Version
279
111
  version: '0'
280
112
  requirements: []
281
- rubygems_version: 3.3.12
113
+ rubygems_version: 3.4.19
282
114
  signing_key:
283
115
  specification_version: 4
284
116
  summary: Client Side Validations