active_form 0.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.
- data.tar.gz.sig +2 -0
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/MIT-LICENSE +19 -0
- data/Manifest.txt +181 -0
- data/README.txt +1 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +71 -0
- data/config/requirements.rb +17 -0
- data/init.rb +5 -0
- data/lib/active_form.rb +86 -0
- data/lib/active_form/core_extensions.rb +179 -0
- data/lib/active_form/definition.rb +72 -0
- data/lib/active_form/element.rb +50 -0
- data/lib/active_form/elements/base.rb +67 -0
- data/lib/active_form/elements/builder.rb +103 -0
- data/lib/active_form/elements/button.rb +15 -0
- data/lib/active_form/elements/checkbox.rb +18 -0
- data/lib/active_form/elements/file.rb +15 -0
- data/lib/active_form/elements/hidden.rb +9 -0
- data/lib/active_form/elements/image.rb +7 -0
- data/lib/active_form/elements/input.rb +23 -0
- data/lib/active_form/elements/password.rb +12 -0
- data/lib/active_form/elements/radio.rb +18 -0
- data/lib/active_form/elements/reset.rb +15 -0
- data/lib/active_form/elements/section.rb +37 -0
- data/lib/active_form/elements/select.rb +42 -0
- data/lib/active_form/elements/submit.rb +19 -0
- data/lib/active_form/elements/text.rb +9 -0
- data/lib/active_form/elements/textarea.rb +18 -0
- data/lib/active_form/errors.rb +73 -0
- data/lib/active_form/facets/checkbox_group.rb +11 -0
- data/lib/active_form/facets/collection_input.rb +96 -0
- data/lib/active_form/facets/radio_group.rb +11 -0
- data/lib/active_form/facets/select_date.rb +10 -0
- data/lib/active_form/facets/select_datetime.rb +10 -0
- data/lib/active_form/facets/select_day.rb +17 -0
- data/lib/active_form/facets/select_from_model.rb +60 -0
- data/lib/active_form/facets/select_hour.rb +17 -0
- data/lib/active_form/facets/select_minute.rb +17 -0
- data/lib/active_form/facets/select_month.rb +46 -0
- data/lib/active_form/facets/select_numeric_range.rb +59 -0
- data/lib/active_form/facets/select_second.rb +17 -0
- data/lib/active_form/facets/select_time.rb +10 -0
- data/lib/active_form/facets/select_timebased.rb +145 -0
- data/lib/active_form/facets/select_weekday.rb +46 -0
- data/lib/active_form/facets/select_year.rb +24 -0
- data/lib/active_form/mixins/attribute_methods.rb +33 -0
- data/lib/active_form/mixins/casting.rb +152 -0
- data/lib/active_form/mixins/collection_element_methods.rb +204 -0
- data/lib/active_form/mixins/common_methods.rb +350 -0
- data/lib/active_form/mixins/container_methods.rb +417 -0
- data/lib/active_form/mixins/css_methods.rb +70 -0
- data/lib/active_form/mixins/element_methods.rb +314 -0
- data/lib/active_form/mixins/javascript_methods.rb +99 -0
- data/lib/active_form/mixins/loader_methods.rb +72 -0
- data/lib/active_form/mixins/option_element_methods.rb +61 -0
- data/lib/active_form/mixins/validation_methods.rb +253 -0
- data/lib/active_form/validator.rb +47 -0
- data/lib/active_form/validators/alpha.rb +9 -0
- data/lib/active_form/validators/alphanum.rb +9 -0
- data/lib/active_form/validators/base.rb +132 -0
- data/lib/active_form/validators/digits.rb +9 -0
- data/lib/active_form/validators/email.rb +29 -0
- data/lib/active_form/validators/format.rb +15 -0
- data/lib/active_form/validators/length_range.rb +24 -0
- data/lib/active_form/validators/number.rb +9 -0
- data/lib/active_form/validators/option_count.rb +24 -0
- data/lib/active_form/validators/proc.rb +22 -0
- data/lib/active_form/validators/required.rb +9 -0
- data/lib/active_form/validators/set.rb +21 -0
- data/lib/active_form/validators/time_range.rb +30 -0
- data/lib/active_form/validators/uri.rb +54 -0
- data/lib/active_form/version.rb +9 -0
- data/lib/active_form/views/fieldsets.rb +34 -0
- data/lib/active_form/views/plain.rb +32 -0
- data/lib/active_form/views/tables.rb +28 -0
- data/lib/active_form/widget.rb +43 -0
- data/lib/active_form/widgets/base.rb +28 -0
- data/lib/loob/uri_validator.rb +140 -0
- data/lib/rails/acts_as_dropdown/MIT-LICENSE +20 -0
- data/lib/rails/acts_as_dropdown/acts_as_dropdown.rb +119 -0
- data/lib/rails/acts_as_dropdown/dropdown.rb +27 -0
- data/lib/rails/controller_helper.rb +19 -0
- data/lib/rails/model/loader.rb +206 -0
- data/lib/rails/view_helper.rb +20 -0
- data/samples/html/css/style.css +175 -0
- data/samples/html/js/effects.js +958 -0
- data/samples/html/js/prototype.js +2006 -0
- data/samples/html/js/validation.js +228 -0
- data/samples/html/plain_view.html +77 -0
- data/samples/html/sample001.html +158 -0
- data/samples/html/sample002.html +76 -0
- data/samples/html/sample003.html +34 -0
- data/samples/layouts/default.rhtml +18 -0
- data/samples/layouts/plain.rhtml +21 -0
- data/samples/layouts/sample003.rhtml +25 -0
- data/samples/plain_view.rb +58 -0
- data/samples/sample001.rb +111 -0
- data/samples/sample002.rb +92 -0
- data/samples/sample003.rb +30 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/elements/test_base_element.rb +159 -0
- data/test/elements/test_builder_element.rb +81 -0
- data/test/elements/test_button_element.rb +12 -0
- data/test/elements/test_checkbox_element.rb +233 -0
- data/test/elements/test_file_element.rb +20 -0
- data/test/elements/test_hidden_element.rb +11 -0
- data/test/elements/test_image_element.rb +11 -0
- data/test/elements/test_input_element.rb +39 -0
- data/test/elements/test_password_element.rb +16 -0
- data/test/elements/test_radio_element.rb +197 -0
- data/test/elements/test_reset_element.rb +12 -0
- data/test/elements/test_section_element.rb +162 -0
- data/test/elements/test_select_element.rb +364 -0
- data/test/elements/test_submit_element.rb +12 -0
- data/test/elements/test_text_element.rb +91 -0
- data/test/elements/test_textarea_element.rb +23 -0
- data/test/facets/test_checkbox_group_element.rb +388 -0
- data/test/facets/test_radio_group_element.rb +312 -0
- data/test/facets/test_select_date_element.rb +211 -0
- data/test/facets/test_select_datetime_element.rb +56 -0
- data/test/facets/test_select_day_element.rb +37 -0
- data/test/facets/test_select_from_model_element.rb +86 -0
- data/test/facets/test_select_hour_element.rb +37 -0
- data/test/facets/test_select_minute_element.rb +52 -0
- data/test/facets/test_select_month_element.rb +79 -0
- data/test/facets/test_select_numeric_range_element.rb +14 -0
- data/test/facets/test_select_second_element.rb +48 -0
- data/test/facets/test_select_time_element.rb +148 -0
- data/test/facets/test_select_weekday_element.rb +71 -0
- data/test/facets/test_select_year_element.rb +73 -0
- data/test/fixtures/author.rb +11 -0
- data/test/fixtures/authors.yml +0 -0
- data/test/fixtures/book.rb +14 -0
- data/test/fixtures/books.yml +8 -0
- data/test/fixtures/categories.yml +0 -0
- data/test/fixtures/categorization.rb +2 -0
- data/test/fixtures/categorizations.yml +0 -0
- data/test/fixtures/category.rb +8 -0
- data/test/fixtures/publisher.rb +5 -0
- data/test/fixtures/publishers.yml +10 -0
- data/test/fixtures/schema.rb +43 -0
- data/test/rails/test_model_autodefinition.rb +121 -0
- data/test/rails/test_model_loader.rb +61 -0
- data/test/resources/elements/chunky.rb +11 -0
- data/test/resources/forms/demo.rb +5 -0
- data/test/resources/models/book.rb +8 -0
- data/test/resources/models/register_publisher.rb +5 -0
- data/test/resources/sections/demo.rb +6 -0
- data/test/resources/sections/foo.rb +6 -0
- data/test/resources/validators/foo.rb +9 -0
- data/test/resources/widgets/custom.rb +13 -0
- data/test/test_active_form.rb +1050 -0
- data/test/test_casting.rb +124 -0
- data/test/test_definition.rb +68 -0
- data/test/test_definition_class.rb +118 -0
- data/test/test_element_class.rb +201 -0
- data/test/test_helper.rb +74 -0
- data/test/test_javascript.rb +234 -0
- data/test/test_load_definition.rb +68 -0
- data/test/test_load_element.rb +35 -0
- data/test/test_load_section_element.rb +43 -0
- data/test/test_load_validator.rb +31 -0
- data/test/test_load_widget.rb +93 -0
- data/test/test_validation.rb +722 -0
- data/test/validators/test_validates_as_alpha.rb +26 -0
- data/test/validators/test_validates_as_alphanum.rb +26 -0
- data/test/validators/test_validates_as_digits.rb +26 -0
- data/test/validators/test_validates_as_email.rb +29 -0
- data/test/validators/test_validates_as_number.rb +26 -0
- data/test/validators/test_validates_as_uri.rb +128 -0
- data/test/validators/test_validates_with_format.rb +26 -0
- data/test/validators/test_validates_within_length_range.rb +46 -0
- data/test/validators/test_validates_within_set.rb +46 -0
- data/test/validators/test_validates_within_time_range.rb +53 -0
- metadata +307 -0
- metadata.gz.sig +4 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module ActiveForm::Mixins::OptionElementMethods
|
|
2
|
+
|
|
3
|
+
def self.included(base)
|
|
4
|
+
base.define_html_flags(:checked, false)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def options=(val)
|
|
8
|
+
if val.kind_of?(Array)
|
|
9
|
+
self.fallback_value = val.last
|
|
10
|
+
self.checked_value = val.first
|
|
11
|
+
else
|
|
12
|
+
self.checked_value = val
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
alias :option= :options=
|
|
16
|
+
|
|
17
|
+
def checked_value=(value)
|
|
18
|
+
@checked_value = value
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def checked_value
|
|
22
|
+
@checked_value ||= nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def valid_option?(value)
|
|
26
|
+
[self.checked_value, self.fallback_value].include?(value)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def checked?
|
|
30
|
+
perform_check!
|
|
31
|
+
end
|
|
32
|
+
alias :active? :checked?
|
|
33
|
+
alias :selected? :checked?
|
|
34
|
+
|
|
35
|
+
def checked
|
|
36
|
+
self.html_flags[:checked]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def checked=(value)
|
|
40
|
+
self.html_flags[:checked] = value.to_s.to_boolean
|
|
41
|
+
self.element_value = (self.html_flags[:checked] ? self.checked_value : self.fallback_value)
|
|
42
|
+
self.html_flags[:checked]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def perform_check!
|
|
46
|
+
self.html_flags[:checked] = !self.blank? && self.element_value == self.checked_value
|
|
47
|
+
self.element_value = (self.html_flags[:checked] ? self.checked_value : self.fallback_value)
|
|
48
|
+
self.html_flags[:checked]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def required=(value)
|
|
52
|
+
self.option_flags[:required] = value.to_s.to_boolean
|
|
53
|
+
if self.option_flags[:required]
|
|
54
|
+
req = proc { |v| v.element.errors.add(v.message, 'confirm') unless v.element.checked? }
|
|
55
|
+
validates_with_proc :code => 'required', :proc => req
|
|
56
|
+
else
|
|
57
|
+
validators.delete_if { |v| v.code == 'required' }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
module ActiveForm::Mixins::ValidationMethods
|
|
2
|
+
|
|
3
|
+
def self.included(base)
|
|
4
|
+
base.send(:extend, ClassMethods)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def define_validator(type, *args, &block)
|
|
8
|
+
args.unshift(self)
|
|
9
|
+
validator = ActiveForm::Validator::build(type, *args, &block)
|
|
10
|
+
validators << validator
|
|
11
|
+
validator
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def format_message(msg = @@default_msg, error_code = 'default', params = [])
|
|
15
|
+
msg = (localize(name, "validates_#{error_code}") || msg) if localized?
|
|
16
|
+
mparams = message_params + params
|
|
17
|
+
sprintf(msg || '', *mparams)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def message_params
|
|
21
|
+
[label, element_value]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def get_validation_advice_wrapper
|
|
25
|
+
if respond_to?(:advice_wrapper)
|
|
26
|
+
method_to_proc(:advice_wrapper)
|
|
27
|
+
elsif self.class.respond_to?(:advice_wrapper)
|
|
28
|
+
self.class.method_to_proc(:advice_wrapper)
|
|
29
|
+
else
|
|
30
|
+
self.class.method_to_proc(:default_validation_advice_wrapper)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def validators_by_type(*types)
|
|
35
|
+
types.map(&:to_s)
|
|
36
|
+
self.validators.find_all { |v| types.include?(v.code) }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def required_message=(str)
|
|
40
|
+
validator = self.validators_by_type('required').first
|
|
41
|
+
validator.message = str unless validator.nil?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def validation_advice(builder = create_builder)
|
|
45
|
+
str = server_side_validation_advice(builder)
|
|
46
|
+
str << client_side_validation_advice(builder) if client_side?
|
|
47
|
+
str
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def server_side_validation_advice(builder = create_builder, first_only = true)
|
|
51
|
+
element_errors(first_only).inject('') do |str, error|
|
|
52
|
+
attrs = { :id => "advice-#{error.identifier}-#{error.element.identifier}", :class => "validation-advice advice-#{error.code}" }
|
|
53
|
+
get_validation_advice_wrapper.call(builder, error, attrs)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def all_server_side_validation_advice(builder = create_builder)
|
|
58
|
+
server_side_validation_advice(builder, false)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def client_side_validation_advice(builder = create_builder)
|
|
62
|
+
gather_validation_advice.each do |adv|
|
|
63
|
+
attrs = { :id => "advice-#{adv.identifier}-#{adv.element.identifier}", :style => 'display: none', :class => "validation-advice advice-#{adv.code}" }
|
|
64
|
+
get_validation_advice_wrapper.call(builder, adv, attrs)
|
|
65
|
+
end
|
|
66
|
+
builder.target!
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def gather_validation_advice
|
|
70
|
+
adv = validators.inject([]) { |ary, v| v.advice.keys.sort.inject(ary) { |a, key| a << v.advice[key] unless v.advice[key].blank? } }
|
|
71
|
+
each { |elem| adv += elem.gather_validation_advice } if container?
|
|
72
|
+
adv.compact
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def validation_css_class
|
|
76
|
+
css = validators.inject(CssAttribute.new) { |cs, v| cs << "#{v.identifier}" }
|
|
77
|
+
each { |elem| css += elem.validation_css_class } if container?
|
|
78
|
+
css.compact
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def validation_javascript_definitions
|
|
82
|
+
js = validators.inject([]) { |ary, v| ary << v.javascript_definition }.compact.join("\n")
|
|
83
|
+
each { |elem| js += elem.validation_javascript_definitions } if container?
|
|
84
|
+
js
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def client_side?
|
|
88
|
+
client_side == true || (contained? && container.client_side?)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def client_side_options
|
|
92
|
+
@client_js_options ||= { :stopOnFirst => false, :useTitles => true }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def client_side
|
|
96
|
+
@client_side_validation ||= false
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def client_side=(value)
|
|
100
|
+
@client_side_validation = value.to_s.to_boolean
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def validators
|
|
104
|
+
@validators ||= []
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def errors
|
|
108
|
+
@errors ||= ActiveForm::Errors.new(self)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def element_errors(first_only = false)
|
|
112
|
+
elem_errors = first_only ? [errors.first] : errors.all
|
|
113
|
+
elements.each { |elem| elem_errors += elem.element_errors(first_only) } if container?
|
|
114
|
+
elem_errors.compact
|
|
115
|
+
end
|
|
116
|
+
alias :all_errors :element_errors
|
|
117
|
+
alias :validation_errors :element_errors
|
|
118
|
+
|
|
119
|
+
def initial_errors
|
|
120
|
+
element_errors(true)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def each_error(&block)
|
|
124
|
+
element_errors.each(&block)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def every_error(&block)
|
|
128
|
+
element_errors(true).each(&block)
|
|
129
|
+
end
|
|
130
|
+
alias :every_initial_error :every_error
|
|
131
|
+
|
|
132
|
+
def reset_errors!
|
|
133
|
+
errors.reset
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def valid?
|
|
137
|
+
initial_errors.empty?
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def validate
|
|
141
|
+
perform_validation && valid?
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def validate!
|
|
145
|
+
return true if validate
|
|
146
|
+
raise ActiveForm::ValidationException
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def perform_validation
|
|
150
|
+
reset_errors!
|
|
151
|
+
each { |elem| elem.perform_validation } if container?
|
|
152
|
+
validators.each(&:validate)
|
|
153
|
+
validate_element
|
|
154
|
+
after_validation_callback(self) if respond_to?(:after_validation_callback)
|
|
155
|
+
return true # so you can write perform_validation && valid?
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def clear_validations!
|
|
159
|
+
reset_errors!
|
|
160
|
+
recurse(&:clear_validations!) if container?
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def validate_element
|
|
164
|
+
internal_validation(self) if respond_to?(:internal_validation)
|
|
165
|
+
validation_handler(self) if respond_to?(:validation_handler)
|
|
166
|
+
self.class.validation_handler(self) if self.class.respond_to?(:validation_handler)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def define_validation(prc = nil, &block)
|
|
170
|
+
define_singleton_method(:validation_handler, &(block_given? ? block : prc))
|
|
171
|
+
end
|
|
172
|
+
alias :validation= :define_validation
|
|
173
|
+
alias :validation :define_validation
|
|
174
|
+
|
|
175
|
+
def reset_validation
|
|
176
|
+
undefine_singleton_method(:validation_handler) rescue nil
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def javascript_validation_code
|
|
180
|
+
return nil unless respond_to?(:js_validation_generator) || self.class.respond_to?(:js_validation_generator)
|
|
181
|
+
vparams = { :name => identifier.dasherize, :msg => "#{label}: validation failed" }
|
|
182
|
+
code = JavascriptAttribute.new
|
|
183
|
+
js_validation_generator(self, code, vparams) if respond_to?(:js_validation_generator)
|
|
184
|
+
self.class.js_validation_generator(self, code, vparams) if self.class.respond_to?(:js_validation_generator)
|
|
185
|
+
return nil if code.empty?
|
|
186
|
+
class_name = "validate-#{vparams[:name]}"
|
|
187
|
+
css_class << class_name unless container? || css_class.include?(class_name)
|
|
188
|
+
%|Validation.add('#{class_name}', "#{vparams[:msg]}", function (v) {\n #{code}\n});|
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def javascript_validation(prc = nil, &block)
|
|
192
|
+
define_singleton_method(:js_validation_generator, &(block_given? ? block : prc))
|
|
193
|
+
end
|
|
194
|
+
alias :javascript_validation= :javascript_validation
|
|
195
|
+
|
|
196
|
+
def reset_javascript_validation
|
|
197
|
+
undefine_singleton_method(:js_validation_generator) rescue nil
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def validation_advice_wrapper(prc = nil, &block)
|
|
201
|
+
define_singleton_method(:advice_wrapper, &(block_given? ? block : prc))
|
|
202
|
+
end
|
|
203
|
+
alias :javascript_validation= :javascript_validation
|
|
204
|
+
|
|
205
|
+
def reset_validation_advice_wrapper
|
|
206
|
+
undefine_singleton_method(:advice_wrapper) rescue nil
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def after_validation(prc = nil, &block)
|
|
210
|
+
define_singleton_method(:after_validation_callback, &(block_given? ? block : prc))
|
|
211
|
+
end
|
|
212
|
+
alias :after_validation_callback= :after_validation
|
|
213
|
+
|
|
214
|
+
def reset_after_validation_callback
|
|
215
|
+
undefine_singleton_method(:after_validation_callback) rescue nil
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
module ClassMethods
|
|
219
|
+
|
|
220
|
+
def define_validation(prc = nil, &block)
|
|
221
|
+
define_singleton_method(:validation_handler, &(block_given? ? block : prc))
|
|
222
|
+
end
|
|
223
|
+
alias :validation= :define_validation
|
|
224
|
+
|
|
225
|
+
def reset_validation
|
|
226
|
+
undefine_singleton_method(:validation_handler) rescue nil
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def javascript_validation(prc = nil, &block)
|
|
230
|
+
define_singleton_method(:js_validation_generator, &(block_given? ? block : prc))
|
|
231
|
+
end
|
|
232
|
+
alias :javascript_validation= :javascript_validation
|
|
233
|
+
|
|
234
|
+
def reset_javascript_validation
|
|
235
|
+
undefine_singleton_method(:js_validation_generator) rescue nil
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def default_validation_advice_wrapper(builder, error, attrs)
|
|
239
|
+
builder.div(error.message, attrs)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def validation_advice_wrapper(prc = nil, &block)
|
|
243
|
+
define_singleton_method(:advice_wrapper, &(block_given? ? block : prc))
|
|
244
|
+
end
|
|
245
|
+
alias :javascript_validation= :javascript_validation
|
|
246
|
+
|
|
247
|
+
def reset_validation_advice_wrapper
|
|
248
|
+
undefine_singleton_method(:advice_wrapper) rescue nil
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module ActiveForm::Validator
|
|
2
|
+
|
|
3
|
+
include ActiveForm::Mixins::LoaderMethods
|
|
4
|
+
|
|
5
|
+
class NoElemException < StandardError #:nodoc:
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class MismatchException < StandardError #:nodoc:
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
|
|
13
|
+
def validator?(klass)
|
|
14
|
+
klass < ActiveForm::Validator::Base
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# loader related
|
|
18
|
+
|
|
19
|
+
def load_paths
|
|
20
|
+
@@load_paths ||= [*base_load_paths]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def base_load_paths
|
|
24
|
+
[::File.join(ActiveForm::BASE_PATH, 'validators')]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def instance(definition_name, klass, *args, &block)
|
|
28
|
+
item = klass.new(*args, &block)
|
|
29
|
+
item
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def create(definition_name, &block)
|
|
33
|
+
ActiveForm::Validator::Base::create(definition_name, &block)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def register(elem_class)
|
|
37
|
+
if validator?(elem_class) && !self.methods.include?("validates_#{elem_class.loadable_type}")
|
|
38
|
+
self.module_eval("
|
|
39
|
+
def validates_#{elem_class.loadable_type}(*args, &block)
|
|
40
|
+
define_validator(:#{elem_class.loadable_type}, *args, &block)
|
|
41
|
+
end")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
class ActiveForm::Validator::Base
|
|
2
|
+
|
|
3
|
+
attr_reader :element
|
|
4
|
+
attr_accessor :msg, :code
|
|
5
|
+
|
|
6
|
+
def initialize(*args, &block)
|
|
7
|
+
setup
|
|
8
|
+
props = args.last.is_a?(Hash) ? args.pop : {}
|
|
9
|
+
register_element(args.shift) if is_element?(args.first)
|
|
10
|
+
self.code = self.class.to_s.demodulize.underscore
|
|
11
|
+
props.each { |prop, value| send("#{prop}=", value) if respond_to?("#{prop}=") }
|
|
12
|
+
yield self if block_given?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
alias :name :code
|
|
16
|
+
|
|
17
|
+
def setup
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def identifier
|
|
21
|
+
self.code == 'required' ? code : "validate-#{code}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def javascript_definition
|
|
25
|
+
self.class.javascript_definition(identifier)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def advice
|
|
29
|
+
{ code => ActiveForm::Error.new(element, message, code, message_params) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def validate
|
|
33
|
+
element.errors << advice[code]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def register_element(elem)
|
|
37
|
+
@element = elem
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def code=(str)
|
|
41
|
+
@code = str.to_s
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def message
|
|
45
|
+
self.msg || self.class.message
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def message=(str)
|
|
49
|
+
self.msg = str
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def message_params
|
|
53
|
+
[]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def label
|
|
57
|
+
element.label
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def value
|
|
61
|
+
element.element_value
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def value_length
|
|
65
|
+
str = self.value.to_s
|
|
66
|
+
charlength = str.respond_to?(:chars) ? str.chars.length : str.length
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def collection_length
|
|
70
|
+
[*self.value].delete_if { |v| v.blank? }.length
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def is_element?(arg)
|
|
74
|
+
arg.respond_to?(:element?) && arg.element?
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def js_validation(validation_msg, code)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class << self
|
|
81
|
+
|
|
82
|
+
def javascript_validation(msg = 'validation failed', jscode = '')
|
|
83
|
+
self.javascript_validation_code = { :msg => msg, :jscode => yield(jscode) }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def javascript_definition(identifier)
|
|
87
|
+
return nil if self.javascript_validation_code.blank?
|
|
88
|
+
%|Validation.add('#{identifier}', "#{self.javascript_validation_code[:msg]}", function (v) {\n #{self.javascript_validation_code[:jscode]}\n});|
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def message
|
|
92
|
+
self.default_msg ||= '%s: validation failure'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def default_message=(str)
|
|
96
|
+
self.default_msg = str
|
|
97
|
+
end
|
|
98
|
+
alias :default_message :default_message=
|
|
99
|
+
|
|
100
|
+
def inherited(derivative)
|
|
101
|
+
ActiveForm::Validator::register(derivative) if derivative.kind_of?(ActiveForm::Validator::Base)
|
|
102
|
+
derivative.class_inheritable_accessor :default_msg
|
|
103
|
+
derivative.class_inheritable_accessor :javascript_validation_code
|
|
104
|
+
super
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def create(definition_name, &block)
|
|
108
|
+
class_name = name_to_class_name(definition_name)
|
|
109
|
+
if !ActiveForm::Validator.const_defined?(class_name)
|
|
110
|
+
ActiveForm::Validator.const_set(class_name, Class.new(self))
|
|
111
|
+
if klass = ActiveForm::Validator.const_get(class_name)
|
|
112
|
+
klass.module_eval(&block) if block_given?
|
|
113
|
+
ActiveForm::Validator::register(klass)
|
|
114
|
+
return klass
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
nil
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def loadable_type
|
|
121
|
+
self.name.to_s.demodulize.underscore.to_sym
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def name_to_class_name(definition_name)
|
|
127
|
+
Inflector::camelize("#{definition_name}")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
end
|