rails4_client_side_validations 0.0.4 → 4.2.0
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 +12 -7
- data/lib/client_side_validations.rb +12 -0
- data/lib/client_side_validations/action_view.rb +13 -0
- data/lib/client_side_validations/action_view/form_builder.rb +105 -0
- data/lib/{rails4_client_side_validations → client_side_validations}/action_view/form_helper.rb +13 -17
- data/lib/client_side_validations/action_view/form_tag_helper.rb +11 -0
- data/lib/{rails4_client_side_validations → client_side_validations}/active_model.rb +31 -9
- data/lib/{rails4_client_side_validations → client_side_validations}/active_model/absence.rb +1 -2
- data/lib/{rails4_client_side_validations → client_side_validations}/active_model/acceptance.rb +1 -2
- data/lib/client_side_validations/active_model/exclusion.rb +7 -0
- data/lib/{rails4_client_side_validations → client_side_validations}/active_model/format.rb +1 -2
- data/lib/client_side_validations/active_model/inclusion.rb +7 -0
- data/lib/{rails4_client_side_validations → client_side_validations}/active_model/length.rb +3 -4
- data/lib/{rails4_client_side_validations → client_side_validations}/active_model/numericality.rb +3 -4
- data/lib/{rails4_client_side_validations → client_side_validations}/active_model/presence.rb +1 -2
- data/lib/client_side_validations/active_record.rb +12 -0
- data/lib/{rails4_client_side_validations → client_side_validations}/active_record/middleware.rb +10 -6
- data/lib/{rails4_client_side_validations → client_side_validations}/active_record/uniqueness.rb +8 -6
- data/lib/{rails4_client_side_validations → client_side_validations}/config.rb +1 -1
- data/lib/client_side_validations/core_ext.rb +3 -0
- data/lib/{rails4_client_side_validations → client_side_validations}/core_ext/range.rb +0 -1
- data/lib/client_side_validations/core_ext/regexp.rb +25 -0
- data/lib/client_side_validations/engine.rb +5 -0
- data/lib/{rails4_client_side_validations → client_side_validations}/files.rb +2 -2
- data/lib/{rails4_client_side_validations → client_side_validations}/generators.rb +2 -3
- data/lib/client_side_validations/generators/rails_validations.rb +14 -0
- data/lib/{rails4_client_side_validations → client_side_validations}/middleware.rb +61 -16
- data/lib/client_side_validations/version.rb +3 -0
- data/lib/generators/{rails4_client_side_validations → client_side_validations}/copy_assets_generator.rb +3 -5
- data/lib/generators/client_side_validations/install_generator.rb +21 -0
- data/lib/generators/templates/{rails4_client_side_validations → client_side_validations}/initializer.rb +4 -4
- data/vendor/assets/javascripts/rails.validations.js +111 -98
- metadata +141 -81
- data/lib/generators/rails4_client_side_validations/install_generator.rb +0 -22
- data/lib/rails4_client_side_validations.rb +0 -13
- data/lib/rails4_client_side_validations/action_view.rb +0 -14
- data/lib/rails4_client_side_validations/action_view/form_builder.rb +0 -105
- data/lib/rails4_client_side_validations/action_view/form_tag_helper.rb +0 -12
- data/lib/rails4_client_side_validations/active_model/exclusion.rb +0 -27
- data/lib/rails4_client_side_validations/active_model/inclusion.rb +0 -26
- data/lib/rails4_client_side_validations/active_record.rb +0 -12
- data/lib/rails4_client_side_validations/core_ext.rb +0 -3
- data/lib/rails4_client_side_validations/core_ext/regexp.rb +0 -13
- data/lib/rails4_client_side_validations/engine.rb +0 -6
- data/lib/rails4_client_side_validations/generators/rails_validations.rb +0 -15
- data/lib/rails4_client_side_validations/version.rb +0 -3
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'client_side_validations/active_model'
|
2
|
+
require 'client_side_validations/middleware'
|
3
|
+
require 'client_side_validations/active_record/middleware'
|
4
|
+
|
5
|
+
%w{uniqueness}.each do |validator|
|
6
|
+
require "client_side_validations/active_record/#{validator}"
|
7
|
+
validator.capitalize!
|
8
|
+
eval "ActiveRecord::Validations::#{validator}Validator.send(:include, ClientSideValidations::ActiveRecord::#{validator})"
|
9
|
+
end
|
10
|
+
|
11
|
+
ActiveRecord::Base.send(:include, ClientSideValidations::ActiveModel::Validations)
|
12
|
+
ClientSideValidations::Middleware::Uniqueness.register_orm(ClientSideValidations::ActiveRecord::Middleware)
|
data/lib/{rails4_client_side_validations → client_side_validations}/active_record/middleware.rb
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module ClientSideValidations::ActiveRecord
|
2
2
|
class Middleware
|
3
3
|
|
4
4
|
def self.is_class?(klass)
|
@@ -7,9 +7,9 @@ module Rails4ClientSideValidations::ActiveRecord
|
|
7
7
|
|
8
8
|
def self.is_unique?(klass, attribute, value, params)
|
9
9
|
klass = find_topmost_superclass(klass)
|
10
|
-
value = type_cast_value(klass, attribute, value)
|
11
10
|
column = klass.columns_hash[attribute.to_s]
|
12
|
-
value = column
|
11
|
+
value = type_cast_value(column, value)
|
12
|
+
value = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s if value.is_a?(String)
|
13
13
|
|
14
14
|
t = klass.arel_table
|
15
15
|
|
@@ -30,7 +30,7 @@ module Rails4ClientSideValidations::ActiveRecord
|
|
30
30
|
end
|
31
31
|
|
32
32
|
(params[:scope] || {}).each do |attribute, value|
|
33
|
-
value
|
33
|
+
value = type_cast_value(klass.columns_hash[attribute], value)
|
34
34
|
if relation.is_a?(Arel::Nodes::SqlLiteral)
|
35
35
|
relation = Arel::Nodes::SqlLiteral.new("#{relation} AND #{t[attribute].eq(value).to_sql}")
|
36
36
|
else
|
@@ -43,8 +43,12 @@ module Rails4ClientSideValidations::ActiveRecord
|
|
43
43
|
|
44
44
|
private
|
45
45
|
|
46
|
-
def self.type_cast_value(
|
47
|
-
|
46
|
+
def self.type_cast_value(column, value)
|
47
|
+
if column.respond_to?(:type_cast)
|
48
|
+
column.type_cast(value)
|
49
|
+
else
|
50
|
+
column.type_cast_from_database(value)
|
51
|
+
end
|
48
52
|
end
|
49
53
|
|
50
54
|
def self.find_topmost_superclass(klass)
|
data/lib/{rails4_client_side_validations → client_side_validations}/active_record/uniqueness.rb
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module ClientSideValidations::ActiveRecord
|
2
2
|
module Uniqueness
|
3
3
|
def client_side_hash(model, attribute, force = nil)
|
4
4
|
hash = {}
|
@@ -6,16 +6,19 @@ module Rails4ClientSideValidations::ActiveRecord
|
|
6
6
|
hash[:case_sensitive] = options[:case_sensitive]
|
7
7
|
hash[:id] = model.id unless model.new_record?
|
8
8
|
hash[:allow_blank] = true if options[:allow_blank]
|
9
|
+
|
10
|
+
if options.key?(:client_validations) && options[:client_validations].key?(:class)
|
11
|
+
hash[:class] = options[:client_validations][:class].underscore
|
12
|
+
elsif model.class.name.demodulize != model.class.name
|
13
|
+
hash[:class] = model.class.name.underscore
|
14
|
+
end
|
15
|
+
|
9
16
|
if options.key?(:scope) && options[:scope].present?
|
10
17
|
hash[:scope] = Array.wrap(options[:scope]).inject({}) do |scope_hash, scope_item|
|
11
18
|
scope_hash.merge!(scope_item => model.send(scope_item))
|
12
19
|
end
|
13
20
|
end
|
14
21
|
|
15
|
-
unless model.class.name.demodulize == model.class.name
|
16
|
-
hash[:class] = model.class.name.underscore
|
17
|
-
end
|
18
|
-
|
19
22
|
hash
|
20
23
|
end
|
21
24
|
|
@@ -26,4 +29,3 @@ module Rails4ClientSideValidations::ActiveRecord
|
|
26
29
|
end
|
27
30
|
end
|
28
31
|
end
|
29
|
-
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Regexp
|
2
|
+
def as_json(options = nil)
|
3
|
+
str = inspect
|
4
|
+
.sub('\\A' , '^')
|
5
|
+
.sub('\\Z' , '$')
|
6
|
+
.sub('\\z' , '$')
|
7
|
+
.sub(/^\// , '')
|
8
|
+
.sub(/\/[a-z]*$/ , '')
|
9
|
+
.gsub(/\(\?#.+\)/ , '')
|
10
|
+
.gsub(/\(\?-\w+:/ , '(')
|
11
|
+
.gsub(/\s/ , '')
|
12
|
+
opts = []
|
13
|
+
opts << 'i' if (self.options & Regexp::IGNORECASE) > 0
|
14
|
+
opts << 'm' if (self.options & Regexp::MULTILINE) > 0
|
15
|
+
{ source: Regexp.new(str).source, options: opts.join }
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_json(options = nil)
|
19
|
+
as_json(options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def encode_json(encoder)
|
23
|
+
inspect
|
24
|
+
end
|
25
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# This is only used by dependant libraries that need to find the files
|
2
2
|
|
3
|
-
module
|
3
|
+
module ClientSideValidations
|
4
4
|
module Files
|
5
|
-
Initializer = File.expand_path(File.dirname(__FILE__) + '/../generators/templates/
|
5
|
+
Initializer = File.expand_path(File.dirname(__FILE__) + '/../generators/templates/client_side_validations/initializer.rb')
|
6
6
|
Javascript = File.expand_path(File.dirname(__FILE__) + '/../../vendor/assets/javascripts/rails.validations.js')
|
7
7
|
end
|
8
8
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module ClientSideValidations
|
2
2
|
module Generators
|
3
3
|
Assets = []
|
4
4
|
|
@@ -8,5 +8,4 @@ module Rails4ClientSideValidations
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
require '
|
12
|
-
|
11
|
+
require 'client_side_validations/generators/rails_validations'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ClientSideValidations
|
2
|
+
module Generators
|
3
|
+
class RailsValidations
|
4
|
+
def self.assets
|
5
|
+
[{
|
6
|
+
path: File.expand_path('../../../../vendor/assets/javascripts', __FILE__),
|
7
|
+
file: 'rails.validations.js'
|
8
|
+
}]
|
9
|
+
end
|
10
|
+
|
11
|
+
Generators.register_assets(self)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'client_side_validations/core_ext'
|
4
4
|
|
5
|
-
module
|
5
|
+
module ClientSideValidations
|
6
6
|
|
7
7
|
module Middleware
|
8
8
|
class Validators
|
@@ -11,16 +11,32 @@ module Rails4ClientSideValidations
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
14
|
-
if matches =
|
15
|
-
|
16
|
-
[500, {'Content-Type' => 'application/json', 'Content-Length' => '0'}, ['']]
|
17
|
-
else
|
18
|
-
"::Rails4ClientSideValidations::Middleware::#{matches[1].camelize}".constantize.new(env).response
|
19
|
-
end
|
14
|
+
if matches = /\A\/validators\/(\w+)\z/.match(env['PATH_INFO'])
|
15
|
+
process_request(matches.captures.first, env)
|
20
16
|
else
|
21
17
|
@app.call(env)
|
22
18
|
end
|
23
19
|
end
|
20
|
+
|
21
|
+
def process_request(validation, env)
|
22
|
+
if disabled_validators.include?(validation)
|
23
|
+
error_resp
|
24
|
+
else
|
25
|
+
klass_name = validation.camelize
|
26
|
+
klass_name = "::ClientSideValidations::Middleware::#{klass_name}"
|
27
|
+
klass_name.constantize.new(env).response
|
28
|
+
end
|
29
|
+
rescue => e
|
30
|
+
error_resp
|
31
|
+
end
|
32
|
+
|
33
|
+
def disabled_validators
|
34
|
+
ClientSideValidations::Config.disabled_validators.map(&:to_s)
|
35
|
+
end
|
36
|
+
|
37
|
+
def error_resp
|
38
|
+
[500, {'Content-Type' => 'application/json', 'Content-Length' => '0'}, ['']]
|
39
|
+
end
|
24
40
|
end
|
25
41
|
|
26
42
|
class Base
|
@@ -80,11 +96,8 @@ module Rails4ClientSideValidations
|
|
80
96
|
|
81
97
|
def is_unique?
|
82
98
|
convert_scope_value_from_null_to_nil
|
83
|
-
|
84
|
-
|
85
|
-
attribute = request.params[resource].keys.first
|
86
|
-
value = request.params[resource][attribute]
|
87
|
-
middleware_class = nil
|
99
|
+
klass, attribute, value = extract_resources
|
100
|
+
middleware_class = nil
|
88
101
|
|
89
102
|
unless Array.wrap(klass._validators[attribute.to_sym]).find { |v| v.kind == :uniqueness }
|
90
103
|
raise NotValidatable
|
@@ -110,11 +123,43 @@ module Rails4ClientSideValidations
|
|
110
123
|
end
|
111
124
|
end
|
112
125
|
|
113
|
-
def
|
126
|
+
def extract_resources
|
114
127
|
parent_key = (request.params.keys - IGNORE_PARAMS).first
|
128
|
+
|
129
|
+
if nested?(request.params[parent_key], 1)
|
130
|
+
klass, attribute, value = uproot(request.params[parent_key])
|
131
|
+
klass = klass.classify.constantize
|
132
|
+
else
|
133
|
+
klass = parent_key.classify.constantize
|
134
|
+
attribute = request.params[parent_key].keys.first
|
135
|
+
value = request.params[parent_key][attribute]
|
136
|
+
end
|
137
|
+
|
138
|
+
[klass, attribute, value]
|
139
|
+
end
|
140
|
+
|
141
|
+
def uproot(nested_hash = nil)
|
142
|
+
uproot_helper(nested_hash)[-3..-1]
|
143
|
+
end
|
144
|
+
|
145
|
+
def uproot_helper(nested_hash = nil, keys = [])
|
146
|
+
if nested_hash.respond_to?(:keys)
|
147
|
+
keys << nested_hash.keys.first
|
148
|
+
uproot_helper(nested_hash[nested_hash.keys.first], keys)
|
149
|
+
else
|
150
|
+
keys << nested_hash
|
151
|
+
end
|
115
152
|
end
|
153
|
+
|
154
|
+
def nested?(hash = nil, levels = 0)
|
155
|
+
i = 0
|
156
|
+
until !(hash.respond_to? :keys)
|
157
|
+
hash = hash[hash.keys.first]
|
158
|
+
i += 1
|
159
|
+
end
|
160
|
+
i > levels
|
161
|
+
end
|
162
|
+
|
116
163
|
end
|
117
164
|
end
|
118
|
-
|
119
165
|
end
|
120
|
-
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module ClientSideValidations
|
2
2
|
module Generators
|
3
3
|
class CopyAssetsGenerator < Rails::Generators::Base
|
4
4
|
|
@@ -38,9 +38,8 @@ module Rails4ClientSideValidations
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.asset_pipeline_enabled?
|
41
|
-
|
42
|
-
|
43
|
-
end
|
41
|
+
# Rails 4.1 doesn't provide :enabled in asset configuration, so we look for Sprockets
|
42
|
+
defined?(Sprockets).present?
|
44
43
|
end
|
45
44
|
|
46
45
|
def asset_pipeline_enabled?
|
@@ -55,4 +54,3 @@ module Rails4ClientSideValidations
|
|
55
54
|
end
|
56
55
|
end
|
57
56
|
end
|
58
|
-
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'generators/client_side_validations/copy_assets_generator'
|
2
|
+
|
3
|
+
module ClientSideValidations
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < CopyAssetsGenerator
|
6
|
+
|
7
|
+
def copy_initializer
|
8
|
+
source_paths << File.expand_path('../../templates/client_side_validations', __FILE__)
|
9
|
+
copy_file 'initializer.rb', 'config/initializers/client_side_validations.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def self.installation_message
|
15
|
+
"Copies initializer into config/initializers and #{super.downcase}"
|
16
|
+
end
|
17
|
+
|
18
|
+
desc installation_message
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -6,10 +6,11 @@
|
|
6
6
|
# Uncomment to validate number format with current I18n locale
|
7
7
|
# ClientSideValidations::Config.number_format_with_locale = true
|
8
8
|
|
9
|
-
# Uncomment to set a custom application scope
|
10
|
-
# ClientSideValidations::Config.root_path = '/your/application/scope'
|
11
|
-
|
12
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
|
+
#
|
13
14
|
# ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
|
14
15
|
# unless html_tag =~ /^<label/
|
15
16
|
# %{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first}</label></div>}.html_safe
|
@@ -17,4 +18,3 @@
|
|
17
18
|
# %{<div class="field_with_errors">#{html_tag}</div>}.html_safe
|
18
19
|
# end
|
19
20
|
# end
|
20
|
-
|
@@ -4,31 +4,31 @@
|
|
4
4
|
|
5
5
|
$ = jQuery;
|
6
6
|
|
7
|
-
$.fn.
|
8
|
-
|
7
|
+
$.fn.disableClientSideValidations = function() {
|
8
|
+
ClientSideValidations.disable(this);
|
9
9
|
return this;
|
10
10
|
};
|
11
11
|
|
12
|
-
$.fn.
|
13
|
-
this.filter(
|
14
|
-
return
|
12
|
+
$.fn.enableClientSideValidations = function() {
|
13
|
+
this.filter(ClientSideValidations.selectors.forms).each(function() {
|
14
|
+
return ClientSideValidations.enablers.form(this);
|
15
15
|
});
|
16
|
-
this.filter(
|
17
|
-
return
|
16
|
+
this.filter(ClientSideValidations.selectors.inputs).each(function() {
|
17
|
+
return ClientSideValidations.enablers.input(this);
|
18
18
|
});
|
19
19
|
return this;
|
20
20
|
};
|
21
21
|
|
22
|
-
$.fn.
|
23
|
-
this.filter(
|
24
|
-
return
|
22
|
+
$.fn.resetClientSideValidations = function() {
|
23
|
+
this.filter(ClientSideValidations.selectors.forms).each(function() {
|
24
|
+
return ClientSideValidations.reset(this);
|
25
25
|
});
|
26
26
|
return this;
|
27
27
|
};
|
28
28
|
|
29
29
|
$.fn.validate = function() {
|
30
|
-
this.filter(
|
31
|
-
return $(this).
|
30
|
+
this.filter(ClientSideValidations.selectors.forms).each(function() {
|
31
|
+
return $(this).enableClientSideValidations();
|
32
32
|
});
|
33
33
|
return this;
|
34
34
|
};
|
@@ -44,41 +44,49 @@
|
|
44
44
|
};
|
45
45
|
|
46
46
|
validatorsFor = function(name, validators) {
|
47
|
-
|
47
|
+
var captures, validator, validator_name;
|
48
|
+
if (captures = name.match(/\[(\w+_attributes)\].*\[(\w+)\]$/)) {
|
49
|
+
for (validator_name in validators) {
|
50
|
+
validator = validators[validator_name];
|
51
|
+
if (validator_name.match("\\[" + captures[1] + "\\].*\\[\\]\\[" + captures[2] + "\\]$")) {
|
52
|
+
name = name.replace(/\[[\da-z_]+\]\[(\w+)\]$/g, "[][$1]");
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
48
56
|
return validators[name] || {};
|
49
57
|
};
|
50
58
|
|
51
59
|
validateForm = function(form, validators) {
|
52
60
|
var valid;
|
53
|
-
form.trigger('form:validate:before.
|
61
|
+
form.trigger('form:validate:before.ClientSideValidations');
|
54
62
|
valid = true;
|
55
|
-
form.find(
|
63
|
+
form.find(ClientSideValidations.selectors.validate_inputs).each(function() {
|
56
64
|
if (!$(this).isValid(validators)) {
|
57
65
|
valid = false;
|
58
66
|
}
|
59
67
|
return true;
|
60
68
|
});
|
61
69
|
if (valid) {
|
62
|
-
form.trigger('form:validate:pass.
|
70
|
+
form.trigger('form:validate:pass.ClientSideValidations');
|
63
71
|
} else {
|
64
|
-
form.trigger('form:validate:fail.
|
72
|
+
form.trigger('form:validate:fail.ClientSideValidations');
|
65
73
|
}
|
66
|
-
form.trigger('form:validate:after.
|
74
|
+
form.trigger('form:validate:after.ClientSideValidations');
|
67
75
|
return valid;
|
68
76
|
};
|
69
77
|
|
70
78
|
validateElement = function(element, validators) {
|
71
79
|
var afterValidate, destroyInputName, executeValidators, failElement, local, passElement, remote;
|
72
|
-
element.trigger('element:validate:before.
|
80
|
+
element.trigger('element:validate:before.ClientSideValidations');
|
73
81
|
passElement = function() {
|
74
|
-
return element.trigger('element:validate:pass.
|
82
|
+
return element.trigger('element:validate:pass.ClientSideValidations').data('valid', null);
|
75
83
|
};
|
76
84
|
failElement = function(message) {
|
77
|
-
element.trigger('element:validate:fail.
|
85
|
+
element.trigger('element:validate:fail.ClientSideValidations', message).data('valid', false);
|
78
86
|
return false;
|
79
87
|
};
|
80
88
|
afterValidate = function() {
|
81
|
-
return element.trigger('element:validate:after.
|
89
|
+
return element.trigger('element:validate:after.ClientSideValidations').data('valid') !== false;
|
82
90
|
};
|
83
91
|
executeValidators = function(context) {
|
84
92
|
var fn, kind, message, valid, validator, _i, _len, _ref;
|
@@ -110,44 +118,44 @@
|
|
110
118
|
return afterValidate();
|
111
119
|
}
|
112
120
|
element.data('changed', false);
|
113
|
-
local =
|
114
|
-
remote =
|
121
|
+
local = ClientSideValidations.validators.local;
|
122
|
+
remote = ClientSideValidations.validators.remote;
|
115
123
|
if (executeValidators(local) && executeValidators(remote)) {
|
116
124
|
passElement();
|
117
125
|
}
|
118
126
|
return afterValidate();
|
119
127
|
};
|
120
128
|
|
121
|
-
if (window.
|
122
|
-
window.
|
129
|
+
if (window.ClientSideValidations === void 0) {
|
130
|
+
window.ClientSideValidations = {};
|
123
131
|
}
|
124
132
|
|
125
|
-
if (window.
|
126
|
-
window.
|
133
|
+
if (window.ClientSideValidations.forms === void 0) {
|
134
|
+
window.ClientSideValidations.forms = {};
|
127
135
|
}
|
128
136
|
|
129
|
-
window.
|
137
|
+
window.ClientSideValidations.selectors = {
|
130
138
|
inputs: ':input:not(button):not([type="submit"])[name]:visible:enabled',
|
131
139
|
validate_inputs: ':input:enabled:visible[data-validate]',
|
132
140
|
forms: 'form[data-validate]'
|
133
141
|
};
|
134
142
|
|
135
|
-
window.
|
143
|
+
window.ClientSideValidations.reset = function(form) {
|
136
144
|
var $form, key;
|
137
145
|
$form = $(form);
|
138
|
-
|
139
|
-
for (key in form.
|
140
|
-
form.
|
146
|
+
ClientSideValidations.disable(form);
|
147
|
+
for (key in form.ClientSideValidations.settings.validators) {
|
148
|
+
form.ClientSideValidations.removeError($form.find("[name='" + key + "']"));
|
141
149
|
}
|
142
|
-
return
|
150
|
+
return ClientSideValidations.enablers.form(form);
|
143
151
|
};
|
144
152
|
|
145
|
-
window.
|
153
|
+
window.ClientSideValidations.disable = function(target) {
|
146
154
|
var $target;
|
147
155
|
$target = $(target);
|
148
|
-
$target.off('.
|
156
|
+
$target.off('.ClientSideValidations');
|
149
157
|
if ($target.is('form')) {
|
150
|
-
return
|
158
|
+
return ClientSideValidations.disable($target.find(':input'));
|
151
159
|
} else {
|
152
160
|
$target.removeData('valid');
|
153
161
|
$target.removeData('changed');
|
@@ -157,50 +165,50 @@
|
|
157
165
|
}
|
158
166
|
};
|
159
167
|
|
160
|
-
window.
|
168
|
+
window.ClientSideValidations.enablers = {
|
161
169
|
form: function(form) {
|
162
170
|
var $form, binding, event, _ref;
|
163
171
|
$form = $(form);
|
164
|
-
form.
|
165
|
-
settings: window.
|
172
|
+
form.ClientSideValidations = {
|
173
|
+
settings: window.ClientSideValidations.forms[$form.attr('id')],
|
166
174
|
addError: function(element, message) {
|
167
|
-
return
|
175
|
+
return ClientSideValidations.formBuilders[form.ClientSideValidations.settings.type].add(element, form.ClientSideValidations.settings, message);
|
168
176
|
},
|
169
177
|
removeError: function(element) {
|
170
|
-
return
|
178
|
+
return ClientSideValidations.formBuilders[form.ClientSideValidations.settings.type].remove(element, form.ClientSideValidations.settings);
|
171
179
|
}
|
172
180
|
};
|
173
181
|
_ref = {
|
174
|
-
'submit.
|
175
|
-
if (!$form.isValid(form.
|
182
|
+
'submit.ClientSideValidations': function(eventData) {
|
183
|
+
if (!$form.isValid(form.ClientSideValidations.settings.validators)) {
|
176
184
|
eventData.preventDefault();
|
177
185
|
return eventData.stopImmediatePropagation();
|
178
186
|
}
|
179
187
|
},
|
180
|
-
'ajax:beforeSend.
|
188
|
+
'ajax:beforeSend.ClientSideValidations': function(eventData) {
|
181
189
|
if (eventData.target === this) {
|
182
|
-
return $form.isValid(form.
|
190
|
+
return $form.isValid(form.ClientSideValidations.settings.validators);
|
183
191
|
}
|
184
192
|
},
|
185
|
-
'form:validate:after.
|
186
|
-
return
|
193
|
+
'form:validate:after.ClientSideValidations': function(eventData) {
|
194
|
+
return ClientSideValidations.callbacks.form.after($form, eventData);
|
187
195
|
},
|
188
|
-
'form:validate:before.
|
189
|
-
return
|
196
|
+
'form:validate:before.ClientSideValidations': function(eventData) {
|
197
|
+
return ClientSideValidations.callbacks.form.before($form, eventData);
|
190
198
|
},
|
191
|
-
'form:validate:fail.
|
192
|
-
return
|
199
|
+
'form:validate:fail.ClientSideValidations': function(eventData) {
|
200
|
+
return ClientSideValidations.callbacks.form.fail($form, eventData);
|
193
201
|
},
|
194
|
-
'form:validate:pass.
|
195
|
-
return
|
202
|
+
'form:validate:pass.ClientSideValidations': function(eventData) {
|
203
|
+
return ClientSideValidations.callbacks.form.pass($form, eventData);
|
196
204
|
}
|
197
205
|
};
|
198
206
|
for (event in _ref) {
|
199
207
|
binding = _ref[event];
|
200
208
|
$form.on(event, binding);
|
201
209
|
}
|
202
|
-
return $form.find(
|
203
|
-
return
|
210
|
+
return $form.find(ClientSideValidations.selectors.inputs).each(function() {
|
211
|
+
return ClientSideValidations.enablers.input(this);
|
204
212
|
});
|
205
213
|
},
|
206
214
|
input: function(input) {
|
@@ -209,30 +217,30 @@
|
|
209
217
|
form = input.form;
|
210
218
|
$form = $(form);
|
211
219
|
_ref = {
|
212
|
-
'focusout.
|
213
|
-
return $(this).isValid(form.
|
220
|
+
'focusout.ClientSideValidations': function() {
|
221
|
+
return $(this).isValid(form.ClientSideValidations.settings.validators);
|
214
222
|
},
|
215
|
-
'change.
|
223
|
+
'change.ClientSideValidations': function() {
|
216
224
|
return $(this).data('changed', true);
|
217
225
|
},
|
218
|
-
'element:validate:after.
|
219
|
-
return
|
226
|
+
'element:validate:after.ClientSideValidations': function(eventData) {
|
227
|
+
return ClientSideValidations.callbacks.element.after($(this), eventData);
|
220
228
|
},
|
221
|
-
'element:validate:before.
|
222
|
-
return
|
229
|
+
'element:validate:before.ClientSideValidations': function(eventData) {
|
230
|
+
return ClientSideValidations.callbacks.element.before($(this), eventData);
|
223
231
|
},
|
224
|
-
'element:validate:fail.
|
232
|
+
'element:validate:fail.ClientSideValidations': function(eventData, message) {
|
225
233
|
var element;
|
226
234
|
element = $(this);
|
227
|
-
return
|
228
|
-
return form.
|
235
|
+
return ClientSideValidations.callbacks.element.fail(element, message, function() {
|
236
|
+
return form.ClientSideValidations.addError(element, message);
|
229
237
|
}, eventData);
|
230
238
|
},
|
231
|
-
'element:validate:pass.
|
239
|
+
'element:validate:pass.ClientSideValidations': function(eventData) {
|
232
240
|
var element;
|
233
241
|
element = $(this);
|
234
|
-
return
|
235
|
-
return form.
|
242
|
+
return ClientSideValidations.callbacks.element.pass(element, function() {
|
243
|
+
return form.ClientSideValidations.removeError(element);
|
236
244
|
}, eventData);
|
237
245
|
}
|
238
246
|
};
|
@@ -242,8 +250,8 @@
|
|
242
250
|
return $(this).attr('data-validate', true);
|
243
251
|
}).on(event, binding);
|
244
252
|
}
|
245
|
-
$input.filter(':checkbox').on('change.
|
246
|
-
return $(this).isValid(form.
|
253
|
+
$input.filter(':checkbox').on('change.ClientSideValidations', function() {
|
254
|
+
return $(this).isValid(form.ClientSideValidations.settings.validators);
|
247
255
|
});
|
248
256
|
return $input.filter('[id$=_confirmation]').each(function() {
|
249
257
|
var confirmationElement, element, _ref1, _results;
|
@@ -251,11 +259,11 @@
|
|
251
259
|
element = $form.find("#" + (this.id.match(/(.+)_confirmation/)[1]) + ":input");
|
252
260
|
if (element[0]) {
|
253
261
|
_ref1 = {
|
254
|
-
'focusout.
|
255
|
-
return element.data('changed', true).isValid(form.
|
262
|
+
'focusout.ClientSideValidations': function() {
|
263
|
+
return element.data('changed', true).isValid(form.ClientSideValidations.settings.validators);
|
256
264
|
},
|
257
|
-
'keyup.
|
258
|
-
return element.data('changed', true).isValid(form.
|
265
|
+
'keyup.ClientSideValidations': function() {
|
266
|
+
return element.data('changed', true).isValid(form.ClientSideValidations.settings.validators);
|
259
267
|
}
|
260
268
|
};
|
261
269
|
_results = [];
|
@@ -269,9 +277,9 @@
|
|
269
277
|
}
|
270
278
|
};
|
271
279
|
|
272
|
-
window.
|
280
|
+
window.ClientSideValidations.validators = {
|
273
281
|
all: function() {
|
274
|
-
return jQuery.extend({},
|
282
|
+
return jQuery.extend({}, ClientSideValidations.validators.local, ClientSideValidations.validators.remote);
|
275
283
|
},
|
276
284
|
local: {
|
277
285
|
absence: function(element, options) {
|
@@ -307,17 +315,17 @@
|
|
307
315
|
}
|
308
316
|
return message;
|
309
317
|
}
|
310
|
-
if (options["with"] && !options["with"].test(element.val())) {
|
318
|
+
if (options["with"] && !new RegExp(options["with"].source, options["with"].options).test(element.val())) {
|
311
319
|
return options.message;
|
312
320
|
}
|
313
|
-
if (options.without && options.without.test(element.val())) {
|
321
|
+
if (options.without && !new RegExp(options.without.source, options.without.options).test(element.val())) {
|
314
322
|
return options.message;
|
315
323
|
}
|
316
324
|
},
|
317
325
|
numericality: function(element, options) {
|
318
326
|
var CHECKS, check, check_value, fn, form, operator, val;
|
319
327
|
val = jQuery.trim(element.val());
|
320
|
-
if (!
|
328
|
+
if (!ClientSideValidations.patterns.numericality.test(val)) {
|
321
329
|
if (options.allow_blank === true && this.presence(element, {
|
322
330
|
message: options.messages.numericality
|
323
331
|
})) {
|
@@ -325,6 +333,7 @@
|
|
325
333
|
}
|
326
334
|
return options.messages.numericality;
|
327
335
|
}
|
336
|
+
val = val.replace(new RegExp("\\" + ClientSideValidations.number_format.delimiter, 'g'), "").replace(new RegExp("\\" + ClientSideValidations.number_format.separator, 'g'), ".");
|
328
337
|
if (options.only_integer && !/^[+-]?\d+$/.test(val)) {
|
329
338
|
return options.messages.only_integer;
|
330
339
|
}
|
@@ -348,7 +357,6 @@
|
|
348
357
|
} else {
|
349
358
|
return;
|
350
359
|
}
|
351
|
-
val = val.replace(new RegExp("\\" + Rails4ClientSideValidations.number_format.delimiter, 'g'), "").replace(new RegExp("\\" + Rails4ClientSideValidations.number_format.separator, 'g'), ".");
|
352
360
|
fn = new Function("return " + val + " " + operator + " " + check_value);
|
353
361
|
if (!fn()) {
|
354
362
|
return options.messages[check];
|
@@ -492,7 +500,7 @@
|
|
492
500
|
remote: {
|
493
501
|
uniqueness: function(element, options) {
|
494
502
|
var data, key, message, name, scope_value, scoped_element, scoped_name, _ref;
|
495
|
-
message =
|
503
|
+
message = ClientSideValidations.validators.local.presence(element, options);
|
496
504
|
if (message) {
|
497
505
|
if (options.allow_blank === true) {
|
498
506
|
return;
|
@@ -519,8 +527,8 @@
|
|
519
527
|
if (scoped_element[0] && scoped_element.val() !== scope_value) {
|
520
528
|
data.scope[key] = scoped_element.val();
|
521
529
|
scoped_element.unbind("change." + element.id).bind("change." + element.id, function() {
|
522
|
-
element.trigger('change.
|
523
|
-
return element.trigger('focusout.
|
530
|
+
element.trigger('change.ClientSideValidations');
|
531
|
+
return element.trigger('focusout.ClientSideValidations');
|
524
532
|
});
|
525
533
|
} else {
|
526
534
|
data.scope[key] = scope_value;
|
@@ -537,11 +545,8 @@
|
|
537
545
|
name = options['class'] + '[' + name.split('[')[1];
|
538
546
|
}
|
539
547
|
data[name] = element.val();
|
540
|
-
if (Rails4ClientSideValidations.remote_validators_prefix == null) {
|
541
|
-
Rails4ClientSideValidations.remote_validators_prefix = "";
|
542
|
-
}
|
543
548
|
if (jQuery.ajax({
|
544
|
-
url:
|
549
|
+
url: ClientSideValidations.remote_validators_url_for('uniqueness'),
|
545
550
|
data: data,
|
546
551
|
async: false,
|
547
552
|
cache: false
|
@@ -552,17 +557,25 @@
|
|
552
557
|
}
|
553
558
|
};
|
554
559
|
|
555
|
-
window.
|
560
|
+
window.ClientSideValidations.remote_validators_url_for = function(validator) {
|
561
|
+
if (ClientSideValidations.remote_validators_prefix != null) {
|
562
|
+
return "//" + window.location.host + "/" + ClientSideValidations.remote_validators_prefix + "/validators/" + validator;
|
563
|
+
} else {
|
564
|
+
return "//" + window.location.host + "/validators/" + validator;
|
565
|
+
}
|
566
|
+
};
|
567
|
+
|
568
|
+
window.ClientSideValidations.disableValidators = function() {
|
556
569
|
var func, validator, _ref, _results;
|
557
|
-
if (window.
|
570
|
+
if (window.ClientSideValidations.disabled_validators === void 0) {
|
558
571
|
return;
|
559
572
|
}
|
560
|
-
_ref = window.
|
573
|
+
_ref = window.ClientSideValidations.validators.remote;
|
561
574
|
_results = [];
|
562
575
|
for (validator in _ref) {
|
563
576
|
func = _ref[validator];
|
564
|
-
if (window.
|
565
|
-
_results.push(delete window.
|
577
|
+
if (__indexOf.call(window.ClientSideValidations.disabled_validators, validator) >= 0) {
|
578
|
+
_results.push(delete window.ClientSideValidations.validators.remote[validator]);
|
566
579
|
} else {
|
567
580
|
_results.push(void 0);
|
568
581
|
}
|
@@ -570,7 +583,7 @@
|
|
570
583
|
return _results;
|
571
584
|
};
|
572
585
|
|
573
|
-
window.
|
586
|
+
window.ClientSideValidations.formBuilders = {
|
574
587
|
'ActionView::Helpers::FormBuilder': {
|
575
588
|
add: function(element, settings, message) {
|
576
589
|
var form, inputErrorField, label, labelErrorField;
|
@@ -608,11 +621,11 @@
|
|
608
621
|
}
|
609
622
|
};
|
610
623
|
|
611
|
-
window.
|
624
|
+
window.ClientSideValidations.patterns = {
|
612
625
|
numericality: /^(-|\+)?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d*)?$/
|
613
626
|
};
|
614
627
|
|
615
|
-
window.
|
628
|
+
window.ClientSideValidations.callbacks = {
|
616
629
|
element: {
|
617
630
|
after: function(element, eventData) {},
|
618
631
|
before: function(element, eventData) {},
|
@@ -632,8 +645,8 @@
|
|
632
645
|
};
|
633
646
|
|
634
647
|
$(function() {
|
635
|
-
|
636
|
-
return $(
|
648
|
+
ClientSideValidations.disableValidators();
|
649
|
+
return $(ClientSideValidations.selectors.forms).validate();
|
637
650
|
});
|
638
651
|
|
639
652
|
}).call(this);
|