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,314 @@
1
+ module ActiveForm::Mixins::ElementMethods
2
+
3
+ def self.included(base)
4
+ base.send(:include, ActiveForm::Mixins::AttributeMethods)
5
+ base.send(:extend, ActiveForm::Mixins::ElementMethods::ClassMethods)
6
+ base.send(:include, ActiveForm::Mixins::Casting)
7
+ base.send(:attr_reader, :container)
8
+ base.send(:attr_accessor, :name)
9
+ end
10
+
11
+ def initialize_element(*args)
12
+ attributes = args.last.is_a?(Hash) ? args.pop : {}
13
+ container = args.shift if is_container?(args.first)
14
+ args.unshift(element_type) unless args.first.kind_of?(String) || args.first.kind_of?(Symbol)
15
+ raise ArgumentError if args.empty?
16
+ self.name = ActiveForm::symbolize_name(args.first)
17
+ self.label = self.name.to_s.titleize
18
+ register_container(container) if is_container?(container)
19
+ initialize_properties
20
+ update_options_and_attributes(attributes)
21
+ yield self if block_given?
22
+ end
23
+
24
+ def register_container(container)
25
+ return ArgumentError unless is_container?(container)
26
+ @container = container
27
+ revert_value unless container.bound_value?(self.name)
28
+ define_localizer(container.localizer) if self.container? && container.localized?
29
+ end
30
+ alias :container= :register_container
31
+
32
+ def accept_block(&block)
33
+ self.instance_eval(&block)
34
+ end
35
+
36
+ def identifier
37
+ self.contained? ? "#{container.identifier}_#{self.name}" : "#{self.name}"
38
+ end
39
+
40
+ def element_name
41
+ elem_name = self.contained? ? "#{container.element_name}[#{self.group || self.name}]" : "#{self.group || self.name}"
42
+ elem_name << '[]' unless self.group.blank?
43
+ elem_name
44
+ end
45
+
46
+ def element_type
47
+ self.class.element_type
48
+ end
49
+
50
+ def label
51
+ return (localize(name, 'label') || @label) if localized?
52
+ @label
53
+ end
54
+
55
+ def title
56
+ return (localize(name, 'title') || attributes[:title]) if localized?
57
+ attributes[:title]
58
+ end
59
+
60
+ def description
61
+ return (localize(name, 'description') || @description) if localized?
62
+ @description
63
+ end
64
+
65
+ def element_binding
66
+ element_value
67
+ end
68
+
69
+ def element_binding_key
70
+ self.name
71
+ end
72
+
73
+ def default_value
74
+ nil
75
+ end
76
+
77
+ def fallback_value
78
+ @fallback_value || default_value
79
+ end
80
+
81
+ def fallback_value=(value)
82
+ @fallback_value = value
83
+ end
84
+ alias :default= :fallback_value=
85
+
86
+ def export_value
87
+ blank? ? cast_value(fallback_value || default_value) : element_value
88
+ end
89
+
90
+ def frozen_value
91
+ @frozen_value.blank? ? freeze_value(element_value) : @frozen_value
92
+ end
93
+
94
+ def frozen_value=(value)
95
+ @frozen_value = value
96
+ end
97
+
98
+ def formatted_value
99
+ return frozen_value if frozen? && !frozen_value.blank?
100
+ format_value(element_value)
101
+ end
102
+
103
+ def element_value(export = false)
104
+ return export_value if export
105
+ if self.contained?
106
+ revert_value unless container.bound_value?(element_binding_key)
107
+ container.get_bound_value(element_binding_key)
108
+ else
109
+ @element_value ||= default_value
110
+ end
111
+ end
112
+ alias :values :element_value
113
+ alias :value :element_value
114
+
115
+ def element_value=(value, force = false)
116
+ value = cast_value(value)
117
+ if self.contained?
118
+ container.set_bound_value(element_binding_key, value)
119
+ else
120
+ @element_value = value
121
+ end
122
+ end
123
+
124
+ alias :update_from_params :element_value=
125
+ alias :params= :element_value=
126
+
127
+ alias :initial_value= :element_value=
128
+ alias :update_value :element_value=
129
+
130
+ alias :values= :element_value=
131
+ alias :value= :element_value=
132
+
133
+ alias :binding= :element_value=
134
+ alias :bind_to :element_value=
135
+
136
+ def revert_value
137
+ if self.contained?
138
+ container.set_bound_value(element_binding_key, default_value)
139
+ else
140
+ @element_value = default_value
141
+ end
142
+ end
143
+
144
+ def element_attributes
145
+ attrs = attribute_names.inject(default_attributes) do |hash, attribute|
146
+ value = send(attribute) rescue nil
147
+ hash[attribute] = value unless value.blank?
148
+ hash
149
+ end
150
+ final = attrs.merge(attributes).merge(html_flag_attributes).merge(option_flag_attributes).stringify_keys.delete_blanks
151
+ if skip_css_class? && !(vcss = validation_css_class.to_s).blank?
152
+ final['class'] = vcss
153
+ end
154
+ final.delete('style') if skip_css_style?
155
+ final
156
+ end
157
+
158
+ def update_options_and_attributes(hash)
159
+ last_pass_options = ['options', 'option', 'multiple', 'binding', 'initial_value', 'fallback_value', 'checked']
160
+ ordered_options = [*self.class.element_html_flag_names] + [*self.class.element_attribute_names]
161
+ ordered_options.map!(&:to_s)
162
+ hash.stringify_keys!
163
+ self.type_cast = hash.delete('type_cast') if hash.key?('type_cast')
164
+ hash['fallback_value'] = hash.delete('default') if hash.key?('default')
165
+ hash['initial_value'] = hash.delete('values') if hash.key?('values')
166
+ hash['initial_value'] = hash.delete('value') if hash.key?('value')
167
+ (((hash.keys & ordered_options) - last_pass_options) + (last_pass_options & hash.keys)).each do |option|
168
+ send("#{option}=", hash[option]) rescue nil
169
+ hash.delete(option)
170
+ end
171
+ hash.each { |option, value| send("#{option}=", value) rescue nil }
172
+ end
173
+ alias :update :update_options_and_attributes
174
+
175
+ def freeze_element
176
+ self.frozen = true
177
+ end
178
+ alias :freeze! :freeze_element
179
+
180
+ def hide_element
181
+ self.hidden = true
182
+ end
183
+ alias :hide! :hide_element
184
+
185
+ # stub implementations:
186
+
187
+ def render_frozen(builder = create_builder)
188
+ raise ActiveForm::StubException
189
+ end
190
+
191
+ def render_element(builder = create_builder)
192
+ raise ActiveForm::StubException
193
+ end
194
+
195
+ def contained?
196
+ @container ||= nil
197
+ (@container && @container.container?) || false
198
+ end
199
+
200
+ def labelled?
201
+ true
202
+ end
203
+
204
+ def hidden?
205
+ (option_flags[:hidden] == true)
206
+ end
207
+
208
+ def frozen?
209
+ (option_flags[:frozen] == true) || (contained? && container.frozen?)
210
+ end
211
+
212
+ def disabled?
213
+ (option_flags[:disabled] == true) || (contained? && container.disabled?)
214
+ end
215
+
216
+ def readonly?
217
+ (option_flags[:readonly] == true) || (contained? && container.readonly?)
218
+ end
219
+
220
+ def required=(value)
221
+ self.option_flags[:required] = value.to_s.to_boolean
222
+ if self.option_flags[:required]
223
+ validates_as_required
224
+ else
225
+ validators.delete_if { |v| v.code == 'required' }
226
+ end
227
+ end
228
+
229
+ def required?
230
+ (option_flags[:required] == true) || (contained? && container.required?)
231
+ end
232
+
233
+ def localized?
234
+ contained? && container.localized?
235
+ end
236
+
237
+ def localize(*args)
238
+ container.localizer.call(container.identifier, *args) if localized?
239
+ end
240
+
241
+ def format_value(value)
242
+ if self.respond_to?(:formatting_filter)
243
+ self.formatting_filter(element_value).to_s rescue element_value
244
+ elsif self.class.respond_to?(:formatting_filter)
245
+ self.class.formatting_filter(element_value).to_s rescue element_value
246
+ else
247
+ element_value.to_s
248
+ end
249
+ end
250
+
251
+ def define_formatting_filter(prc = nil, &block)
252
+ define_singleton_method(:formatting_filter, &(block_given? ? block : prc))
253
+ end
254
+ alias :formatting_filter= :define_formatting_filter
255
+
256
+ def reset_formatting_filter
257
+ define_singleton_method(:formatting_filter) rescue nil
258
+ end
259
+
260
+ def freeze_value(value)
261
+ if self.respond_to?(:freeze_filter)
262
+ self.freeze_filter(element_value).to_s rescue element_value
263
+ elsif self.class.respond_to?(:freeze_filter)
264
+ self.class.freeze_filter(element_value).to_s rescue element_value
265
+ else
266
+ element_value.to_s
267
+ end
268
+ end
269
+
270
+ def define_freeze_filter(prc = nil, &block)
271
+ define_singleton_method(:freeze_filter, &(block_given? ? block : prc))
272
+ end
273
+ alias :freeze_filter= :define_freeze_filter
274
+
275
+ def reset_freeze_filter
276
+ define_singleton_method(:freeze_filter) rescue nil
277
+ end
278
+
279
+ module ClassMethods
280
+
281
+ def element_type
282
+ self.name.to_s.demodulize.underscore.to_sym
283
+ end
284
+ alias :loadable_type :element_type
285
+
286
+ def type_classname(definition_name)
287
+ "#{definition_name}".camelize
288
+ end
289
+
290
+ def define_standard_option_flags
291
+ define_option_flags(:frozen, :hidden, :disabled, :readonly, :required, :skip_css_class, :skip_css_style)
292
+ end
293
+
294
+ def define_formatting_filter(prc = nil, &block)
295
+ define_singleton_method(:formatting_filter, &(block_given? ? block : prc))
296
+ end
297
+ alias :formatting_filter= :define_formatting_filter
298
+
299
+ def reset_formatting_filter
300
+ define_singleton_method(:formatting_filter) rescue nil
301
+ end
302
+
303
+ def define_freeze_filter(prc = nil, &block)
304
+ define_singleton_method(:freeze_filter, &(block_given? ? block : prc))
305
+ end
306
+ alias :freeze_filter= :define_freeze_filter
307
+
308
+ def reset_freeze_filter
309
+ define_singleton_method(:freeze_filter) rescue nil
310
+ end
311
+
312
+ end
313
+
314
+ end
@@ -0,0 +1,99 @@
1
+ module ActiveForm::Mixins::JavascriptMethods
2
+
3
+ EVENTS = [:onsubmit, :onreset, :onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover,
4
+ :onmousemove, :onmouseout, :onkeypress, :onkeydown, :onkeyup, :onblur, :onfocus, :onchange]
5
+
6
+ EVENTS.each do |event|
7
+ define_method("#{event}") { self.javascript_events[event] }
8
+ define_method("#{event}?") { !self.javascript_events[event].blank? }
9
+ define_method("#{event}=") { |js| self.javascript_events[event] = js }
10
+ module_eval %{ def inline_#{event}; #{event}? ? "#{event}=\#{self.javascript_events[:#{event}].to_json}" : nil; end }
11
+ module_eval %{ def #{event}_event; self.javascript_events[:#{event}] = (yield(self.identifier)).to_s if block_given?; end }
12
+ end
13
+
14
+ def default_javascript
15
+ end
16
+
17
+ def internal_javascript(tag = false)
18
+ @internal_js ||= JavascriptAttribute.new
19
+ return @internal_js unless tag
20
+ @internal_js.empty? ? nil : javascript_tag(@internal_js.to_s)
21
+ end
22
+
23
+ def internal_javascript=(string_or_array)
24
+ internal_javascript.replace(string_or_array)
25
+ end
26
+
27
+ def javascript_events
28
+ @javascript_events ||= HashWithIndifferentAccess.new
29
+ end
30
+
31
+ def javascript(tag = false)
32
+ @javascript_attribute ||= JavascriptAttribute.new.push(default_javascript).compact
33
+ return @javascript_attribute unless tag
34
+ @javascript_attribute.empty? ? nil : javascript_tag(@javascript_attribute.to_s)
35
+ end
36
+
37
+ def javascript=(string_or_array)
38
+ javascript.replace(string_or_array)
39
+ end
40
+
41
+ def javascript?
42
+ !(javascript.blank? && javascript_events.empty? && internal_javascript.empty? && javascript_validation_code.blank?) || container?
43
+ end
44
+
45
+ def javascript_var
46
+ "f#{self.element_type}_#{self.identifier}"
47
+ end
48
+
49
+ def script_tag
50
+ element_javascript(true)
51
+ end
52
+
53
+ def element_javascript(tag = false)
54
+ return '' unless javascript?
55
+ elem_var = javascript_var
56
+ js = (internal_javascript.empty? ? '' : " #{internal_javascript};\n")
57
+ unless (jsvalidation = javascript_validation_code).blank?
58
+ js << " #{jsvalidation}\n"
59
+ end
60
+ unless (jsvalidationdef = validation_javascript_definitions).blank?
61
+ js << "#{jsvalidationdef.gsub(/^/, ' ')}\n"
62
+ end
63
+ js << (javascript.blank? ? '' : " #{javascript};\n")
64
+ js << javascript_events.stringify_keys.keys.sort.inject('') do |ary, key|
65
+ ary << " Event.observe(#{elem_var},'#{key.from(2)}',function(ev){ #{javascript_events[key]}; });\n"
66
+ end unless javascript_events.empty?
67
+ js << elements.inject('') do |ejs, elem|
68
+ if elem.javascript? && !(s = elem.element_javascript).match(/^(\s+)?$/)
69
+ ejs << "#{s.gsub(/^/, ' ')}\n"
70
+ end
71
+ ejs
72
+ end if container?
73
+ js << " new Validation(#{elem_var}, #{options_for_javascript(client_side_options)});\n" if client_side? && container? && !contained?
74
+ return '' if js.match(/^(\s+)?$/)
75
+ str = "var #{elem_var}=$('#{self.identifier}');if(#{elem_var}){\n#{js}}"
76
+ tag ? javascript_tag(str) : str
77
+ end
78
+ alias :js :element_javascript
79
+ alias :script :element_javascript
80
+
81
+ def inline_javascript
82
+ self.javascript_events.inject([]) { |ary, (event, code)| ary << send("inline_#{event}") unless code.blank?; ary }.compact.sort.join(' ')
83
+ end
84
+
85
+ protected
86
+
87
+ def javascript_tag(js)
88
+ "<script type=\"text/javascript\" charset=\"utf-8\">//<![CDATA[\n#{js}\n//]]>\n</script>\n"
89
+ end
90
+
91
+ def escape_javascript(javascript)
92
+ (javascript || '').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
93
+ end
94
+
95
+ def options_for_javascript(options)
96
+ '{' + options.map {|k, v| "#{k}:#{v}"}.sort.join(', ') + '}'
97
+ end
98
+
99
+ end
@@ -0,0 +1,72 @@
1
+ module ActiveForm::Mixins::LoaderMethods
2
+
3
+ def self.included(base)
4
+ base.send(:extend, ActiveForm::Mixins::LoaderMethods::ClassMethods)
5
+ end
6
+
7
+ class NotFoundException < StandardError #:nodoc:
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ def register(elem_class)
13
+ raise ActiveForm::StubException
14
+ end
15
+
16
+ def instance(klass, *args, &block)
17
+ raise ActiveForm::StubException
18
+ end
19
+
20
+ def build(definition_name, *args, &block)
21
+ if klass = self.get(definition_name)
22
+ return instance(definition_name, klass, *args, &block)
23
+ end
24
+ nil
25
+ end
26
+
27
+ def get(type, &block)
28
+ load(type) rescue nil unless loaded?(type)
29
+ klass = self.const_get(type_classname(type)) rescue nil
30
+ klass.module_eval(&block) if klass && block_given?
31
+ klass
32
+ end
33
+ alias :modify :get
34
+
35
+ def load(type)
36
+ self.load_paths.reverse.each do |dir|
37
+ loadable_file = ::File.join(dir, "#{type_filename(type)}.rb")
38
+ require loadable_file if ::File.exists?(loadable_file)
39
+ end
40
+ raise NotFoundException unless self.loaded?(type)
41
+ true
42
+ end
43
+
44
+ def exists?(type)
45
+ load(type) rescue nil unless loaded?(type)
46
+ loaded?(type)
47
+ end
48
+
49
+ def loaded?(type)
50
+ self.const_defined?(type_classname(type))
51
+ end
52
+
53
+ def type_filename(type)
54
+ type.to_s.camelize.underscore
55
+ end
56
+
57
+ def type_classname(type)
58
+ type.to_s.camelize
59
+ end
60
+
61
+ def const_missing(type)
62
+ begin
63
+ load(type) && get(type)
64
+ rescue NotFoundException
65
+ rescue
66
+ super
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ end