client_side_validations 3.2.8 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.md +46 -0
  3. data/README.md +540 -0
  4. data/lib/client_side_validations.rb +0 -1
  5. data/lib/client_side_validations/action_view.rb +4 -3
  6. data/lib/client_side_validations/action_view/form_builder.rb +101 -84
  7. data/lib/client_side_validations/action_view/form_helper.rb +99 -110
  8. data/lib/client_side_validations/action_view/form_tag_helper.rb +13 -9
  9. data/lib/client_side_validations/active_model.rb +95 -80
  10. data/lib/client_side_validations/active_model/absence.rb +11 -0
  11. data/lib/client_side_validations/active_model/acceptance.rb +7 -6
  12. data/lib/client_side_validations/active_model/exclusion.rb +4 -24
  13. data/lib/client_side_validations/active_model/format.rb +24 -23
  14. data/lib/client_side_validations/active_model/inclusion.rb +4 -23
  15. data/lib/client_side_validations/active_model/length.rb +15 -15
  16. data/lib/client_side_validations/active_model/numericality.rb +23 -22
  17. data/lib/client_side_validations/active_model/presence.rb +7 -6
  18. data/lib/client_side_validations/active_record.rb +2 -2
  19. data/lib/client_side_validations/active_record/middleware.rb +41 -39
  20. data/lib/client_side_validations/active_record/uniqueness.rb +24 -23
  21. data/lib/client_side_validations/config.rb +1 -1
  22. data/lib/client_side_validations/core_ext/range.rb +1 -2
  23. data/lib/client_side_validations/core_ext/regexp.rb +6 -4
  24. data/lib/client_side_validations/engine.rb +0 -1
  25. data/lib/client_side_validations/generators.rb +2 -3
  26. data/lib/client_side_validations/generators/rails_validations.rb +2 -3
  27. data/lib/client_side_validations/middleware.rb +17 -24
  28. data/lib/client_side_validations/version.rb +1 -1
  29. data/lib/generators/client_side_validations/copy_assets_generator.rb +7 -11
  30. data/lib/generators/client_side_validations/install_generator.rb +0 -2
  31. data/lib/generators/templates/client_side_validations/initializer.rb +1 -2
  32. data/vendor/assets/javascripts/rails.validations.js +26 -20
  33. metadata +173 -48
  34. data/client_side_validations.gemspec +0 -30
@@ -1,12 +1,16 @@
1
- module ClientSideValidations::ActionView::Helpers
2
- module FormTagHelper
3
- private
4
- def html_options_for_form(url_for_options, options, *parameters_for_url)
5
- options.stringify_keys!
6
- html_options = {}
7
- html_options['data-validate'] = options.delete('validate') if options['validate']
8
- html_options.merge!(super(url_for_options, options, *parameters_for_url))
1
+ module ClientSideValidations
2
+ module ActionView
3
+ module Helpers
4
+ module FormTagHelper
5
+ private
6
+
7
+ def html_options_for_form(url_for_options, options)
8
+ options.stringify_keys!
9
+ html_options = {}
10
+ html_options['data-validate'] = options.delete('validate') if options['validate']
11
+ html_options.merge!(super(url_for_options, options))
12
+ end
9
13
  end
14
+ end
10
15
  end
11
16
  end
12
-
@@ -1,40 +1,39 @@
1
1
  require 'client_side_validations/core_ext'
2
2
 
3
- module ClientSideValidations::ActiveModel
4
- module Validator
3
+ module ClientSideValidations
4
+ module ActiveModel
5
+ module Validator
6
+ def client_side_hash(model, attribute, _force = nil)
7
+ build_client_side_hash(model, attribute, options.dup)
8
+ end
5
9
 
6
- def client_side_hash(model, attribute, force = nil)
7
- build_client_side_hash(model, attribute, self.options.dup)
8
- end
10
+ def copy_conditional_attributes(to, from)
11
+ [:if, :unless].each { |key| to[key] = from[key] if from[key].present? }
12
+ end
9
13
 
10
- def copy_conditional_attributes(to, from)
11
- [:if, :unless].each { |key| to[key] = from[key] if from[key].present? }
12
- end
14
+ private
13
15
 
14
- private
16
+ def build_client_side_hash(model, attribute, options)
17
+ { message: model.errors.generate_message(attribute, message_type, options) }.merge(options.except(*::ActiveModel::Errors::CALLBACKS_OPTIONS - [:allow_blank, :if, :unless]))
18
+ end
15
19
 
16
- def build_client_side_hash(model, attribute, options)
17
- { :message => model.errors.generate_message(attribute, message_type, options) }.merge(options.except(*::ActiveModel::Errors::CALLBACKS_OPTIONS - [:allow_blank, :if, :unless]))
20
+ def message_type
21
+ kind
22
+ end
18
23
  end
19
24
 
20
- def message_type
21
- kind
22
- end
23
- end
25
+ module Validations
26
+ def client_side_validation_hash(force = nil)
27
+ _validators.inject({}) do |attr_hash, attr|
28
+ return attr_hash if [nil, :block].include?(attr[0])
24
29
 
25
- module Validations
26
- def client_side_validation_hash(force = nil)
27
- _validators.inject({}) do |attr_hash, attr|
28
- unless [nil, :block].include?(attr[0])
30
+ validator_hash = attr[1].each_with_object(Hash.new { |h, k| h[k] = [] }) do |validator, kind_hash|
31
+ next unless can_use_for_client_side_validation?(attr[0], validator, force)
29
32
 
30
- validator_hash = attr[1].inject(Hash.new { |h,k| h[k] = []}) do |kind_hash, validator|
31
- if can_use_for_client_side_validation?(attr[0], validator, force)
32
- if client_side_hash = validator.client_side_hash(self, attr[0], extract_force_option(attr[0], force))
33
- kind_hash[validator.kind] << client_side_hash.except(:on, :if, :unless)
34
- end
33
+ client_side_hash = validator.client_side_hash(self, attr[0], extract_force_option(attr[0], force))
34
+ if client_side_hash
35
+ kind_hash[validator.kind] << client_side_hash.except(:on, :if, :unless)
35
36
  end
36
-
37
- kind_hash
38
37
  end
39
38
 
40
39
  if validator_hash.present?
@@ -42,92 +41,109 @@ module ClientSideValidations::ActiveModel
42
41
  else
43
42
  attr_hash
44
43
  end
45
- else
46
- attr_hash
47
44
  end
48
45
  end
49
- end
50
46
 
51
- private
47
+ private
52
48
 
53
- def extract_force_option(attr, force)
54
- case force
55
- when FalseClass, TrueClass, NilClass
56
- force
57
- when Hash
58
- extract_force_option(nil, force[attr])
59
- else
60
- nil
49
+ def extract_force_option(attr, force)
50
+ case force
51
+ when FalseClass, TrueClass, NilClass
52
+ force
53
+ when Hash
54
+ extract_force_option(nil, force[attr])
55
+ end
61
56
  end
62
- end
63
57
 
64
- def can_use_for_client_side_validation?(attr, validator, force)
65
- if validator_turned_off?(attr, validator, force)
66
- result = false
67
- else
58
+ def can_use_for_client_side_validation?(attr, validator, force)
59
+ return false if validator_turned_off?(attr, validator, force)
60
+
68
61
  # Yeah yeah, #new_record? is not part of ActiveModel :p
69
62
  result = ((self.respond_to?(:new_record?) && validator.options[:on] == (self.new_record? ? :create : :update)) || validator.options[:on].nil?)
70
- result = result && validator.kind != :block
63
+ result &&= validator.kind != :block
71
64
 
72
65
  if validator.options[:if] || validator.options[:unless]
73
66
  if validator.options[:if] && validator.options[:if] =~ /changed\?/
74
67
  result = true
75
- else result = can_force_validator?(attr, validator, force)
68
+ else
69
+ result = can_force_validator?(attr, validator, force)
76
70
  if validator.options[:if]
77
- result = result && run_conditional(validator.options[:if])
71
+ result &&= run_conditional(validator.options[:if])
78
72
  end
79
73
  if validator.options[:unless]
80
- result = result && !run_conditional(validator.options[:unless])
74
+ result &&= !run_conditional(validator.options[:unless])
81
75
  end
82
76
  end
83
77
  end
84
- end
85
78
 
86
- result
87
- end
79
+ result
80
+ end
88
81
 
89
- def run_conditional(method_name_value_or_proc)
90
- if method_name_value_or_proc.respond_to?(:call)
91
- method_name_value_or_proc.call(self)
92
- else
93
- self.send(method_name_value_or_proc)
82
+ def run_conditional(method_name_value_or_proc)
83
+ if method_name_value_or_proc.respond_to?(:call)
84
+ method_name_value_or_proc.call self
85
+ else
86
+ send method_name_value_or_proc
87
+ end
94
88
  end
95
- end
96
89
 
97
- def validator_turned_off?(attr, validator, force)
98
- return true if ::ClientSideValidations::Config.disabled_validators.include?(validator.kind)
99
- case force
100
- when FalseClass
101
- true
102
- when Hash
103
- case force[attr]
90
+ def validator_turned_off?(attr, validator, force)
91
+ case force
104
92
  when FalseClass
105
93
  true
106
94
  when Hash
107
- force[attr][validator.kind] == false
95
+ case force[attr]
96
+ when FalseClass
97
+ true
98
+ when Hash
99
+ force[attr][validator.kind] == false
100
+ else
101
+ false
102
+ end
108
103
  else
109
- false
104
+ ::ClientSideValidations::Config.disabled_validators.include?(validator.kind)
110
105
  end
111
- else
112
- false
113
106
  end
114
- end
115
107
 
116
- def can_force_validator?(attr, validator, force)
117
- case force
118
- when TrueClass
119
- true
120
- when Hash
121
- case force[attr]
108
+ def can_force_validator?(attr, validator, force)
109
+ case force
122
110
  when TrueClass
123
111
  true
124
112
  when Hash
125
- force[attr][validator.kind]
113
+ case force[attr]
114
+ when TrueClass
115
+ true
116
+ when Hash
117
+ force[attr][validator.kind]
118
+ else
119
+ false
120
+ end
126
121
  else
127
122
  false
128
123
  end
129
- else
130
- false
124
+ end
125
+ end
126
+
127
+ module EnumerableValidator
128
+ def client_side_hash(model, attribute, force = nil)
129
+ options = self.options.dup
130
+ if options[:in].respond_to?(:call)
131
+ if force
132
+ options[:in] = options[:in].call(model)
133
+ hash = build_client_side_hash(model, attribute, options)
134
+ else
135
+ return
136
+ end
137
+ else
138
+ hash = build_client_side_hash(model, attribute, options)
139
+ end
140
+
141
+ if hash[:in].is_a?(Range)
142
+ hash[:range] = hash[:in]
143
+ hash.delete(:in)
144
+ end
145
+
146
+ hash
131
147
  end
132
148
  end
133
149
  end
@@ -136,9 +152,8 @@ end
136
152
  ActiveModel::Validator.send(:include, ClientSideValidations::ActiveModel::Validator)
137
153
  ActiveModel::Validations.send(:include, ClientSideValidations::ActiveModel::Validations)
138
154
 
139
- %w{acceptance exclusion inclusion length format numericality presence}.each do |validator|
155
+ %w(absence acceptance exclusion inclusion length format numericality presence).each do |validator|
140
156
  require "client_side_validations/active_model/#{validator}"
141
157
  validator.capitalize!
142
- eval "ActiveModel::Validations::#{validator}Validator.send(:include, ClientSideValidations::ActiveModel::#{validator})"
158
+ ActiveModel::Validations.const_get("#{validator}Validator").send :include, ClientSideValidations::ActiveModel.const_get(validator)
143
159
  end
144
-
@@ -0,0 +1,11 @@
1
+ module ClientSideValidations
2
+ module ActiveModel
3
+ module Absence
4
+ private
5
+
6
+ def message_type
7
+ :present
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,10 +1,11 @@
1
- module ClientSideValidations::ActiveModel
2
- module Acceptance
3
- private
1
+ module ClientSideValidations
2
+ module ActiveModel
3
+ module Acceptance
4
+ private
4
5
 
5
- def message_type
6
- :accepted
6
+ def message_type
7
+ :accepted
8
+ end
7
9
  end
8
10
  end
9
11
  end
10
-
@@ -1,27 +1,7 @@
1
- module ClientSideValidations::ActiveModel
2
- module Exclusion
3
-
4
- def client_side_hash(model, attribute, force = nil)
5
- if options[:in].respond_to?(:call)
6
- if force
7
- options = self.options.dup
8
- options[:in] = options[:in].call(model)
9
- hash = build_client_side_hash(model, attribute, options)
10
- else
11
- return
12
- end
13
- else
14
- hash = build_client_side_hash(model, attribute, self.options.dup)
15
- end
16
-
17
- if hash[:in].is_a?(Range)
18
- hash[:range] = hash[:in]
19
- hash.delete(:in)
20
- end
21
-
22
- hash
1
+ module ClientSideValidations
2
+ module ActiveModel
3
+ module Exclusion
4
+ include EnumerableValidator
23
5
  end
24
-
25
6
  end
26
7
  end
27
-
@@ -1,31 +1,32 @@
1
- module ClientSideValidations::ActiveModel
2
- module Format
3
- def client_side_hash(model, attribute, force = nil)
4
- options = self.options.dup
5
- if options[:with].respond_to?(:call)
6
- if force
7
- options[:with] = options[:with].call(model)
8
- build_client_side_hash(model, attribute, options)
1
+ module ClientSideValidations
2
+ module ActiveModel
3
+ module Format
4
+ def client_side_hash(model, attribute, force = nil)
5
+ options = self.options.dup
6
+ if options[:with].respond_to?(:call)
7
+ if force
8
+ options[:with] = options[:with].call(model)
9
+ build_client_side_hash(model, attribute, options)
10
+ else
11
+ return
12
+ end
13
+ elsif options[:without].respond_to?(:call)
14
+ if force
15
+ options[:without] = options[:without].call(model)
16
+ build_client_side_hash(model, attribute, options)
17
+ else
18
+ return
19
+ end
9
20
  else
10
- return
21
+ super
11
22
  end
12
- elsif options[:without].respond_to?(:call)
13
- if force
14
- options[:without] = options[:without].call(model)
15
- build_client_side_hash(model, attribute, options)
16
- else
17
- return
18
- end
19
- else
20
- super
21
23
  end
22
- end
23
24
 
24
- private
25
+ private
25
26
 
26
- def message_type
27
- :invalid
27
+ def message_type
28
+ :invalid
29
+ end
28
30
  end
29
31
  end
30
32
  end
31
-
@@ -1,26 +1,7 @@
1
- module ClientSideValidations::ActiveModel
2
- module Inclusion
3
-
4
- def client_side_hash(model, attribute, force = nil)
5
- if options[:in].respond_to?(:call)
6
- if force
7
- options = self.options.dup
8
- options[:in] = options[:in].call(model)
9
- hash = build_client_side_hash(model, attribute, options)
10
- else
11
- return
12
- end
13
- else
14
- hash = build_client_side_hash(model, attribute, self.options.dup)
15
- end
16
-
17
- if hash[:in].is_a?(Range)
18
- hash[:range] = hash[:in]
19
- hash.delete(:in)
20
- end
21
- hash
1
+ module ClientSideValidations
2
+ module ActiveModel
3
+ module Inclusion
4
+ include EnumerableValidator
22
5
  end
23
-
24
6
  end
25
7
  end
26
-
@@ -1,26 +1,26 @@
1
- module ClientSideValidations::ActiveModel
2
- module Length
1
+ module ClientSideValidations
2
+ module ActiveModel
3
+ module Length
4
+ def client_side_hash(model, attribute, _force = nil)
5
+ options = self.options.dup
6
+ hash = { messages: {} }
7
+ hash[:js_tokenizer] = options[:js_tokenizer] if options[:js_tokenizer]
8
+ hash[:allow_blank] = true if options[:allow_blank]
3
9
 
4
- def client_side_hash(model, attribute, force = nil)
5
- options = self.options.dup
6
- hash = { :messages => {} }
7
- hash[:js_tokenizer] = options[:js_tokenizer] if options[:js_tokenizer]
8
- hash[:allow_blank] = true if options[:allow_blank]
10
+ self.class::MESSAGES.each do |option, message_type|
11
+ count = options[option]
12
+ next unless count
9
13
 
10
- self.class::MESSAGES.each do |option, message_type|
11
- if count = options[option]
12
14
  options[:message] = options[message_type] if options[message_type].present?
13
15
  options.delete(:message) if options[:message].nil?
14
- hash[:messages][option] = model.errors.generate_message(attribute, message_type, options.merge(:count => count))
16
+ hash[:messages][option] = model.errors.generate_message(attribute, message_type, options.merge(count: count))
15
17
  hash[option] = count
16
18
  end
17
- end
18
19
 
19
- copy_conditional_attributes(hash, options)
20
+ copy_conditional_attributes(hash, options)
20
21
 
21
- hash
22
+ hash
23
+ end
22
24
  end
23
-
24
25
  end
25
26
  end
26
-