client_side_validations 3.0.0 → 3.0.1

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.
Files changed (33) hide show
  1. data/javascript/rails.validations.js +27 -18
  2. data/lib/client_side_validations/action_view/form_builder.rb +11 -4
  3. data/lib/client_side_validations/action_view/form_helper.rb +15 -4
  4. data/lib/client_side_validations/active_model.rb +1 -1
  5. data/lib/client_side_validations/active_record/uniqueness.rb +4 -2
  6. data/lib/client_side_validations/formtastic.rb +1 -1
  7. data/lib/client_side_validations/mongoid/uniqueness.rb +4 -2
  8. data/lib/client_side_validations/simple_form.rb +1 -1
  9. data/lib/client_side_validations/version.rb +1 -1
  10. data/test/action_view/cases/helper.rb +6 -6
  11. data/test/action_view/cases/test_helpers.rb +51 -36
  12. data/test/active_model/cases/test_validations.rb +9 -0
  13. data/test/active_model/models/person.rb +5 -0
  14. data/test/active_record/cases/test_uniqueness_validator.rb +15 -1
  15. data/test/formtastic/cases/test_form_builder.rb +1 -1
  16. data/test/formtastic/cases/test_form_helper.rb +3 -3
  17. data/test/javascript/public/test/callbacks/elementAfter.js +3 -2
  18. data/test/javascript/public/test/callbacks/elementBefore.js +3 -2
  19. data/test/javascript/public/test/callbacks/elementFail.js +3 -2
  20. data/test/javascript/public/test/callbacks/elementPass.js +3 -2
  21. data/test/javascript/public/test/callbacks/formAfter.js +3 -2
  22. data/test/javascript/public/test/callbacks/formBefore.js +3 -2
  23. data/test/javascript/public/test/callbacks/formFail.js +3 -2
  24. data/test/javascript/public/test/callbacks/formPass.js +3 -2
  25. data/test/javascript/public/test/form_builders/validateForm.js +3 -2
  26. data/test/javascript/public/test/form_builders/validateFormtastic.js +5 -2
  27. data/test/javascript/public/test/form_builders/validateSimpleForm.js +5 -2
  28. data/test/javascript/public/test/validateElement.js +11 -5
  29. data/test/javascript/public/test/validators/uniqueness.js +3 -2
  30. data/test/mongoid/cases/test_uniqueness_validator.rb +14 -1
  31. data/test/simple_form/cases/test_form_builder.rb +1 -1
  32. data/test/simple_form/cases/test_form_helper.rb +2 -2
  33. metadata +2 -2
@@ -1,3 +1,12 @@
1
+ /*!
2
+ * Rails 3 Client Side Validations - v3.0.1
3
+ * https://github.com/bcardarlela/client_side_validations
4
+ *
5
+ * Copyright (c) 2011 Brian Cardarella
6
+ * Licensed under the MIT license
7
+ * http://www.opensource.org/licenses/mit-license.php
8
+ */
9
+
1
10
  (function($) {
2
11
  $.fn.validate = function() {
3
12
  return this.filter('form[data-validate]').each(function() {
@@ -6,8 +15,8 @@
6
15
 
7
16
  // Set up the events for the form
8
17
  form
9
- .submit(function() { return form.isValid(); })
10
- .bind('ajax:beforeSend', function() { return form.isValid(); })
18
+ .submit(function() { return form.isValid(settings.validators); })
19
+ .bind('ajax:beforeSend', function() { return form.isValid(settings.validators); })
11
20
  // Callbacks
12
21
  .bind('form:validate:after', function(eventData) { clientSideValidations.callbacks.form.after( form, eventData); })
13
22
  .bind('form:validate:before', function(eventData) { clientSideValidations.callbacks.form.before(form, eventData); })
@@ -15,8 +24,8 @@
15
24
  .bind('form:validate:pass', function(eventData) { clientSideValidations.callbacks.form.pass( form, eventData); })
16
25
 
17
26
  // Set up the events for each validatable form element
18
- .find('[data-validators]:input')
19
- .live('focusout', function() { $(this).isValid(); })
27
+ .find('[data-validate]:input')
28
+ .live('focusout', function() { $(this).isValid(settings.validators); })
20
29
  .live('change', function() { $(this).data('changed', true); })
21
30
  // Callbacks
22
31
  .live('element:validate:after', function(eventData) { clientSideValidations.callbacks.element.after( $(this), eventData); })
@@ -32,19 +41,19 @@
32
41
  removeError(element);
33
42
  }, eventData) })
34
43
  // Checkboxes - Live events don't support filter
35
- .end().find('[data-validators]:checkbox')
36
- .live('click', function() { $(this).isValid(); })
44
+ .end().find('[data-validate]:checkbox')
45
+ .live('click', function() { $(this).isValid(settings.validators); })
37
46
  // Inputs for confirmations
38
47
  .end().find('[id*=_confirmation]').each(function() {
39
48
  var confirmationElement = $(this),
40
- element = form.find('#' + this.id.match(/(.+)_confirmation/)[1] + '[data-validators]:input');
49
+ element = form.find('#' + this.id.match(/(.+)_confirmation/)[1] + '[data-validate]:input');
41
50
 
42
51
  $('#' + confirmationElement.attr('id'))
43
52
  .live('focusout', function() {
44
- element.data('changed', true).isValid();
53
+ element.data('changed', true).isValid(settings.validators);
45
54
  })
46
55
  .live('keyup', function() {
47
- element.data('changed', true).isValid();
56
+ element.data('changed', true).isValid(settings.validators);
48
57
  })
49
58
  });
50
59
 
@@ -58,19 +67,19 @@
58
67
  });
59
68
  }
60
69
 
61
- $.fn.isValid = function() {
70
+ $.fn.isValid = function(validators) {
62
71
  if ($(this[0]).is('form')) {
63
- return validateForm($(this[0]));
72
+ return validateForm($(this[0]), validators);
64
73
  } else {
65
- return validateElement($(this[0]));
74
+ return validateElement($(this[0]), validators[this[0].name]);
66
75
  }
67
76
  }
68
77
 
69
- var validateForm = function(form) {
78
+ var validateForm = function(form, validators) {
70
79
  var valid = true;
71
80
 
72
- form.trigger('form:validate:before').find('[data-validators]:input').each(function() {
73
- if (!validateElement($(this))) { valid = false; }
81
+ form.trigger('form:validate:before').find('[data-validate]:input').each(function() {
82
+ if (!$(this).isValid(validators)) { valid = false; }
74
83
  });
75
84
 
76
85
  if (valid) {
@@ -83,12 +92,11 @@
83
92
  return valid;
84
93
  }
85
94
 
86
- var validateElement = function(element) {
95
+ var validateElement = function(element, validators) {
87
96
  element.trigger('element:validate:before');
88
97
 
89
98
  if (element.data('changed') !== false) {
90
- var valid = true,
91
- validators = new Function("return " + element.attr('data-validators'))();
99
+ var valid = true;
92
100
  element.data('changed', false);
93
101
 
94
102
  // Because 'length' is defined on the list of validators we cannot call jQuery.each on
@@ -302,6 +310,7 @@ var clientSideValidations = {
302
310
  labelErrorField = jQuery(settings.label_tag),
303
311
  label = jQuery('label[for="' + element.attr('id') + '"]:not(.message)');
304
312
 
313
+ if (element.attr('autofocus')) { element.attr('autofocus', false) };
305
314
  element.before(inputErrorField);
306
315
  inputErrorField.find('span#input_tag').replaceWith(element);
307
316
  inputErrorField.find('label.message').attr('for', element.attr('id'));
@@ -15,11 +15,12 @@ module ClientSideValidations::ActionView::Helpers
15
15
  end
16
16
 
17
17
  base.class_eval do
18
- alias_method_chain :fields_for, :client_side_validations
19
- alias_method_chain :check_box, :client_side_validations
18
+ alias_method_chain :initialize, :client_side_validations
19
+ alias_method_chain :fields_for, :client_side_validations
20
+ alias_method_chain :check_box, :client_side_validations
20
21
  alias_method_chain :radio_button, :client_side_validations
21
22
 
22
- def self.client_side_form_js_hash(options, form_helper)
23
+ def self.client_side_form_settings(options, form_helper)
23
24
  {
24
25
  :type => self.to_s,
25
26
  :input_tag => form_helper.class.field_error_proc.call(%{<span id="input_tag" />}, Struct.new(:error_message, :tag_id).new([], "")),
@@ -29,6 +30,11 @@ module ClientSideValidations::ActionView::Helpers
29
30
  end
30
31
  end
31
32
 
33
+ def initialize_with_client_side_validations(object_name, object, template, options, proc)
34
+ initialize_without_client_side_validations(object_name, object, template, options, proc)
35
+ @options[:validators] = {}
36
+ end
37
+
32
38
  def fields_for_with_client_side_validations(record_or_name_or_array, *args, &block)
33
39
  options = args.extract_options!
34
40
  options[:validate] ||= @options[:validate] if @options[:validate] && !options.key?(:validate)
@@ -49,7 +55,8 @@ module ClientSideValidations::ActionView::Helpers
49
55
 
50
56
  def apply_client_side_validators(method, options = {})
51
57
  if @options[:validate] && options[:validate] != false && validators = @object.client_side_validation_hash[method]
52
- options.merge!("data-validators" => validators.to_json)
58
+ options.merge!("data-validate" => true)
59
+ @options[:validators].merge!("#{@object_name}[#{method}]" => validators)
53
60
  end
54
61
  end
55
62
 
@@ -21,8 +21,13 @@ module ClientSideValidations::ActionView::Helpers
21
21
  end
22
22
  end
23
23
 
24
- script_tag = client_side_form_js_variable(object, options)
25
- "#{super(record_or_name_or_array, *(args << options), &proc)}#{script_tag}".html_safe
24
+ @validators = {}
25
+ # Order matters here. Rails mutates the options object
26
+ script = client_side_form_settings(object, options)
27
+ form = super(record_or_name_or_array, *(args << options), &proc)
28
+ # Because of the load order requirement above this sub is necessary
29
+ # Would be nice to not do this
30
+ "#{form}#{script ? script.sub('"validator_hash"', @validators.to_json) : nil}".html_safe
26
31
  end
27
32
 
28
33
  def apply_form_for_options!(object_or_array, options)
@@ -30,9 +35,15 @@ module ClientSideValidations::ActionView::Helpers
30
35
  options[:html][:validate] = true if options[:validate]
31
36
  end
32
37
 
38
+ def fields_for(record_or_name_or_array, *args, &block)
39
+ output = super
40
+ @validators.merge!(args.last[:validators])
41
+ output
42
+ end
43
+
33
44
  private
34
45
 
35
- def client_side_form_js_variable(object, options)
46
+ def client_side_form_settings(object, options)
36
47
  if options[:validate]
37
48
  builder = options[:builder] || ActionView::Base.default_form_builder
38
49
 
@@ -47,7 +58,7 @@ module ClientSideValidations::ActionView::Helpers
47
58
  end
48
59
 
49
60
  content_tag(:script) do
50
- "var #{var_name} = #{builder.client_side_form_js_hash(options, self).to_json};".html_safe
61
+ "var #{var_name} = #{builder.client_side_form_settings(options, self).merge(:validators => 'validator_hash').to_json};".html_safe
51
62
  end
52
63
 
53
64
  end
@@ -17,7 +17,7 @@ module ClientSideValidations::ActiveModel
17
17
 
18
18
  module Validations
19
19
  def client_side_validation_hash
20
- _validators.inject({}) do |attr_hash, attr|
20
+ _validators.except(nil).inject({}) do |attr_hash, attr|
21
21
 
22
22
  validator_hash = attr[1].inject({}) do |kind_hash, validator|
23
23
  client_side_hash = validator.client_side_hash(self, attr[0])
@@ -5,10 +5,12 @@ module ClientSideValidations::ActiveRecord
5
5
  hash = { :message => model.errors.generate_message(attribute, message_type, extra_options.except(:case_sensitive, :scope)) }
6
6
  hash = hash.merge(extra_options).merge(model.new_record? ? {} : { :id => model.id })
7
7
 
8
- if hash[:scope]
9
- hash[:scope] = hash[:scope].inject({}) do |scope_hash, scope_item|
8
+ if hash[:scope].present?
9
+ hash[:scope] = Array.wrap(hash[:scope]).inject({}) do |scope_hash, scope_item|
10
10
  scope_hash.merge!(scope_item => model.send(scope_item))
11
11
  end
12
+ else
13
+ hash.delete(:scope)
12
14
  end
13
15
 
14
16
  hash
@@ -4,7 +4,7 @@ module ClientSideValidations
4
4
 
5
5
  def self.included(base)
6
6
  base.class_eval do
7
- def self.client_side_form_js_hash(options, form_helper)
7
+ def self.client_side_form_settings(options, form_helper)
8
8
  {
9
9
  :type => self.to_s,
10
10
  :inline_error_class => ::Formtastic::SemanticFormBuilder.default_inline_error_class
@@ -5,10 +5,12 @@ module ClientSideValidations::Mongoid
5
5
  hash = { :message => model.errors.generate_message(attribute, message_type, extra_options.except(:case_sensitive, :scope)) }
6
6
  hash = hash.merge(extra_options).merge(model.new_record? ? {} : { :id => model.id })
7
7
 
8
- if hash[:scope]
9
- hash[:scope] = hash[:scope].inject({}) do |scope_hash, scope_item|
8
+ if hash[:scope].present?
9
+ hash[:scope] = Array.wrap(hash[:scope]).inject({}) do |scope_hash, scope_item|
10
10
  scope_hash.merge!(scope_item => model.send(scope_item))
11
11
  end
12
+ else
13
+ hash.delete(:scope)
12
14
  end
13
15
 
14
16
  hash
@@ -4,7 +4,7 @@ module ClientSideValidations
4
4
 
5
5
  def self.included(base)
6
6
  base.class_eval do
7
- def self.client_side_form_js_hash(options, form_helper)
7
+ def self.client_side_form_settings(options, form_helper)
8
8
  {
9
9
  :type => self.to_s,
10
10
  :error_class => ::SimpleForm.error_class,
@@ -1,3 +1,3 @@
1
1
  module ClientSideValidations
2
- VERSION = "3.0.0"
2
+ VERSION = "3.0.1"
3
3
  end
@@ -85,11 +85,11 @@ module ActionViewTestSetup
85
85
  txt << %{</div>}
86
86
  end
87
87
 
88
- def form_text(action = "http://www.example.com", id = nil, html_class = nil, remote = nil, validate = nil)
88
+ def form_text(action = "http://www.example.com", id = nil, html_class = nil, remote = nil, validators = nil)
89
89
  txt = %{<form accept-charset="UTF-8" action="#{action}"}
90
90
  txt << %{ data-remote="true"} if remote
91
91
  txt << %{ class="#{html_class}"} if html_class
92
- txt << %{ data-validate="true"} if validate
92
+ txt << %{ data-validate="true"} if validators
93
93
  txt << %{ id="#{id}"} if id
94
94
  txt << %{ method="post">}
95
95
  end
@@ -98,15 +98,15 @@ module ActionViewTestSetup
98
98
  contents = block_given? ? yield : ""
99
99
 
100
100
  if options.is_a?(Hash)
101
- method, remote, validate = options.values_at(:method, :remote, :validate)
101
+ method, remote, validators = options.values_at(:method, :remote, :validators)
102
102
  else
103
103
  method = options
104
104
  end
105
105
 
106
- html = form_text(action, id, html_class, remote, validate) + snowman(method) + (contents || "") + "</form>"
106
+ html = form_text(action, id, html_class, remote, validators) + snowman(method) + (contents || "") + "</form>"
107
107
 
108
- if options.is_a?(Hash) && options[:validate]
109
- html + %Q{<script>var #{id} = #{client_side_form_js_variable_helper};</script>}
108
+ if options.is_a?(Hash) && options[:validators]
109
+ html + %Q{<script>var #{id} = #{client_side_form_settings_helper.merge(:validators => validators).to_json};</script>}
110
110
  else
111
111
  html
112
112
  end
@@ -6,12 +6,12 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
6
6
  cattr_accessor :field_error_proc
7
7
  @@field_error_proc = Proc.new { |html_tag, instance| html_tag }
8
8
 
9
- def client_side_form_js_variable_helper
10
- json = {
9
+ def client_side_form_settings_helper
10
+ {
11
11
  :type => "ActionView::Helpers::FormBuilder",
12
12
  :input_tag => %{<span id="input_tag" />},
13
13
  :label_tag => %{<label id="label_tag" />}
14
- }.to_json
14
+ }
15
15
  end
16
16
 
17
17
  def test_text_field
@@ -19,8 +19,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
19
19
  concat f.text_field(:cost)
20
20
  end
21
21
 
22
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
23
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" size="30" type="text" />}
22
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
23
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
24
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="text" />}
24
25
  end
25
26
  assert_equal expected, output_buffer
26
27
  end
@@ -30,8 +31,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
30
31
  concat f.password_field(:cost)
31
32
  end
32
33
 
33
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
34
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" size="30" type="password" />}
34
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
35
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
36
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="password" />}
35
37
  end
36
38
  assert_equal expected, output_buffer
37
39
  end
@@ -41,8 +43,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
41
43
  concat f.file_field(:cost)
42
44
  end
43
45
 
44
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
45
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" type="file" />}
46
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
47
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
48
+ %{<input data-validate="true" id="post_cost" name="post[cost]" type="file" />}
46
49
  end
47
50
  assert_equal expected, output_buffer
48
51
  end
@@ -52,8 +55,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
52
55
  concat f.text_area(:cost)
53
56
  end
54
57
 
55
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
56
- %{<textarea cols="40" data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" rows="20"></textarea>}
58
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
59
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
60
+ %{<textarea cols="40" data-validate="true" id="post_cost" name="post[cost]" rows="20"></textarea>}
57
61
  end
58
62
  assert_equal expected, output_buffer
59
63
  end
@@ -63,8 +67,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
63
67
  concat f.search_field(:cost)
64
68
  end
65
69
 
66
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
67
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" size="30" type="search" />}
70
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
71
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
72
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="search" />}
68
73
  end
69
74
  assert_equal expected, output_buffer
70
75
  end
@@ -74,8 +79,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
74
79
  concat f.telephone_field(:cost)
75
80
  end
76
81
 
77
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
78
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" size="30" type="tel" />}
82
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
83
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
84
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="tel" />}
79
85
  end
80
86
  assert_equal expected, output_buffer
81
87
  end
@@ -85,8 +91,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
85
91
  concat f.phone_field(:cost)
86
92
  end
87
93
 
88
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
89
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" size="30" type="tel" />}
94
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
95
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
96
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="tel" />}
90
97
  end
91
98
  assert_equal expected, output_buffer
92
99
  end
@@ -96,8 +103,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
96
103
  concat f.url_field(:cost)
97
104
  end
98
105
 
99
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
100
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" size="30" type="url" />}
106
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
107
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
108
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="url" />}
101
109
  end
102
110
  assert_equal expected, output_buffer
103
111
  end
@@ -107,8 +115,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
107
115
  concat f.email_field(:cost)
108
116
  end
109
117
 
110
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
111
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" size="30" type="email" />}
118
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
119
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
120
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="email" />}
112
121
  end
113
122
  assert_equal expected, output_buffer
114
123
  end
@@ -118,8 +127,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
118
127
  concat f.number_field(:cost)
119
128
  end
120
129
 
121
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
122
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" size="30" type="number" />}
130
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
131
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
132
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="number" />}
123
133
  end
124
134
  assert_equal expected, output_buffer
125
135
  end
@@ -129,8 +139,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
129
139
  concat f.range_field(:cost)
130
140
  end
131
141
 
132
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
133
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" size="30" type="range" />}
142
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
143
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
144
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="range" />}
134
145
  end
135
146
  assert_equal expected, output_buffer
136
147
  end
@@ -140,9 +151,10 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
140
151
  concat f.check_box(:cost)
141
152
  end
142
153
 
143
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
154
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
155
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
144
156
  %{<input name="post[cost]" type="hidden" value="0" />} +
145
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" type="checkbox" value="1" />}
157
+ %{<input data-validate="true" id="post_cost" name="post[cost]" type="checkbox" value="1" />}
146
158
  end
147
159
  assert_equal expected, output_buffer
148
160
  end
@@ -152,8 +164,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
152
164
  concat f.radio_button(:cost, "10")
153
165
  end
154
166
 
155
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
156
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost_10" name="post[cost]" type="radio" value="10" />}
167
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
168
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
169
+ %{<input data-validate="true" id="post_cost_10" name="post[cost]" type="radio" value="10" />}
157
170
  end
158
171
  assert_equal expected, output_buffer
159
172
  end
@@ -163,7 +176,7 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
163
176
  concat f.text_field(:title)
164
177
  end
165
178
 
166
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
179
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => {}) do
167
180
  %{<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />}
168
181
  end
169
182
  assert_equal expected, output_buffer
@@ -174,7 +187,7 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
174
187
  concat f.text_field(:cost, :validate => false)
175
188
  end
176
189
 
177
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
190
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => {}) do
178
191
  %{<input id="post_cost" name="post[cost]" size="30" type="text" />}
179
192
  end
180
193
  assert_equal expected, output_buffer
@@ -187,8 +200,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
187
200
  }
188
201
  end
189
202
 
190
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
191
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_comment_title" name="post[comment][title]" size="30" type="text" />}
203
+ validators = {'post[comment][title]' => {:presence => {:message => "can't be blank"}}}
204
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
205
+ %{<input data-validate="true" id="post_comment_title" name="post[comment][title]" size="30" type="text" />}
192
206
  end
193
207
 
194
208
  assert_equal expected, output_buffer
@@ -201,7 +215,7 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
201
215
  }
202
216
  end
203
217
 
204
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validate => true) do
218
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => {}) do
205
219
  %{<input id="post_comment_title" name="post[comment][title]" size="30" type="text" />}
206
220
  end
207
221
 
@@ -213,8 +227,9 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
213
227
  concat f.text_field(:cost)
214
228
  end
215
229
 
216
- expected = whole_form("/posts/123", "some_form", "edit_post", :method => "put", :validate => true) do
217
- %{<input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" size="30" type="text" />}
230
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
231
+ expected = whole_form("/posts/123", "some_form", "edit_post", :method => "put", :validators => validators) do
232
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="text" />}
218
233
  end
219
234
  assert_equal expected, output_buffer
220
235
  end
@@ -128,5 +128,14 @@ class ActiveModel::ValidationsTest < ClientSideValidations::ActiveModelTestBase
128
128
  }
129
129
  assert_equal expected_hash, person.client_side_validation_hash
130
130
  end
131
+
132
+ def test_validates_with_should_be_ignored
133
+ person = new_person do |p|
134
+ p.validates_with PersonValidator
135
+ end
136
+
137
+ expected_hash = {}
138
+ assert_equal expected_hash, person.client_side_validation_hash
139
+ end
131
140
  end
132
141
 
@@ -1,3 +1,8 @@
1
+ class PersonValidator < ActiveModel::Validator
2
+ def validate(record)
3
+ end
4
+ end
5
+
1
6
  class Person
2
7
  include ActiveModel::Validations
3
8
 
@@ -19,7 +19,15 @@ class ActiveRecord::UniquenessValidatorTest < ClientSideValidations::ActiveRecor
19
19
  assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name]).client_side_hash(@user, :name)
20
20
  end
21
21
 
22
- def test_uniqueness_client_side_hash_with_scope
22
+ def test_uniqueness_client_side_hash_with_single_scope_item
23
+ @user.stubs(:age).returns(30)
24
+ @user.stubs(:title).returns("test title")
25
+ expected_hash = { :message => "has already been taken", :case_sensitive => true, :scope => {:title => "test title"} }
26
+ result_hash = UniquenessValidator.new(:attributes => [:name], :scope => :title).client_side_hash(@user, :name)
27
+ assert_equal expected_hash, result_hash
28
+ end
29
+
30
+ def test_uniqueness_client_side_hash_with_multiple_scope_items
23
31
  @user.stubs(:age).returns(30)
24
32
  @user.stubs(:title).returns("test title")
25
33
  expected_hash = { :message => "has already been taken", :case_sensitive => true, :scope => {:age => 30, :title => "test title"} }
@@ -27,5 +35,11 @@ class ActiveRecord::UniquenessValidatorTest < ClientSideValidations::ActiveRecor
27
35
  assert_equal expected_hash, result_hash
28
36
  end
29
37
 
38
+ def test_uniqueness_client_side_hash_with_empty_scope_array
39
+ expected_hash = { :message => "has already been taken", :case_sensitive => true }
40
+ result_hash = UniquenessValidator.new(:attributes => [:name], :scope => []).client_side_hash(@user, :name)
41
+ assert_equal expected_hash, result_hash
42
+ end
43
+
30
44
  end
31
45
 
@@ -6,6 +6,6 @@ class ClientSideValidations::Formtastic::SemanticFormBuilderTest < Test::Unit::T
6
6
  :type => 'Formtastic::SemanticFormBuilder',
7
7
  :inline_error_class => 'inline-errors'
8
8
  }
9
- assert_equal expected, Formtastic::SemanticFormBuilder.client_side_form_js_hash(nil, nil)
9
+ assert_equal expected, Formtastic::SemanticFormBuilder.client_side_form_settings(nil, nil)
10
10
  end
11
11
  end
@@ -5,7 +5,7 @@ class ClientSideValidations::Formtastic::FormHelperTest < ActionView::TestCase
5
5
  include ActionViewTestSetup
6
6
  include Formtastic::SemanticFormHelper
7
7
 
8
- def client_side_form_js_variable_helper
8
+ def client_side_form_settings_helper
9
9
  ""
10
10
  end
11
11
 
@@ -14,8 +14,8 @@ class ClientSideValidations::Formtastic::FormHelperTest < ActionView::TestCase
14
14
  concat f.input(:cost)
15
15
  end
16
16
 
17
- expected = %{<form accept-charset="UTF-8" action="/posts/123" class="formtastic post" data-validate="true" id="edit_post_123" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="_method" type="hidden" value="put" /></div><li class="string required" id="post_cost_input"><label for="post_cost">Cost<abbr title="required">*</abbr></label><input data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" type="text" /></li></form><script>var edit_post_123 = {"type":"Formtastic::SemanticFormBuilder","inline_error_class":"inline-errors"};</script>}
18
- assert_equal expected, output_buffer
17
+ expected = %{<form accept-charset="UTF-8" action="/posts/123" class="formtastic post" data-validate="true" id="edit_post_123" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="_method" type="hidden" value="put" /></div><li class="string required" id="post_cost_input"><label for="post_cost">Cost<abbr title="required">*</abbr></label><input data-validate="true" id="post_cost" name="post[cost]" type="text" /></li></form><script>var edit_post_123 = {"type":"Formtastic::SemanticFormBuilder","inline_error_class":"inline-errors","validators":{"post[cost]":{"presence":{"message":"can't be blank"}}}};</script>}
18
+ assert_equal expected, output_buffer, "\n\n *** If you're running Ruby 1.8 and this test fails is is most likely due to 1.8's lack of insertion order persistence with Hashes ***\n"
19
19
  end
20
20
 
21
21
  end
@@ -3,7 +3,8 @@ module('Element Validate After Callback', {
3
3
  new_user = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
- label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>'
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {"user[name]":{"presence":{"message": "must be present"}}}
7
8
  }
8
9
 
9
10
  $('#qunit-fixture')
@@ -18,7 +19,7 @@ module('Element Validate After Callback', {
18
19
  .append($('<input />', {
19
20
  name: 'user[name]',
20
21
  id: 'user_name',
21
- 'data-validators': '{presence:{message: "must be present"}}',
22
+ 'data-validate': 'true',
22
23
  type: 'text'
23
24
  }))
24
25
  .append($('<label for="user_name">Name</label>'));
@@ -3,7 +3,8 @@ module('Element Validate Before Callback', {
3
3
  new_user = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
- label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>'
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {"user[name]":{"{presence":{"message": "must be present"}}}
7
8
  }
8
9
 
9
10
  $('#qunit-fixture')
@@ -18,7 +19,7 @@ module('Element Validate Before Callback', {
18
19
  .append($('<input />', {
19
20
  name: 'user[name]',
20
21
  id: 'user_name',
21
- 'data-validators': '{presence:{message: "must be present"}}',
22
+ 'data-validate': 'true',
22
23
  type: 'text'
23
24
  }))
24
25
  .append($('<label for="user_name">Name</label>'));
@@ -3,7 +3,8 @@ module('Element Validate Fail Callback', {
3
3
  new_user = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
- label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>'
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {"user[name]":{"presence":{"message": "must be present"}}}
7
8
  }
8
9
 
9
10
  $('#qunit-fixture')
@@ -18,7 +19,7 @@ module('Element Validate Fail Callback', {
18
19
  .append($('<input />', {
19
20
  name: 'user[name]',
20
21
  id: 'user_name',
21
- 'data-validators': '{presence:{message: "must be present"}}',
22
+ 'data-validate': 'true',
22
23
  type: 'text'
23
24
  }))
24
25
  .append($('<label for="user_name">Name</label>'));
@@ -3,7 +3,8 @@ module('Element Validate Pass Callback', {
3
3
  new_user = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
- label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>'
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {"user[name]":{"presence":{"message": "must be present"}}}
7
8
  }
8
9
 
9
10
  $('#qunit-fixture')
@@ -18,7 +19,7 @@ module('Element Validate Pass Callback', {
18
19
  .append($('<input />', {
19
20
  name: 'user[name]',
20
21
  id: 'user_name',
21
- 'data-validators': '{presence:{message: "must be present"}}',
22
+ 'data-validate': 'true',
22
23
  type: 'text'
23
24
  }))
24
25
  .append($('<label for="user_name">Name</label>'));
@@ -3,7 +3,8 @@ module('Form Validate After Callback', {
3
3
  new_user = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
- label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>'
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {"user[name]":{"presence":{"message": "must be present"}}}
7
8
  }
8
9
 
9
10
  $('#qunit-fixture')
@@ -18,7 +19,7 @@ module('Form Validate After Callback', {
18
19
  .append($('<input />', {
19
20
  name: 'user[name]',
20
21
  id: 'user_name',
21
- 'data-validators': '{presence:{message: "must be present"}}',
22
+ 'data-validate': 'true',
22
23
  type: 'text'
23
24
  }))
24
25
  .append($('<label for="user_name">Name</label>'));
@@ -3,7 +3,8 @@ module('Form Validate Before Callback', {
3
3
  new_user = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
- label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>'
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {"user[name]":{"presence":{"message": "must be present"}}}
7
8
  }
8
9
 
9
10
  $('#qunit-fixture')
@@ -18,7 +19,7 @@ module('Form Validate Before Callback', {
18
19
  .append($('<input />', {
19
20
  name: 'user[name]',
20
21
  id: 'user_name',
21
- 'data-validators': '{presence:{message: "must be present"}}',
22
+ 'data-validate': 'true',
22
23
  type: 'text'
23
24
  }))
24
25
  .append($('<label for="user_name">Name</label>'));
@@ -3,7 +3,8 @@ module('Form Validate Fail Callback', {
3
3
  new_user = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
- label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>'
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {"user[name]":{"presence":{"message": "must be present"}}}
7
8
  }
8
9
 
9
10
  $('#qunit-fixture')
@@ -18,7 +19,7 @@ module('Form Validate Fail Callback', {
18
19
  .append($('<input />', {
19
20
  name: 'user[name]',
20
21
  id: 'user_name',
21
- 'data-validators': '{presence:{message: "must be present"}}',
22
+ 'data-validate': 'true',
22
23
  type: 'text'
23
24
  }))
24
25
  .append($('<label for="user_name">Name</label>'));
@@ -3,7 +3,8 @@ module('Form Validate Pass Callback', {
3
3
  new_user = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
- label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>'
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {"user[name]":{"presence":{"message": "must be present"}}}
7
8
  }
8
9
 
9
10
  $('#qunit-fixture')
@@ -18,7 +19,7 @@ module('Form Validate Pass Callback', {
18
19
  .append($('<input />', {
19
20
  name: 'user[name]',
20
21
  id: 'user_name',
21
- 'data-validators': '{presence:{message: "must be present"}}',
22
+ 'data-validate': 'true',
22
23
  type: 'text'
23
24
  }))
24
25
  .append($('<label for="user_name">Name</label>'));
@@ -3,7 +3,8 @@ module('Validate Form', {
3
3
  new_user = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
- label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>'
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {'user[name]':{"presence":{"message": "must be present"}}}
7
8
  }
8
9
 
9
10
  $('#qunit-fixture')
@@ -17,7 +18,7 @@ module('Validate Form', {
17
18
  .append($('<input />', {
18
19
  name: 'user[name]',
19
20
  id: 'user_name',
20
- 'data-validators': '{presence:{message: "must be present"}}',
21
+ 'data-validate': 'true',
21
22
  type: 'text'
22
23
  }))
23
24
  .append($('<label for="user_name">Name</label>'));
@@ -2,7 +2,10 @@ module('Validate Formtastic', {
2
2
  setup: function() {
3
3
  new_user = {
4
4
  type: 'Formtastic::SemanticFormBuilder',
5
- inline_error_class: 'inline-errors'
5
+ inline_error_class: 'inline-errors',
6
+ validators: {
7
+ "user[name]":{"presence":{"message": "must be present"}, "format":{"message":"is invalid","with":/\d+/}}
8
+ }
6
9
  }
7
10
 
8
11
  $('#qunit-fixture')
@@ -17,7 +20,7 @@ module('Validate Formtastic', {
17
20
  .append($('<input />', {
18
21
  name: 'user[name]',
19
22
  id: 'user_name',
20
- 'data-validators': '{"presence":{"message": "must be present"}, "format":{"message":"is invalid","with":/\\d+/}}',
23
+ 'data-validate': 'true',
21
24
  type: 'text'
22
25
  }))
23
26
  .append($('<label for="user_name">Name</label>'));
@@ -5,7 +5,10 @@ module('Validate SimpleForm', {
5
5
  error_class: 'error',
6
6
  error_tag: 'span',
7
7
  wrapper_error_class: 'field_with_errors',
8
- wrapper_tag: 'div'
8
+ wrapper_tag: 'div',
9
+ validators: {
10
+ "user[name]":{"presence":{"message": "must be present"}, "format":{"message":"is invalid","with":/\d+/}}
11
+ }
9
12
  }
10
13
 
11
14
  $('#qunit-fixture')
@@ -20,7 +23,7 @@ module('Validate SimpleForm', {
20
23
  .append($('<input />', {
21
24
  name: 'user[name]',
22
25
  id: 'user_name',
23
- 'data-validators': '{"presence":{"message": "must be present"}, "format":{"message":"is invalid","with":/\\d+/}}',
26
+ 'data-validate': 'true',
24
27
  type: 'text'
25
28
  }))
26
29
  .append($('<label for="user_name">Name</label>'));
@@ -3,7 +3,13 @@ module('Validate Element', {
3
3
  new_user = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
- label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>'
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {
8
+ 'user[name]':{"presence":{"message": "must be present"}, "format":{"message":"is invalid","with":/\d+/}},
9
+ 'user[password]':{"confirmation":{"message": "must match confirmation"}},
10
+ 'user[agree]':{"acceptance": {"message": "must be accepted"}},
11
+ 'user[email]':{"uniqueness":{"message": "must be unique"},"presence":{"message": "must be present"}}
12
+ }
7
13
  }
8
14
 
9
15
  $('#qunit-fixture')
@@ -18,14 +24,14 @@ module('Validate Element', {
18
24
  .append($('<input />', {
19
25
  name: 'user[name]',
20
26
  id: 'user_name',
21
- 'data-validators': '{"presence":{"message": "must be present"}, "format":{"message":"is invalid","with":/\\d+/}}',
27
+ 'data-validate': 'true',
22
28
  type: 'text'
23
29
  }))
24
30
  .append($('<label for="user_password">Password</label>'))
25
31
  .append($('<input />', {
26
32
  name: 'user[password]',
27
33
  id: 'user_password',
28
- 'data-validators': '{"confirmation":{"message": "must match confirmation"}}',
34
+ 'data-validate': 'true',
29
35
  type: 'password'
30
36
  }))
31
37
  .append($('<label for="user_password_confirmation">Password Confirmation</label>'))
@@ -38,14 +44,14 @@ module('Validate Element', {
38
44
  .append($('<input />', {
39
45
  name: 'user[agree]',
40
46
  id: 'user_agree',
41
- 'data-validators': '{"acceptance": {"message": "must be accepted"}}',
47
+ 'data-validate': 'true',
42
48
  type: 'checkbox',
43
49
  value: 1
44
50
  }))
45
51
  .append($('<input />', {
46
52
  name: 'user[email]',
47
53
  id: 'user_email',
48
- 'data-validators': '{"uniqueness":{"message": "must be unique"},"presence":{"message": "must be present"}}',
54
+ 'data-validate': 'true',
49
55
  type: 'text'
50
56
  }))
51
57
 
@@ -3,7 +3,8 @@ module('Uniqueness options', {
3
3
  new_user = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label class="message"></label></div>',
6
- label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>'
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {'user[email]':{"uniqueness":{"message": "must be unique", "scope":{name:"pass"}},"presence":{"message": "must be present"}}}
7
8
  }
8
9
 
9
10
  $('#qunit-fixture')
@@ -22,7 +23,7 @@ module('Uniqueness options', {
22
23
  .append($('<input />', {
23
24
  name: 'user[email]',
24
25
  id: 'user_email',
25
- 'data-validators': '{"uniqueness":{"message": "must be unique", "scope":{name:"pass"}},"presence":{"message": "must be present"}}',
26
+ 'data-validate': 'true',
26
27
  type: 'text'
27
28
  }))
28
29
 
@@ -19,7 +19,14 @@ class Mongoid::UniqunessValidatorTest < ClientSideValidations::MongoidTestBase
19
19
  assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name]).client_side_hash(@book, :age)
20
20
  end
21
21
 
22
- def test_uniqueness_client_side_hash_with_scope
22
+ def test_uniqueness_client_side_hash_with_single_scope_item
23
+ @book.stubs(:author_email).returns("test@test.com")
24
+ expected_hash = { :message => "is already taken", :scope => {:author_email => "test@test.com"} }
25
+ result_hash = UniquenessValidator.new(:attributes => [:author_name], :scope => :author_email).client_side_hash(@book, :author_name)
26
+ assert_equal expected_hash, result_hash
27
+ end
28
+
29
+ def test_uniqueness_client_side_hash_with_multiple_scope_items
23
30
  @book.stubs(:age).returns(30)
24
31
  @book.stubs(:author_email).returns("test@test.com")
25
32
  expected_hash = { :message => "is already taken", :scope => {:age => 30, :author_email => "test@test.com"} }
@@ -27,5 +34,11 @@ class Mongoid::UniqunessValidatorTest < ClientSideValidations::MongoidTestBase
27
34
  assert_equal expected_hash, result_hash
28
35
  end
29
36
 
37
+ def test_uniqueness_client_side_hash_with_empty_scope_array
38
+ expected_hash = { :message => "is already taken" }
39
+ result_hash = UniquenessValidator.new(:attributes => [:author_name], :scope => []).client_side_hash(@book, :author_name)
40
+ assert_equal expected_hash, result_hash
41
+ end
42
+
30
43
  end
31
44
 
@@ -9,6 +9,6 @@ class ClientSideValidations::SimpleForm::FormBuilderTest < Test::Unit::TestCase
9
9
  :wrapper_error_class => :field_with_errors,
10
10
  :wrapper_tag => :div
11
11
  }
12
- assert_equal expected, SimpleForm::FormBuilder.client_side_form_js_hash(nil, nil)
12
+ assert_equal expected, SimpleForm::FormBuilder.client_side_form_settings(nil, nil)
13
13
  end
14
14
  end
@@ -5,7 +5,7 @@ class ClientSideValidations::SimpleForm::FormHelperTest < ActionView::TestCase
5
5
  include ActionViewTestSetup
6
6
  include SimpleForm::ActionViewExtensions::FormHelper
7
7
 
8
- def client_side_form_js_variable_helper
8
+ def client_side_form_settings_helper
9
9
  ""
10
10
  end
11
11
 
@@ -14,7 +14,7 @@ class ClientSideValidations::SimpleForm::FormHelperTest < ActionView::TestCase
14
14
  concat f.input(:cost)
15
15
  end
16
16
 
17
- expected = %{<form accept-charset="UTF-8" action="/posts/123" class="simple_form post" data-validate="true" id="edit_post_123" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="_method" type="hidden" value="put" /></div><div class="input string required"><label class="string required" for="post_cost"><abbr title="required">*</abbr> Cost</label><input class="string required" data-validators="{&quot;presence&quot;:{&quot;message&quot;:&quot;can't be blank&quot;}}" id="post_cost" name="post[cost]" required="required" size="50" type="text" /></div></form><script>var edit_post_123 = {"type":"SimpleForm::FormBuilder","error_class":"error","error_tag":"span","wrapper_error_class":"field_with_errors","wrapper_tag":"div"};</script>}
17
+ expected = %{<form accept-charset="UTF-8" action="/posts/123" class="simple_form post" data-validate="true" id="edit_post_123" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="_method" type="hidden" value="put" /></div><div class="input string required"><label class="string required" for="post_cost"><abbr title="required">*</abbr> Cost</label><input class="string required" data-validate="true" id="post_cost" name="post[cost]" required="required" size="50" type="text" /></div></form><script>var edit_post_123 = {"type":"SimpleForm::FormBuilder","error_class":"error","error_tag":"span","wrapper_error_class":"field_with_errors","wrapper_tag":"div","validators":{"post[cost]":{"presence":{"message":"can't be blank"}}}};</script>}
18
18
  assert_equal expected, output_buffer, "\n\n *** If you're running Ruby 1.8 and this test fails is is most likely due to 1.8's lack of insertion order persistence with Hashes ***\n"
19
19
  end
20
20
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: client_side_validations
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 3.0.0
5
+ version: 3.0.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Brian Cardarella
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-30 00:00:00 -04:00
13
+ date: 2011-04-05 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency