client_side_validations 2.2.2 → 2.3.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.
- data/README.markdown +5 -3
- data/javascript/lib/client_side_validations.js +22 -19
- data/lib/client_side_validations.rb +40 -46
- data/lib/client_side_validations/adapters/action_view.rb +78 -14
- data/lib/client_side_validations/adapters/active_model.rb +2 -0
- data/lib/client_side_validations/adapters/active_record_2.rb +4 -0
- metadata +4 -4
data/README.markdown
CHANGED
@@ -17,6 +17,7 @@ Currently the following validations are supported:
|
|
17
17
|
* validates_numericality_of
|
18
18
|
* validates_length_of
|
19
19
|
* validates_uniqueness_of
|
20
|
+
* validates_confirmation_of
|
20
21
|
|
21
22
|
The uniqueness validation works for both ActiveRecord and Mongoid.
|
22
23
|
|
@@ -43,9 +44,10 @@ This will copy client_side_validations.js to "public/javascripts"
|
|
43
44
|
Currently only [jquery.validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) is supported so you will need to download [jQuery](http://docs.jquery.com/Downloading_jQuery) and the jQuery Validate plugin to "public/javascripts"
|
44
45
|
|
45
46
|
### Rack
|
46
|
-
|
47
|
+
If you want to validate_uniqueness_of a call to the server must be made. You can do this by simply drop in the ClidenSideValidations Rack middleware.
|
48
|
+
|
49
|
+
The following route will be reserved for client side validations:
|
47
50
|
|
48
|
-
/validations.json
|
49
51
|
/validations/uniqueness.json
|
50
52
|
|
51
53
|
Add the middleware to your stack:
|
@@ -55,7 +57,7 @@ config/environment.rb for Rails 2.x
|
|
55
57
|
config/application.rb for Rails 3.x
|
56
58
|
|
57
59
|
...
|
58
|
-
config.middleware.use 'ClientSideValidations'
|
60
|
+
config.middleware.use 'ClientSideValidations::Uniqueness'
|
59
61
|
...
|
60
62
|
|
61
63
|
### Model
|
@@ -6,29 +6,28 @@ if (typeof(jQuery) != "undefined") {
|
|
6
6
|
|
7
7
|
$.extend($.fn, {
|
8
8
|
clientSideValidations: function() {
|
9
|
-
var form
|
10
|
-
var object
|
11
|
-
var
|
12
|
-
var
|
13
|
-
var
|
14
|
-
var object_id = null;
|
15
|
-
if (edit_pattern.test(id)) {
|
16
|
-
object_id = Number(edit_pattern.exec(id)[1]);
|
17
|
-
}
|
18
|
-
var adapter = 'jquery.validate';
|
9
|
+
var form = this;
|
10
|
+
var object = form.attr('object-csv');
|
11
|
+
var id = form[0].id;
|
12
|
+
var object_id = null;
|
13
|
+
var adapter = 'jquery.validate';
|
19
14
|
if (/new/.test(id)) {
|
20
15
|
id = /new_(\w+)/.exec(id)[1]
|
21
16
|
} else if (/edit/.test(id)) {
|
22
|
-
id
|
17
|
+
id = /edit_(\w+)_\d+/.exec(id)[1]
|
18
|
+
object_id = /edit_\w+_(\d+)/.exec(id)[1]
|
19
|
+
}
|
20
|
+
if (eval("typeof(" + object + "_validation_options)") != "undefined") {
|
21
|
+
var options = eval(object + '_validation_options');
|
22
|
+
} else {
|
23
|
+
var options = { }
|
23
24
|
}
|
24
|
-
var client
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
});
|
31
|
-
});
|
25
|
+
var client = new ClientSideValidations(id, adapter, object_id)
|
26
|
+
var rules = eval(object + '_validation_rules');
|
27
|
+
var validations = client.adaptValidations(rules);
|
28
|
+
options['rules'] = validations.rules;
|
29
|
+
options['messages'] = validations.messages;
|
30
|
+
form.validate(options);
|
32
31
|
}
|
33
32
|
});
|
34
33
|
|
@@ -84,6 +83,10 @@ ClientSideValidations = function(id, adapter, object_id) {
|
|
84
83
|
}
|
85
84
|
}
|
86
85
|
break;
|
86
|
+
case 'confirmation':
|
87
|
+
rule = 'equalTo';
|
88
|
+
value = "[name='" + this.id + "[" + attr + "_confirmation]" + "']";
|
89
|
+
break;
|
87
90
|
|
88
91
|
default:
|
89
92
|
}
|
@@ -2,63 +2,57 @@ require 'rubygems'
|
|
2
2
|
require 'json'
|
3
3
|
require 'cgi'
|
4
4
|
|
5
|
-
|
6
|
-
def
|
7
|
-
@
|
5
|
+
module ClientSideValidations
|
6
|
+
def self.default_options=(options)
|
7
|
+
@default_options = options
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
|
12
|
-
# We need to override this
|
13
|
-
params = {}.merge!(CGI::parse(env['QUERY_STRING']))
|
14
|
-
case env['PATH_INFO']
|
15
|
-
when %r{^/validations.json}
|
16
|
-
body = get_validations(params['model'][0])
|
17
|
-
[200, {'Content-Type' => 'application/json', 'Content-Length' => "#{body.length}"}, body]
|
18
|
-
when %r{^/validations/uniqueness.json}
|
19
|
-
field = params.keys.first
|
20
|
-
resource, attribute = field.split(/[^\w]/)
|
21
|
-
value = params[field][0]
|
22
|
-
# Because params returns an array for each field value we want to always grab
|
23
|
-
# the first element of the array for id, even if it is nil
|
24
|
-
id = [params["#{resource}[id]"]].flatten.first
|
25
|
-
body = is_unique?(resource, attribute, value, id).to_s
|
26
|
-
[200, {'Content-Type' => 'application/json', 'Content-Length' => "#{body.length}"}, body]
|
27
|
-
else
|
28
|
-
@app.call(env)
|
29
|
-
end
|
10
|
+
def self.default_options
|
11
|
+
@default_options
|
30
12
|
end
|
31
13
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
14
|
+
class Uniqueness
|
15
|
+
def initialize(app)
|
16
|
+
@app = app
|
17
|
+
end
|
37
18
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
19
|
+
def call(env)
|
20
|
+
# By default CGI::parse will instantize a hash that defaults nil elements to [].
|
21
|
+
# We need to override this
|
22
|
+
case env['PATH_INFO']
|
23
|
+
when %r{^/validations/uniqueness.json}
|
24
|
+
params = {}.merge!(CGI::parse(env['QUERY_STRING']))
|
25
|
+
field = params.keys.first
|
26
|
+
resource, attribute = field.split(/[^\w]/)
|
27
|
+
value = params[field][0]
|
28
|
+
# Because params returns an array for each field value we want to always grab
|
29
|
+
# the first element of the array for id, even if it is nil
|
30
|
+
id = [params["#{resource}[id]"]].flatten.first
|
31
|
+
body = is_unique?(resource, attribute, value, id).to_s
|
32
|
+
[200, {'Content-Type' => 'application/json', 'Content-Length' => "#{body.length}"}, body]
|
33
|
+
else
|
34
|
+
@app.call(env)
|
48
35
|
end
|
49
36
|
end
|
50
|
-
|
51
|
-
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def is_unique?(resource, attribute, value, id = nil)
|
41
|
+
klass = constantize_resource(resource)
|
42
|
+
instance = nil
|
52
43
|
instance = klass.send("find_by_#{attribute}", value)
|
53
|
-
end
|
54
44
|
|
55
|
-
|
56
|
-
|
45
|
+
if instance
|
46
|
+
return instance.id.to_i == id.to_i
|
47
|
+
else
|
48
|
+
return true
|
49
|
+
end
|
50
|
+
end
|
57
51
|
|
58
|
-
|
59
|
-
|
52
|
+
def constantize_resource(resource)
|
53
|
+
eval(resource.split('_').map{ |word| word.capitalize}.join)
|
54
|
+
end
|
60
55
|
end
|
61
|
-
|
62
56
|
end
|
63
57
|
|
64
58
|
require 'client_side_validations/orm'
|
@@ -10,34 +10,98 @@ module DNCLabs
|
|
10
10
|
define_method(:form_for) do |record_or_name_or_array, *args, &proc|
|
11
11
|
options = args.extract_options!
|
12
12
|
options.symbolize_keys!
|
13
|
+
script = ""
|
13
14
|
if validations = options.delete(:validations)
|
14
15
|
unless options.key?(:html)
|
15
16
|
options[:html] = {}
|
16
17
|
end
|
17
|
-
|
18
|
-
unless validations == true
|
19
|
-
object = validations.to_s.underscore
|
20
|
-
else
|
21
|
-
case record_or_name_or_array
|
22
|
-
when String, Symbol
|
23
|
-
object = record_or_name_or_array.to_s
|
24
|
-
else
|
25
|
-
object = record_or_name_or_array.class.to_s.underscore
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
18
|
+
object, rules, csv_options = csv_get_variables(validations, record_or_name_or_array)
|
29
19
|
options[:html]['object-csv'] = object
|
20
|
+
csv_rules = %{var #{object}_validation_rules=#{rules};}
|
21
|
+
script = %{<script type='text/javascript'>#{csv_rules}#{csv_options}</script>}
|
30
22
|
end
|
31
23
|
args << options
|
32
|
-
form_method.bind(self).call(record_or_name_or_array, *args, &proc)
|
24
|
+
result = form_method.bind(self).call(record_or_name_or_array, *args, &proc)
|
25
|
+
|
26
|
+
if rails3?
|
27
|
+
result += script.html_safe
|
28
|
+
else
|
29
|
+
concat(script)
|
30
|
+
end
|
31
|
+
result
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
36
|
+
private
|
37
|
+
|
38
|
+
def rails3?
|
39
|
+
version=
|
40
|
+
if defined?(ActionPack::VERSION::MAJOR)
|
41
|
+
ActionPack::VERSION::MAJOR
|
42
|
+
end
|
43
|
+
!version.blank? && version >= 3
|
44
|
+
end
|
45
|
+
|
46
|
+
def csv_get_variables(validations, record_or_name_or_array)
|
47
|
+
csv_options = ::ClientSideValidations.default_options || { }
|
48
|
+
case validations
|
49
|
+
when true
|
50
|
+
object, rules = csv_get_object_and_validation_rules(record_or_name_or_array)
|
51
|
+
when Hash
|
52
|
+
validations.symbolize_keys!
|
53
|
+
if validations.has_key?(:instance)
|
54
|
+
object = validations[:instance].class.to_s.underscore
|
55
|
+
rules = validations[:instance].validations_to_json
|
56
|
+
elsif validations.has_key?(:class)
|
57
|
+
object = validations[:instance].to_s.underscore
|
58
|
+
rules = validations[:instance].new.validations_to_json
|
59
|
+
else
|
60
|
+
object, rules = csv_get_object_and_validation_rules(record_or_name_or_array)
|
61
|
+
end
|
62
|
+
if validations.has_key?(:options)
|
63
|
+
csv_options.merge!(validations[:options])
|
64
|
+
end
|
65
|
+
else
|
66
|
+
object = validations.to_s.underscore
|
67
|
+
rules = validations.new.validations_to_json
|
68
|
+
end
|
69
|
+
|
70
|
+
if csv_options.empty?
|
71
|
+
csv_options = ""
|
72
|
+
else
|
73
|
+
csv_options = %{var #{object}_validation_options=#{convert_csv_options_to_json(csv_options)};}
|
74
|
+
end
|
75
|
+
|
76
|
+
[object, rules, csv_options]
|
77
|
+
end
|
78
|
+
|
79
|
+
def convert_csv_options_to_json(csv_options)
|
80
|
+
json = []
|
81
|
+
csv_options.each do |k, v|
|
82
|
+
json << %{#{k}:#{v}}
|
83
|
+
end
|
84
|
+
%{{#{json.join(',')}}}
|
85
|
+
end
|
86
|
+
|
87
|
+
def csv_get_object_and_validation_rules(record_or_name_or_array)
|
88
|
+
case record_or_name_or_array
|
89
|
+
when String, Symbol
|
90
|
+
object = record_or_name_or_array.to_s
|
91
|
+
rules = object.camelize.constantize.new.validations_to_json
|
92
|
+
when Array
|
93
|
+
object, rules = csv_get_object_and_validation_rules(record_or_name_or_array.last)
|
94
|
+
else
|
95
|
+
object = record_or_name_or_array.class.to_s.underscore
|
96
|
+
rules = record_or_name_or_array.validations_to_json
|
97
|
+
end
|
98
|
+
|
99
|
+
[object, rules]
|
100
|
+
end
|
37
101
|
end # BaseMethods
|
38
102
|
|
39
103
|
module FormBuilderMethods
|
40
|
-
|
104
|
+
|
41
105
|
def client_side_validations(options = {})
|
42
106
|
@template.send(:client_side_validations, @object_name, objectify_options(options))
|
43
107
|
end
|
@@ -61,6 +61,8 @@ module DNCLabs
|
|
61
61
|
elsif defined?(Mongoid) && base.class.included_modules.include?(Mongoid::Document)
|
62
62
|
I18n.translate('errors.messages.taken', :locale => locale)
|
63
63
|
end
|
64
|
+
when :confirmation
|
65
|
+
I18n.translate('errors.messages.confirmation', :locale => locale)
|
64
66
|
end
|
65
67
|
|
66
68
|
message = validation.options[:message]
|
@@ -57,6 +57,8 @@ module DNCLabs
|
|
57
57
|
I18n.translate('activerecord.errors.messages.not_a_number', :locale => locale)
|
58
58
|
when 'validates_uniqueness_of'
|
59
59
|
I18n.translate('activerecord.errors.messages.taken', :locale => locale)
|
60
|
+
when 'validates_confirmation_of'
|
61
|
+
I18n.translate('activerecord.errors.messages.confirmation', :locale => locale)
|
60
62
|
end
|
61
63
|
|
62
64
|
message = validation.options[:message]
|
@@ -90,6 +92,8 @@ module DNCLabs
|
|
90
92
|
'length'
|
91
93
|
when 'validates_uniqueness_of'
|
92
94
|
'uniqueness'
|
95
|
+
when 'validates_confirmation_of'
|
96
|
+
'confirmation'
|
93
97
|
end
|
94
98
|
end
|
95
99
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 2
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 2.
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
version: 2.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Brian Cardarella
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-07-
|
17
|
+
date: 2010-07-09 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|