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.
Files changed (184) hide show
  1. data.tar.gz.sig +2 -0
  2. data/History.txt +4 -0
  3. data/License.txt +20 -0
  4. data/MIT-LICENSE +19 -0
  5. data/Manifest.txt +181 -0
  6. data/README.txt +1 -0
  7. data/Rakefile +4 -0
  8. data/config/hoe.rb +71 -0
  9. data/config/requirements.rb +17 -0
  10. data/init.rb +5 -0
  11. data/lib/active_form.rb +86 -0
  12. data/lib/active_form/core_extensions.rb +179 -0
  13. data/lib/active_form/definition.rb +72 -0
  14. data/lib/active_form/element.rb +50 -0
  15. data/lib/active_form/elements/base.rb +67 -0
  16. data/lib/active_form/elements/builder.rb +103 -0
  17. data/lib/active_form/elements/button.rb +15 -0
  18. data/lib/active_form/elements/checkbox.rb +18 -0
  19. data/lib/active_form/elements/file.rb +15 -0
  20. data/lib/active_form/elements/hidden.rb +9 -0
  21. data/lib/active_form/elements/image.rb +7 -0
  22. data/lib/active_form/elements/input.rb +23 -0
  23. data/lib/active_form/elements/password.rb +12 -0
  24. data/lib/active_form/elements/radio.rb +18 -0
  25. data/lib/active_form/elements/reset.rb +15 -0
  26. data/lib/active_form/elements/section.rb +37 -0
  27. data/lib/active_form/elements/select.rb +42 -0
  28. data/lib/active_form/elements/submit.rb +19 -0
  29. data/lib/active_form/elements/text.rb +9 -0
  30. data/lib/active_form/elements/textarea.rb +18 -0
  31. data/lib/active_form/errors.rb +73 -0
  32. data/lib/active_form/facets/checkbox_group.rb +11 -0
  33. data/lib/active_form/facets/collection_input.rb +96 -0
  34. data/lib/active_form/facets/radio_group.rb +11 -0
  35. data/lib/active_form/facets/select_date.rb +10 -0
  36. data/lib/active_form/facets/select_datetime.rb +10 -0
  37. data/lib/active_form/facets/select_day.rb +17 -0
  38. data/lib/active_form/facets/select_from_model.rb +60 -0
  39. data/lib/active_form/facets/select_hour.rb +17 -0
  40. data/lib/active_form/facets/select_minute.rb +17 -0
  41. data/lib/active_form/facets/select_month.rb +46 -0
  42. data/lib/active_form/facets/select_numeric_range.rb +59 -0
  43. data/lib/active_form/facets/select_second.rb +17 -0
  44. data/lib/active_form/facets/select_time.rb +10 -0
  45. data/lib/active_form/facets/select_timebased.rb +145 -0
  46. data/lib/active_form/facets/select_weekday.rb +46 -0
  47. data/lib/active_form/facets/select_year.rb +24 -0
  48. data/lib/active_form/mixins/attribute_methods.rb +33 -0
  49. data/lib/active_form/mixins/casting.rb +152 -0
  50. data/lib/active_form/mixins/collection_element_methods.rb +204 -0
  51. data/lib/active_form/mixins/common_methods.rb +350 -0
  52. data/lib/active_form/mixins/container_methods.rb +417 -0
  53. data/lib/active_form/mixins/css_methods.rb +70 -0
  54. data/lib/active_form/mixins/element_methods.rb +314 -0
  55. data/lib/active_form/mixins/javascript_methods.rb +99 -0
  56. data/lib/active_form/mixins/loader_methods.rb +72 -0
  57. data/lib/active_form/mixins/option_element_methods.rb +61 -0
  58. data/lib/active_form/mixins/validation_methods.rb +253 -0
  59. data/lib/active_form/validator.rb +47 -0
  60. data/lib/active_form/validators/alpha.rb +9 -0
  61. data/lib/active_form/validators/alphanum.rb +9 -0
  62. data/lib/active_form/validators/base.rb +132 -0
  63. data/lib/active_form/validators/digits.rb +9 -0
  64. data/lib/active_form/validators/email.rb +29 -0
  65. data/lib/active_form/validators/format.rb +15 -0
  66. data/lib/active_form/validators/length_range.rb +24 -0
  67. data/lib/active_form/validators/number.rb +9 -0
  68. data/lib/active_form/validators/option_count.rb +24 -0
  69. data/lib/active_form/validators/proc.rb +22 -0
  70. data/lib/active_form/validators/required.rb +9 -0
  71. data/lib/active_form/validators/set.rb +21 -0
  72. data/lib/active_form/validators/time_range.rb +30 -0
  73. data/lib/active_form/validators/uri.rb +54 -0
  74. data/lib/active_form/version.rb +9 -0
  75. data/lib/active_form/views/fieldsets.rb +34 -0
  76. data/lib/active_form/views/plain.rb +32 -0
  77. data/lib/active_form/views/tables.rb +28 -0
  78. data/lib/active_form/widget.rb +43 -0
  79. data/lib/active_form/widgets/base.rb +28 -0
  80. data/lib/loob/uri_validator.rb +140 -0
  81. data/lib/rails/acts_as_dropdown/MIT-LICENSE +20 -0
  82. data/lib/rails/acts_as_dropdown/acts_as_dropdown.rb +119 -0
  83. data/lib/rails/acts_as_dropdown/dropdown.rb +27 -0
  84. data/lib/rails/controller_helper.rb +19 -0
  85. data/lib/rails/model/loader.rb +206 -0
  86. data/lib/rails/view_helper.rb +20 -0
  87. data/samples/html/css/style.css +175 -0
  88. data/samples/html/js/effects.js +958 -0
  89. data/samples/html/js/prototype.js +2006 -0
  90. data/samples/html/js/validation.js +228 -0
  91. data/samples/html/plain_view.html +77 -0
  92. data/samples/html/sample001.html +158 -0
  93. data/samples/html/sample002.html +76 -0
  94. data/samples/html/sample003.html +34 -0
  95. data/samples/layouts/default.rhtml +18 -0
  96. data/samples/layouts/plain.rhtml +21 -0
  97. data/samples/layouts/sample003.rhtml +25 -0
  98. data/samples/plain_view.rb +58 -0
  99. data/samples/sample001.rb +111 -0
  100. data/samples/sample002.rb +92 -0
  101. data/samples/sample003.rb +30 -0
  102. data/script/destroy +14 -0
  103. data/script/generate +14 -0
  104. data/script/txt2html +74 -0
  105. data/setup.rb +1585 -0
  106. data/tasks/deployment.rake +34 -0
  107. data/tasks/environment.rake +7 -0
  108. data/tasks/website.rake +17 -0
  109. data/test/elements/test_base_element.rb +159 -0
  110. data/test/elements/test_builder_element.rb +81 -0
  111. data/test/elements/test_button_element.rb +12 -0
  112. data/test/elements/test_checkbox_element.rb +233 -0
  113. data/test/elements/test_file_element.rb +20 -0
  114. data/test/elements/test_hidden_element.rb +11 -0
  115. data/test/elements/test_image_element.rb +11 -0
  116. data/test/elements/test_input_element.rb +39 -0
  117. data/test/elements/test_password_element.rb +16 -0
  118. data/test/elements/test_radio_element.rb +197 -0
  119. data/test/elements/test_reset_element.rb +12 -0
  120. data/test/elements/test_section_element.rb +162 -0
  121. data/test/elements/test_select_element.rb +364 -0
  122. data/test/elements/test_submit_element.rb +12 -0
  123. data/test/elements/test_text_element.rb +91 -0
  124. data/test/elements/test_textarea_element.rb +23 -0
  125. data/test/facets/test_checkbox_group_element.rb +388 -0
  126. data/test/facets/test_radio_group_element.rb +312 -0
  127. data/test/facets/test_select_date_element.rb +211 -0
  128. data/test/facets/test_select_datetime_element.rb +56 -0
  129. data/test/facets/test_select_day_element.rb +37 -0
  130. data/test/facets/test_select_from_model_element.rb +86 -0
  131. data/test/facets/test_select_hour_element.rb +37 -0
  132. data/test/facets/test_select_minute_element.rb +52 -0
  133. data/test/facets/test_select_month_element.rb +79 -0
  134. data/test/facets/test_select_numeric_range_element.rb +14 -0
  135. data/test/facets/test_select_second_element.rb +48 -0
  136. data/test/facets/test_select_time_element.rb +148 -0
  137. data/test/facets/test_select_weekday_element.rb +71 -0
  138. data/test/facets/test_select_year_element.rb +73 -0
  139. data/test/fixtures/author.rb +11 -0
  140. data/test/fixtures/authors.yml +0 -0
  141. data/test/fixtures/book.rb +14 -0
  142. data/test/fixtures/books.yml +8 -0
  143. data/test/fixtures/categories.yml +0 -0
  144. data/test/fixtures/categorization.rb +2 -0
  145. data/test/fixtures/categorizations.yml +0 -0
  146. data/test/fixtures/category.rb +8 -0
  147. data/test/fixtures/publisher.rb +5 -0
  148. data/test/fixtures/publishers.yml +10 -0
  149. data/test/fixtures/schema.rb +43 -0
  150. data/test/rails/test_model_autodefinition.rb +121 -0
  151. data/test/rails/test_model_loader.rb +61 -0
  152. data/test/resources/elements/chunky.rb +11 -0
  153. data/test/resources/forms/demo.rb +5 -0
  154. data/test/resources/models/book.rb +8 -0
  155. data/test/resources/models/register_publisher.rb +5 -0
  156. data/test/resources/sections/demo.rb +6 -0
  157. data/test/resources/sections/foo.rb +6 -0
  158. data/test/resources/validators/foo.rb +9 -0
  159. data/test/resources/widgets/custom.rb +13 -0
  160. data/test/test_active_form.rb +1050 -0
  161. data/test/test_casting.rb +124 -0
  162. data/test/test_definition.rb +68 -0
  163. data/test/test_definition_class.rb +118 -0
  164. data/test/test_element_class.rb +201 -0
  165. data/test/test_helper.rb +74 -0
  166. data/test/test_javascript.rb +234 -0
  167. data/test/test_load_definition.rb +68 -0
  168. data/test/test_load_element.rb +35 -0
  169. data/test/test_load_section_element.rb +43 -0
  170. data/test/test_load_validator.rb +31 -0
  171. data/test/test_load_widget.rb +93 -0
  172. data/test/test_validation.rb +722 -0
  173. data/test/validators/test_validates_as_alpha.rb +26 -0
  174. data/test/validators/test_validates_as_alphanum.rb +26 -0
  175. data/test/validators/test_validates_as_digits.rb +26 -0
  176. data/test/validators/test_validates_as_email.rb +29 -0
  177. data/test/validators/test_validates_as_number.rb +26 -0
  178. data/test/validators/test_validates_as_uri.rb +128 -0
  179. data/test/validators/test_validates_with_format.rb +26 -0
  180. data/test/validators/test_validates_within_length_range.rb +46 -0
  181. data/test/validators/test_validates_within_set.rb +46 -0
  182. data/test/validators/test_validates_within_time_range.rb +53 -0
  183. metadata +307 -0
  184. 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,9 @@
1
+ ActiveForm::Validator::Base.create :alpha do
2
+
3
+ default_message "%s: should contain alphabetical characters only"
4
+
5
+ def validate
6
+ element.errors << advice[code] unless element.blank? || value.to_s.match(/^[a-zA-Z]+$/)
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ ActiveForm::Validator::Base.create :alphanum do
2
+
3
+ default_message "%s: should contain alphabetical characters or numbers only"
4
+
5
+ def validate
6
+ element.errors << advice[code] unless element.blank? || value.to_s.match(/^[a-zA-Z0-9]+$/)
7
+ end
8
+
9
+ 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