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,37 @@
1
+ class ActiveForm::Element::Section
2
+
3
+ include ActiveForm::Mixins::CommonMethods
4
+ include ActiveForm::Mixins::ElementMethods
5
+ include ActiveForm::Mixins::ContainerMethods
6
+
7
+ inheritable_set :element_attribute_names, :element_option_flag_names, :element_html_flag_names
8
+
9
+ define_standard_option_flags
10
+
11
+ define_attributes :title
12
+
13
+ def render_label(builder = create_builder)
14
+ builder.span(label, label_attributes)
15
+ end
16
+
17
+ def render_frozen(builder = create_builder)
18
+ render_element(builder)
19
+ end
20
+
21
+ def render_element(builder = create_builder)
22
+ render_elements(builder)
23
+ end
24
+
25
+ def render_elements(builder = create_builder, &block)
26
+ elements.each { |elem| elem.to_html(builder, &block) }
27
+ end
28
+
29
+ def label_attributes
30
+ { :class => label_css }
31
+ end
32
+
33
+ def self.element_type
34
+ :section
35
+ end
36
+
37
+ end
@@ -0,0 +1,42 @@
1
+ ActiveForm::Element::Base::create :select do
2
+
3
+ include ActiveForm::Mixins::CollectionElementMethods
4
+
5
+ define_attributes :size
6
+ define_html_flags :multiple
7
+ define_option_flags :include_empty
8
+
9
+ def selected_attr(option)
10
+ (selected_value?(option) ? 'selected' : nil)
11
+ end
12
+
13
+ def default_attributes
14
+ attrs = Hash.new
15
+ attrs[:disabled] = 'disabled' if disabled?
16
+ super.merge(attrs)
17
+ end
18
+
19
+ def render_frozen(builder = create_builder)
20
+ return builder.span('-', :class => 'blank') if formatted_value.blank?
21
+ builder.text!(selected_option_label)
22
+ end
23
+
24
+ def render_element(builder = create_builder)
25
+ builder.select(element_attributes) do
26
+ options_to_render = options.uniq
27
+ options_to_render.unshift(ActiveForm::Element::CollectionOption.new('--', :blank)) if include_empty?
28
+ options_to_render.each do |opt|
29
+ if opt.kind_of?(ActiveForm::Element::CollectionOptionGroup)
30
+ builder.optgroup(:label => opt.label) do
31
+ opt.options.uniq.each do |o|
32
+ builder.option(o.label, { :value => o.value, :selected => selected_attr(o.value) })
33
+ end
34
+ end
35
+ else
36
+ builder.option(opt.label, { :value => opt.value, :selected => selected_attr(opt.value) })
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,19 @@
1
+ ActiveForm::Element::Input::create :submit do
2
+
3
+ def default_attributes
4
+ super.merge(:type => 'submit')
5
+ end
6
+
7
+ def element_attributes
8
+ super.merge('value' => label)
9
+ end
10
+
11
+ def render_frozen(builder = create_builder)
12
+ builder.span(label, :class => 'blank')
13
+ end
14
+
15
+ def labelled?
16
+ false
17
+ end
18
+
19
+ end
@@ -0,0 +1,9 @@
1
+ ActiveForm::Element::Input::create :text do
2
+
3
+ define_attributes :maxlength, :size
4
+
5
+ def default_attributes
6
+ super.merge(:type => 'text', :size => 30)
7
+ end
8
+
9
+ end
@@ -0,0 +1,18 @@
1
+ ActiveForm::Element::Base::create :textarea do
2
+
3
+ define_attributes :rows, :cols
4
+
5
+ def render_element(builder = create_builder)
6
+ builder.textarea(formatted_value, element_attributes)
7
+ end
8
+
9
+ def default_attributes
10
+ attrs = Hash.new
11
+ attrs[:rows] = 20
12
+ attrs[:cols] = 40
13
+ attrs[:disabled] = 'disabled' if disabled?
14
+ attrs[:readonly] = 'readonly' if readonly?
15
+ super.merge(attrs)
16
+ end
17
+
18
+ end
@@ -0,0 +1,73 @@
1
+ module ActiveForm
2
+
3
+ class Error
4
+
5
+ attr_accessor :code, :msg, :element
6
+
7
+ def initialize(element, msg, code = 'default', params = [])
8
+ msg = element.format_message(msg, code, params)
9
+ self.element, self.msg, self.code = element, msg, code.to_s
10
+ end
11
+
12
+ alias :message :msg
13
+
14
+ def identifier
15
+ self.code == 'required' ? code : "validate-#{code}"
16
+ end
17
+
18
+ end
19
+
20
+ class Errors
21
+ include Enumerable
22
+
23
+ @@default_msg = 'A validation error occurred'
24
+
25
+ attr_reader :element
26
+
27
+ def initialize(element)
28
+ @errors, @element = [], element
29
+ end
30
+
31
+ def add(msg = @@default_msg, error_code = 'default', params = [])
32
+ @errors << ActiveForm::Error.new(element, msg, error_code, params)
33
+ end
34
+
35
+ def <<(error)
36
+ @errors << error if error.kind_of?(ActiveForm::Error)
37
+ end
38
+
39
+ def valid?
40
+ errors.empty?
41
+ end
42
+
43
+ def first
44
+ errors.first
45
+ end
46
+
47
+ def errors
48
+ @errors ||= []
49
+ end
50
+ alias :all :errors
51
+
52
+ def at(index)
53
+ errors.at(index)
54
+ end
55
+ alias :[] :at
56
+
57
+ def each(&block)
58
+ @errors.each { |error| block.call(error) }
59
+ end
60
+
61
+ def clear
62
+ @errors.clear
63
+ end
64
+ alias :reset :clear
65
+
66
+ def length
67
+ @errors.length
68
+ end
69
+ alias :size :length
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,11 @@
1
+ ActiveForm::Element::CollectionInput::create :checkbox_group do
2
+
3
+ def multiple?
4
+ true
5
+ end
6
+
7
+ def input_element_type
8
+ :checkbox
9
+ end
10
+
11
+ end
@@ -0,0 +1,96 @@
1
+ ActiveForm::Element::Base::create :collection_input do
2
+
3
+ include ActiveForm::Mixins::CollectionElementMethods
4
+
5
+ attr_accessor :columns
6
+
7
+ define_option_flags :legend, :render_empty
8
+
9
+ def self.group?
10
+ true
11
+ end
12
+
13
+ def multiple?
14
+ true
15
+ end
16
+
17
+ def input_element_type
18
+ :text
19
+ end
20
+
21
+ def in_columns?
22
+ self.columns.to_i > 1
23
+ end
24
+
25
+ def each_option_column(&block)
26
+ return self.options unless in_columns? && block_given?
27
+ cols = self.columns.to_i
28
+ partitioned_options = options
29
+ options.length.modulo(cols).times { partitioned_options << nil }
30
+ partitioned_options.in_groups_of(options.length/cols, &block)
31
+ end
32
+
33
+ def selected_attr(option)
34
+ (selected_value?(option) ? 'checked' : nil)
35
+ end
36
+
37
+ def default_attributes
38
+ { :id => identifier, :class => css }
39
+ end
40
+
41
+ def input_element_attributes
42
+ attrs = { :type => input_element_type, :class => "elem_#{input_element_type}", :name => self.element_name }
43
+ attrs[:disabled] = 'disabled' if disabled?
44
+ attrs
45
+ end
46
+
47
+ def render_frozen(builder = create_builder)
48
+ return builder.span('-', :class => 'blank') if formatted_value.blank?
49
+ builder.text!(selected_option_label)
50
+ end
51
+
52
+ def render_element(builder = create_builder)
53
+ if in_columns?
54
+ colcount = 0
55
+ builder.fieldset(element_attributes) do
56
+ builder.legend(label) if legend?
57
+ each_option_column do |col|
58
+ colcount += 1
59
+ builder.div(:class => "column column-#{colcount}") {
60
+ col.each { |opt| render_collection_element(opt, builder) }
61
+ }
62
+ end
63
+ end
64
+ else
65
+ builder.fieldset(element_attributes) do
66
+ builder.legend(label) if legend?
67
+ options.each { |opt| render_collection_element(opt, builder) }
68
+ end
69
+ end
70
+ end
71
+
72
+ def render_collection_element(option, builder = create_builder)
73
+ if option.kind_of?(ActiveForm::Element::CollectionOptionGroup)
74
+ builder.fieldset(:class => 'options') do
75
+ builder.legend(option.label) if legend?
76
+ option.options.each { |opt| render_collection_element(opt, builder) }
77
+ end
78
+ else
79
+ render_input_element(option, builder)
80
+ end
81
+ end
82
+
83
+ def render_input_element(option, builder = create_builder)
84
+ unless option.nil? && !render_empty?
85
+ class_name = option.nil? ? 'empty-elem' : 'elem'
86
+ builder.span(:class => class_name) {
87
+ unless option.nil?
88
+ id = "#{self.identifier}_#{value_to_identifier(option.label)}"
89
+ builder.input(input_element_attributes.merge(:id => id, :value => option.value, :checked => selected_attr(option.value)))
90
+ builder.label(option.label, :for => id)
91
+ end
92
+ }
93
+ end
94
+ end
95
+
96
+ end
@@ -0,0 +1,11 @@
1
+ ActiveForm::Element::CollectionInput::create :radio_group do
2
+
3
+ def multiple?
4
+ false
5
+ end
6
+
7
+ def input_element_type
8
+ :radio
9
+ end
10
+
11
+ end
@@ -0,0 +1,10 @@
1
+ class ActiveForm::Element::SelectDate < ActiveForm::Element::SelectTimebased
2
+
3
+ self.default_format = [:month, :day, :year]
4
+ self.allowed_parts = [:month, :day, :year]
5
+
6
+ def self.element_type
7
+ :select_date
8
+ end
9
+
10
+ end
@@ -0,0 +1,10 @@
1
+ class ActiveForm::Element::SelectDatetime < ActiveForm::Element::SelectTimebased
2
+
3
+ self.default_format = [:month, :day, :year, :hour, :minute]
4
+ self.allowed_parts = [:month, :day, :year, :hour, :minute, :second]
5
+
6
+ def self.element_type
7
+ :select_datetime
8
+ end
9
+
10
+ end
@@ -0,0 +1,17 @@
1
+ ActiveForm::Element::SelectNumericRange::create :select_day do
2
+
3
+ def range
4
+ (1..31)
5
+ end
6
+
7
+ def casting_filter(value)
8
+ value = case value
9
+ when Date then value.mday
10
+ when Time then value.day
11
+ when Array, Range then value.to_a
12
+ else value.to_i rescue 0
13
+ end
14
+ super(value)
15
+ end
16
+
17
+ end
@@ -0,0 +1,60 @@
1
+ # In case you need a specific select for a model you could also do:
2
+ #
3
+ # ActiveForm::Element::Select::create :select_country do
4
+ #
5
+ # def options
6
+ # Model.find(:all).map { |item| ActiveForm::Element::CollectionOption.new(item.name, item.id) }
7
+ # end
8
+ #
9
+ # end
10
+
11
+ ActiveForm::Element::Select::create :select_from_model do
12
+
13
+ attr_accessor :model, :find_options, :label_attr, :value_attr, :group_attr
14
+
15
+ define_option_flags :to_dropdown
16
+
17
+ def model_class
18
+ (@model || self.name.to_s.sub(/_id$/, '')).to_s.classify
19
+ end
20
+
21
+ def label_attr
22
+ @label_attr ||= :name
23
+ end
24
+
25
+ def value_attr
26
+ @value_attr ||= :id
27
+ end
28
+
29
+ def find_options
30
+ @find_options ||= { :select => "#{label_attr}, #{value_attr}", :order => "#{label_attr}, #{value_attr}" }
31
+ end
32
+
33
+ alias :find= :find_options=
34
+
35
+ def options
36
+ opts = []
37
+ opts << ActiveForm::Element::CollectionOption.new('--', :blank) if include_empty?
38
+ model = self.model_class.constantize rescue nil
39
+ return opts unless !model.nil? && model < ActiveRecord::Base
40
+ if model.respond_to?(:to_dropdown) && to_dropdown?
41
+ model.to_dropdown.each { |(label, value)| opts << ActiveForm::Element::CollectionOption.new(label, value) }
42
+ else
43
+ items = model.find(:all, find_options)
44
+ if !group_attr.nil? && items.first.respond_to?(group_attr)
45
+ attrib = group_attr.to_sym
46
+ items.group_by { |item| item.send(attrib) }.each do |label, values|
47
+ opts << ActiveForm::Element::CollectionOptionGroup.new(label) do |g|
48
+ values.each { |item| g << ActiveForm::Element::CollectionOption.new(item.send(label_attr), item.send(value_attr)) }
49
+ end
50
+ end
51
+ else
52
+ items.each do |item|
53
+ opts << ActiveForm::Element::CollectionOption.new(item.send(label_attr), item.send(value_attr))
54
+ end
55
+ end
56
+ end
57
+ opts
58
+ end
59
+
60
+ end
@@ -0,0 +1,17 @@
1
+ ActiveForm::Element::SelectNumericRange::create :select_hour do
2
+
3
+ def range
4
+ (0..23)
5
+ end
6
+
7
+ def casting_filter(value)
8
+ value = case value
9
+ when Date then value.to_time.hour
10
+ when Time then value.hour
11
+ when Array, Range then value.to_a
12
+ else value.to_i rescue 0
13
+ end
14
+ super(value)
15
+ end
16
+
17
+ end