client_side_validations 3.2.5 → 4.2.12
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.
- checksums.yaml +4 -4
- data/README.md +558 -0
- data/lib/client_side_validations/action_view/form_builder.rb +102 -84
- data/lib/client_side_validations/action_view/form_helper.rb +106 -111
- data/lib/client_side_validations/action_view/form_tag_helper.rb +13 -9
- data/lib/client_side_validations/action_view.rb +4 -3
- data/lib/client_side_validations/active_model/absence.rb +11 -0
- data/lib/client_side_validations/active_model/acceptance.rb +7 -6
- data/lib/client_side_validations/active_model/conditionals.rb +41 -0
- data/lib/client_side_validations/active_model/exclusion.rb +4 -24
- data/lib/client_side_validations/active_model/format.rb +14 -19
- data/lib/client_side_validations/active_model/inclusion.rb +4 -23
- data/lib/client_side_validations/active_model/length.rb +15 -15
- data/lib/client_side_validations/active_model/numericality.rb +25 -27
- data/lib/client_side_validations/active_model/presence.rb +7 -6
- data/lib/client_side_validations/active_model.rb +90 -82
- data/lib/client_side_validations/active_record/middleware.rb +48 -42
- data/lib/client_side_validations/active_record/uniqueness.rb +25 -21
- data/lib/client_side_validations/active_record.rb +5 -6
- data/lib/client_side_validations/config.rb +1 -1
- data/lib/client_side_validations/core_ext/range.rb +1 -2
- data/lib/client_side_validations/core_ext/regexp.rb +6 -4
- data/lib/client_side_validations/engine.rb +0 -1
- data/lib/client_side_validations/generators/rails_validations.rb +2 -3
- data/lib/client_side_validations/generators.rb +6 -3
- data/lib/client_side_validations/middleware.rb +37 -28
- data/lib/client_side_validations/version.rb +2 -1
- data/lib/client_side_validations.rb +0 -1
- data/lib/generators/client_side_validations/copy_assets_generator.rb +21 -25
- data/lib/generators/client_side_validations/install_generator.rb +0 -4
- data/lib/generators/templates/client_side_validations/initializer.rb +5 -2
- data/vendor/assets/javascripts/rails.validations.js +120 -100
- metadata +175 -62
- data/client_side_validations.gemspec +0 -32
|
@@ -3,8 +3,8 @@ module ClientSideValidations
|
|
|
3
3
|
class RailsValidations
|
|
4
4
|
def self.assets
|
|
5
5
|
[{
|
|
6
|
-
:
|
|
7
|
-
:
|
|
6
|
+
path: File.expand_path('../../../../vendor/assets/javascripts', __FILE__),
|
|
7
|
+
file: 'rails.validations.js'
|
|
8
8
|
}]
|
|
9
9
|
end
|
|
10
10
|
|
|
@@ -12,4 +12,3 @@ module ClientSideValidations
|
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
|
-
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
module ClientSideValidations
|
|
2
2
|
module Generators
|
|
3
|
-
|
|
3
|
+
@@assets = []
|
|
4
4
|
|
|
5
5
|
def self.register_assets(klass)
|
|
6
|
-
|
|
6
|
+
@@assets.concat(klass.assets)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.assets
|
|
10
|
+
@@assets
|
|
7
11
|
end
|
|
8
12
|
end
|
|
9
13
|
end
|
|
10
14
|
|
|
11
15
|
require 'client_side_validations/generators/rails_validations'
|
|
12
|
-
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
1
|
require 'client_side_validations/core_ext'
|
|
4
2
|
|
|
5
3
|
module ClientSideValidations
|
|
6
|
-
|
|
7
4
|
module Middleware
|
|
8
5
|
class Validators
|
|
9
6
|
def initialize(app)
|
|
@@ -11,16 +8,33 @@ module ClientSideValidations
|
|
|
11
8
|
end
|
|
12
9
|
|
|
13
10
|
def call(env)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
else
|
|
18
|
-
"::ClientSideValidations::Middleware::#{matches[1].camelize}".constantize.new(env).response
|
|
19
|
-
end
|
|
11
|
+
matches = %r{\A/?#{ClientSideValidations::Config.root_path}/validators\/(\w+)\z}.match(env['PATH_INFO'])
|
|
12
|
+
if matches
|
|
13
|
+
process_request(matches.captures.first, env)
|
|
20
14
|
else
|
|
21
15
|
@app.call(env)
|
|
22
16
|
end
|
|
23
17
|
end
|
|
18
|
+
|
|
19
|
+
def process_request(validation, env)
|
|
20
|
+
if disabled_validators.include?(validation)
|
|
21
|
+
error_resp
|
|
22
|
+
else
|
|
23
|
+
klass_name = validation.camelize
|
|
24
|
+
klass_name = "::ClientSideValidations::Middleware::#{klass_name}"
|
|
25
|
+
klass_name.constantize.new(env).response
|
|
26
|
+
end
|
|
27
|
+
rescue
|
|
28
|
+
error_resp
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def disabled_validators
|
|
32
|
+
ClientSideValidations::Config.disabled_validators.map(&:to_s)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def error_resp
|
|
36
|
+
[500, { 'Content-Type' => 'application/json', 'Content-Length' => '0' }, ['']]
|
|
37
|
+
end
|
|
24
38
|
end
|
|
25
39
|
|
|
26
40
|
class Base
|
|
@@ -35,7 +49,7 @@ module ClientSideValidations
|
|
|
35
49
|
end
|
|
36
50
|
|
|
37
51
|
def response
|
|
38
|
-
[status, {'Content-Type' => content_type, 'Content-Length' => body.length.to_s}, [body]]
|
|
52
|
+
[status, { 'Content-Type' => content_type, 'Content-Length' => body.length.to_s }, [body]]
|
|
39
53
|
end
|
|
40
54
|
|
|
41
55
|
def content_type
|
|
@@ -44,13 +58,13 @@ module ClientSideValidations
|
|
|
44
58
|
end
|
|
45
59
|
|
|
46
60
|
class Uniqueness < Base
|
|
47
|
-
IGNORE_PARAMS = %w
|
|
48
|
-
|
|
61
|
+
IGNORE_PARAMS = %w(case_sensitive id scope).freeze
|
|
62
|
+
@@registered_orms = []
|
|
49
63
|
class NotValidatable < StandardError; end
|
|
50
64
|
|
|
51
65
|
def response
|
|
52
66
|
begin
|
|
53
|
-
if
|
|
67
|
+
if unique?
|
|
54
68
|
self.status = 404
|
|
55
69
|
self.body = 'true'
|
|
56
70
|
else
|
|
@@ -69,7 +83,7 @@ module ClientSideValidations
|
|
|
69
83
|
end
|
|
70
84
|
|
|
71
85
|
def self.registered_orms
|
|
72
|
-
|
|
86
|
+
@@registered_orms
|
|
73
87
|
end
|
|
74
88
|
|
|
75
89
|
def registered_orms
|
|
@@ -78,7 +92,7 @@ module ClientSideValidations
|
|
|
78
92
|
|
|
79
93
|
private
|
|
80
94
|
|
|
81
|
-
def
|
|
95
|
+
def unique?
|
|
82
96
|
convert_scope_value_from_null_to_nil
|
|
83
97
|
klass, attribute, value = extract_resources
|
|
84
98
|
middleware_class = nil
|
|
@@ -88,29 +102,26 @@ module ClientSideValidations
|
|
|
88
102
|
end
|
|
89
103
|
|
|
90
104
|
registered_orms.each do |orm|
|
|
91
|
-
if orm.
|
|
105
|
+
if orm.class?(klass)
|
|
92
106
|
middleware_class = orm
|
|
93
107
|
break
|
|
94
108
|
end
|
|
95
109
|
end
|
|
96
110
|
|
|
97
|
-
middleware_class.
|
|
111
|
+
middleware_class.unique?(klass, attribute, value, request.params)
|
|
98
112
|
end
|
|
99
113
|
|
|
100
114
|
def convert_scope_value_from_null_to_nil
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
request.params['scope'][key] = nil
|
|
105
|
-
end
|
|
106
|
-
end
|
|
115
|
+
return unless request.params['scope']
|
|
116
|
+
request.params['scope'].each do |key, value|
|
|
117
|
+
request.params['scope'][key] = nil if value == 'null'
|
|
107
118
|
end
|
|
108
119
|
end
|
|
109
120
|
|
|
110
121
|
def extract_resources
|
|
111
122
|
parent_key = (request.params.keys - IGNORE_PARAMS).first
|
|
112
|
-
|
|
113
|
-
if nested?(request.params[parent_key], 1)
|
|
123
|
+
|
|
124
|
+
if nested?(request.params[parent_key], 1)
|
|
114
125
|
klass, attribute, value = uproot(request.params[parent_key])
|
|
115
126
|
klass = klass.classify.constantize
|
|
116
127
|
else
|
|
@@ -137,14 +148,12 @@ module ClientSideValidations
|
|
|
137
148
|
|
|
138
149
|
def nested?(hash = nil, levels = 0)
|
|
139
150
|
i = 0
|
|
140
|
-
|
|
151
|
+
while hash.respond_to? :keys
|
|
141
152
|
hash = hash[hash.keys.first]
|
|
142
153
|
i += 1
|
|
143
154
|
end
|
|
144
155
|
i > levels
|
|
145
156
|
end
|
|
146
|
-
|
|
147
157
|
end
|
|
148
158
|
end
|
|
149
159
|
end
|
|
150
|
-
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
module ClientSideValidations
|
|
2
2
|
module Generators
|
|
3
3
|
class CopyAssetsGenerator < Rails::Generators::Base
|
|
4
|
-
|
|
5
4
|
def copy_javascript_asset
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
end
|
|
5
|
+
return unless self.class == CopyAssetsGenerator || !asset_pipeline_enabled?
|
|
6
|
+
assets.each do |asset|
|
|
7
|
+
source_paths << asset[:path]
|
|
8
|
+
copy_file asset[:file], "#{asset_directory}/#{asset[:file]}"
|
|
11
9
|
end
|
|
12
10
|
end
|
|
13
11
|
|
|
14
|
-
private
|
|
15
|
-
|
|
16
12
|
def self.asset_directory
|
|
17
13
|
if asset_pipeline_enabled?
|
|
18
14
|
"app#{Rails.configuration.assets.prefix}/javascripts"
|
|
@@ -21,16 +17,8 @@ module ClientSideValidations
|
|
|
21
17
|
end
|
|
22
18
|
end
|
|
23
19
|
|
|
24
|
-
def asset_directory
|
|
25
|
-
CopyAssetsGenerator.asset_directory
|
|
26
|
-
end
|
|
27
|
-
|
|
28
20
|
def self.assets
|
|
29
|
-
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def assets
|
|
33
|
-
CopyAssetsGenerator.assets
|
|
21
|
+
ClientSideValidations::Generators.assets
|
|
34
22
|
end
|
|
35
23
|
|
|
36
24
|
def self.asset_file_names
|
|
@@ -38,13 +26,8 @@ module ClientSideValidations
|
|
|
38
26
|
end
|
|
39
27
|
|
|
40
28
|
def self.asset_pipeline_enabled?
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def asset_pipeline_enabled?
|
|
47
|
-
self.class.asset_pipeline_enabled?
|
|
29
|
+
# Rails 4.1 doesn't provide :enabled in asset configuration, so we look for Sprockets
|
|
30
|
+
defined?(Sprockets).present?
|
|
48
31
|
end
|
|
49
32
|
|
|
50
33
|
def self.installation_message
|
|
@@ -52,7 +35,20 @@ module ClientSideValidations
|
|
|
52
35
|
end
|
|
53
36
|
|
|
54
37
|
desc installation_message
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def asset_directory
|
|
42
|
+
CopyAssetsGenerator.asset_directory
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def assets
|
|
46
|
+
CopyAssetsGenerator.assets
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def asset_pipeline_enabled?
|
|
50
|
+
self.class.asset_pipeline_enabled?
|
|
51
|
+
end
|
|
55
52
|
end
|
|
56
53
|
end
|
|
57
54
|
end
|
|
58
|
-
|
|
@@ -3,14 +3,11 @@ require 'generators/client_side_validations/copy_assets_generator'
|
|
|
3
3
|
module ClientSideValidations
|
|
4
4
|
module Generators
|
|
5
5
|
class InstallGenerator < CopyAssetsGenerator
|
|
6
|
-
|
|
7
6
|
def copy_initializer
|
|
8
7
|
source_paths << File.expand_path('../../templates/client_side_validations', __FILE__)
|
|
9
8
|
copy_file 'initializer.rb', 'config/initializers/client_side_validations.rb'
|
|
10
9
|
end
|
|
11
10
|
|
|
12
|
-
private
|
|
13
|
-
|
|
14
11
|
def self.installation_message
|
|
15
12
|
"Copies initializer into config/initializers and #{super.downcase}"
|
|
16
13
|
end
|
|
@@ -19,4 +16,3 @@ module ClientSideValidations
|
|
|
19
16
|
end
|
|
20
17
|
end
|
|
21
18
|
end
|
|
22
|
-
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# ClientSideValidations Initializer
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# Disabled validators. The uniqueness validator is disabled by default for security issues. Enable it on your own responsibility!
|
|
4
4
|
# ClientSideValidations::Config.disabled_validators = [:uniqueness]
|
|
5
5
|
|
|
6
6
|
# Uncomment to validate number format with current I18n locale
|
|
7
7
|
# ClientSideValidations::Config.number_format_with_locale = true
|
|
8
8
|
|
|
9
9
|
# Uncomment the following block if you want each input field to have the validation messages attached.
|
|
10
|
+
#
|
|
11
|
+
# Note: client_side_validation requires the error to be encapsulated within
|
|
12
|
+
# <label for="#{instance.send(:tag_id)}" class="message"></label>
|
|
13
|
+
#
|
|
10
14
|
# ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
|
|
11
15
|
# unless html_tag =~ /^<label/
|
|
12
16
|
# %{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first}</label></div>}.html_safe
|
|
@@ -14,4 +18,3 @@
|
|
|
14
18
|
# %{<div class="field_with_errors">#{html_tag}</div>}.html_safe
|
|
15
19
|
# end
|
|
16
20
|
# end
|
|
17
|
-
|