client_side_validations 2.2.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
- The following routes will be reserved for client side validations:
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 = this;
10
- var object = form.attr('object-csv');
11
- var edit_pattern = new RegExp('^edit_' + object + '_(.+)', 'i');
12
- var url = '/validations.json?model=' + object;
13
- var id = form[0].id;
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 = /edit_(\w+)_\d+/.exec(id)[1]
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 = new ClientSideValidations(id, adapter, object_id)
25
- $.getJSON(url, function(json) {
26
- var validations = client.adaptValidations(json);
27
- form.validate({
28
- rules: validations.rules,
29
- messages: validations.messages
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
- class ClientSideValidations
6
- def initialize(app)
7
- @app = app
5
+ module ClientSideValidations
6
+ def self.default_options=(options)
7
+ @default_options = options
8
8
  end
9
9
 
10
- def call(env)
11
- # By default CGI::parse will instantize a hash that defaults nil elements to [].
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
- private
33
-
34
- def get_validations(resource)
35
- constantize_resource(resource).new.validations_to_json
36
- end
14
+ class Uniqueness
15
+ def initialize(app)
16
+ @app = app
17
+ end
37
18
 
38
- def is_unique?(resource, attribute, value, id = nil)
39
- klass = constantize_resource(resource)
40
- instance = nil
41
- if id
42
- if instance = klass.find(id)
43
- if instance.send(attribute) == value
44
- return true
45
- else
46
- instance = nil
47
- end
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
- unless instance
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
- instance == nil
56
- end
45
+ if instance
46
+ return instance.id.to_i == id.to_i
47
+ else
48
+ return true
49
+ end
50
+ end
57
51
 
58
- def constantize_resource(resource)
59
- eval(resource.split('_').map{ |word| word.capitalize}.join)
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
- - 2
8
- - 2
9
- version: 2.2.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-07 00:00:00 -04:00
17
+ date: 2010-07-09 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency