merb-helpers 0.9.8

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 (192) hide show
  1. data/LICENSE +20 -0
  2. data/README +180 -0
  3. data/Rakefile +77 -0
  4. data/TODO +5 -0
  5. data/lib/merb-helpers.rb +38 -0
  6. data/lib/merb-helpers/core_ext.rb +57 -0
  7. data/lib/merb-helpers/core_ext/numeric.rb +388 -0
  8. data/lib/merb-helpers/date_time_formatting.rb +127 -0
  9. data/lib/merb-helpers/date_time_helpers.rb +190 -0
  10. data/lib/merb-helpers/form/builder.rb +410 -0
  11. data/lib/merb-helpers/form/helpers.rb +448 -0
  12. data/lib/merb-helpers/form_helpers.rb +24 -0
  13. data/lib/merb-helpers/tag_helpers.rb +61 -0
  14. data/lib/merb-helpers/text_helpers.rb +61 -0
  15. data/lib/merb-helpers/time_dsl.rb +59 -0
  16. data/spec/core_ext_spec.rb +19 -0
  17. data/spec/fixture/app/controllers/application.rb +4 -0
  18. data/spec/fixture/app/controllers/bound_check_box.rb +2 -0
  19. data/spec/fixture/app/controllers/bound_file_field.rb +2 -0
  20. data/spec/fixture/app/controllers/bound_hidden_field.rb +2 -0
  21. data/spec/fixture/app/controllers/bound_option_tag.rb +2 -0
  22. data/spec/fixture/app/controllers/bound_password_field.rb +2 -0
  23. data/spec/fixture/app/controllers/bound_radio_button.rb +2 -0
  24. data/spec/fixture/app/controllers/bound_radio_group.rb +2 -0
  25. data/spec/fixture/app/controllers/bound_select.rb +2 -0
  26. data/spec/fixture/app/controllers/bound_text_area.rb +2 -0
  27. data/spec/fixture/app/controllers/bound_text_field.rb +2 -0
  28. data/spec/fixture/app/controllers/button.rb +2 -0
  29. data/spec/fixture/app/controllers/check_box.rb +2 -0
  30. data/spec/fixture/app/controllers/custom_builder.rb +2 -0
  31. data/spec/fixture/app/controllers/delete_button.rb +2 -0
  32. data/spec/fixture/app/controllers/exceptions.rb +25 -0
  33. data/spec/fixture/app/controllers/field_set.rb +2 -0
  34. data/spec/fixture/app/controllers/fields_for.rb +3 -0
  35. data/spec/fixture/app/controllers/file_field.rb +2 -0
  36. data/spec/fixture/app/controllers/foo.rb +23 -0
  37. data/spec/fixture/app/controllers/form.rb +2 -0
  38. data/spec/fixture/app/controllers/form_for.rb +2 -0
  39. data/spec/fixture/app/controllers/hidden_field.rb +2 -0
  40. data/spec/fixture/app/controllers/label.rb +3 -0
  41. data/spec/fixture/app/controllers/numeric_ext.rb +3 -0
  42. data/spec/fixture/app/controllers/option_tag.rb +2 -0
  43. data/spec/fixture/app/controllers/password_field.rb +2 -0
  44. data/spec/fixture/app/controllers/radio_button.rb +2 -0
  45. data/spec/fixture/app/controllers/radio_group.rb +2 -0
  46. data/spec/fixture/app/controllers/select.rb +2 -0
  47. data/spec/fixture/app/controllers/specs_controller.rb +11 -0
  48. data/spec/fixture/app/controllers/submit.rb +2 -0
  49. data/spec/fixture/app/controllers/tag_helper.rb +21 -0
  50. data/spec/fixture/app/controllers/text_area.rb +2 -0
  51. data/spec/fixture/app/controllers/text_field.rb +3 -0
  52. data/spec/fixture/app/helpers/global_helpers.rb +8 -0
  53. data/spec/fixture/app/models/fake_dm_model.rb +25 -0
  54. data/spec/fixture/app/models/first_generic_fake_model.rb +57 -0
  55. data/spec/fixture/app/models/second_generic_fake_model.rb +18 -0
  56. data/spec/fixture/app/models/third_generic_fake_model.rb +3 -0
  57. data/spec/fixture/app/views/bound_check_box_specs/basic.html.erb +4 -0
  58. data/spec/fixture/app/views/bound_check_box_specs/checked.html.erb +4 -0
  59. data/spec/fixture/app/views/bound_check_box_specs/errors.html.erb +4 -0
  60. data/spec/fixture/app/views/bound_check_box_specs/label.html.erb +3 -0
  61. data/spec/fixture/app/views/bound_check_box_specs/on_and_off.html.erb +3 -0
  62. data/spec/fixture/app/views/bound_check_box_specs/raise_value_error.html.erb +3 -0
  63. data/spec/fixture/app/views/bound_file_field_specs/additional_attributes.html.erb +3 -0
  64. data/spec/fixture/app/views/bound_file_field_specs/takes_string.html.erb +3 -0
  65. data/spec/fixture/app/views/bound_file_field_specs/with_label.html.erb +3 -0
  66. data/spec/fixture/app/views/bound_hidden_field_specs/basic.html.erb +3 -0
  67. data/spec/fixture/app/views/bound_hidden_field_specs/errors.html.erb +3 -0
  68. data/spec/fixture/app/views/bound_hidden_field_specs/hidden_error.html.erb +3 -0
  69. data/spec/fixture/app/views/bound_hidden_field_specs/label.html.erb +3 -0
  70. data/spec/fixture/app/views/bound_option_tag_specs/grouped.html.erb +3 -0
  71. data/spec/fixture/app/views/bound_option_tag_specs/nested.html.erb +3 -0
  72. data/spec/fixture/app/views/bound_option_tag_specs/text_and_value.html.erb +4 -0
  73. data/spec/fixture/app/views/bound_password_field_specs/attributes.html.erb +3 -0
  74. data/spec/fixture/app/views/bound_password_field_specs/basic.html.erb +3 -0
  75. data/spec/fixture/app/views/bound_password_field_specs/label.html.erb +3 -0
  76. data/spec/fixture/app/views/bound_radio_button_specs/basic.html.erb +3 -0
  77. data/spec/fixture/app/views/bound_radio_group_specs/basic.html.erb +3 -0
  78. data/spec/fixture/app/views/bound_radio_group_specs/hashes.html.erb +3 -0
  79. data/spec/fixture/app/views/bound_radio_group_specs/mixed.html.erb +4 -0
  80. data/spec/fixture/app/views/bound_radio_group_specs/override_id.html.erb +3 -0
  81. data/spec/fixture/app/views/bound_select_specs/basic.html.erb +3 -0
  82. data/spec/fixture/app/views/bound_select_specs/blank.html.erb +3 -0
  83. data/spec/fixture/app/views/bound_select_specs/multiple.html.erb +3 -0
  84. data/spec/fixture/app/views/bound_select_specs/prompt.html.erb +3 -0
  85. data/spec/fixture/app/views/bound_select_specs/with_options.html.erb +3 -0
  86. data/spec/fixture/app/views/bound_select_specs/with_options_with_blank.html.erb +3 -0
  87. data/spec/fixture/app/views/bound_text_area_specs/basic.html.erb +3 -0
  88. data/spec/fixture/app/views/bound_text_field_specs/basic.html.erb +3 -0
  89. data/spec/fixture/app/views/button_specs/button_with_label.html.erb +1 -0
  90. data/spec/fixture/app/views/button_specs/button_with_values.html.erb +1 -0
  91. data/spec/fixture/app/views/button_specs/disabled_button.html.erb +1 -0
  92. data/spec/fixture/app/views/check_box_specs/basic.html.erb +1 -0
  93. data/spec/fixture/app/views/check_box_specs/boolean.html.erb +1 -0
  94. data/spec/fixture/app/views/check_box_specs/disabled.html.erb +1 -0
  95. data/spec/fixture/app/views/check_box_specs/label.html.erb +1 -0
  96. data/spec/fixture/app/views/check_box_specs/on_off_is_boolean.html.erb +1 -0
  97. data/spec/fixture/app/views/check_box_specs/raise_unless_both_on_and_off.html.erb +2 -0
  98. data/spec/fixture/app/views/check_box_specs/raises_error_if_not_boolean.html.erb +1 -0
  99. data/spec/fixture/app/views/check_box_specs/raises_error_if_on_off_and_boolean_false.html.erb +1 -0
  100. data/spec/fixture/app/views/check_box_specs/simple.html.erb +1 -0
  101. data/spec/fixture/app/views/check_box_specs/to_string.html.erb +8 -0
  102. data/spec/fixture/app/views/check_box_specs/unchecked.html.erb +2 -0
  103. data/spec/fixture/app/views/custom_builder_specs/everything.html.erb +10 -0
  104. data/spec/fixture/app/views/delete_button_specs/delete_with_explicit_url.html.erb +1 -0
  105. data/spec/fixture/app/views/delete_button_specs/delete_with_extra_params.html.erb +1 -0
  106. data/spec/fixture/app/views/delete_button_specs/delete_with_label.html.erb +1 -0
  107. data/spec/fixture/app/views/delete_button_specs/simple_delete.html.erb +1 -0
  108. data/spec/fixture/app/views/exeptions/client_error.html.erb +37 -0
  109. data/spec/fixture/app/views/exeptions/internal_server_error.html.erb +216 -0
  110. data/spec/fixture/app/views/exeptions/not_acceptable.html.erb +38 -0
  111. data/spec/fixture/app/views/exeptions/not_found.html.erb +40 -0
  112. data/spec/fixture/app/views/fields_for_specs/basic.html.erb +3 -0
  113. data/spec/fixture/app/views/fields_for_specs/midstream.html.erb +7 -0
  114. data/spec/fixture/app/views/fields_for_specs/nil.html.erb +3 -0
  115. data/spec/fixture/app/views/fieldset_specs/legend.html.erb +3 -0
  116. data/spec/fixture/app/views/file_field_specs/disabled.html.erb +1 -0
  117. data/spec/fixture/app/views/file_field_specs/makes_multipart.html.erb +3 -0
  118. data/spec/fixture/app/views/file_field_specs/with_label.html.erb +1 -0
  119. data/spec/fixture/app/views/file_field_specs/with_values.html.erb +1 -0
  120. data/spec/fixture/app/views/foo/bar.html.erb +0 -0
  121. data/spec/fixture/app/views/form_for_specs/basic.html.erb +3 -0
  122. data/spec/fixture/app/views/form_specs/create_a_form.html.erb +3 -0
  123. data/spec/fixture/app/views/form_specs/create_a_multipart_form.html.erb +3 -0
  124. data/spec/fixture/app/views/form_specs/fake_delete_if_set.html.erb +3 -0
  125. data/spec/fixture/app/views/form_specs/fake_put_if_set.html.erb +3 -0
  126. data/spec/fixture/app/views/form_specs/get_if_set.html.erb +3 -0
  127. data/spec/fixture/app/views/form_specs/post_by_default.html.erb +3 -0
  128. data/spec/fixture/app/views/form_specs/resourceful_form.html.erb +3 -0
  129. data/spec/fixture/app/views/hidden_field_specs/basic.html.erb +1 -0
  130. data/spec/fixture/app/views/hidden_field_specs/disabled.html.erb +1 -0
  131. data/spec/fixture/app/views/hidden_field_specs/label.html.erb +1 -0
  132. data/spec/fixture/app/views/label_specs/basic.html.erb +1 -0
  133. data/spec/fixture/app/views/layout/application.html.erb +11 -0
  134. data/spec/fixture/app/views/numeric_ext_specs/minutes_to_hours.html.erb +1 -0
  135. data/spec/fixture/app/views/numeric_ext_specs/to_concurrency_default.html.erb +1 -0
  136. data/spec/fixture/app/views/numeric_ext_specs/two_digits.html.erb +1 -0
  137. data/spec/fixture/app/views/option_tag_specs/array.html.erb +1 -0
  138. data/spec/fixture/app/views/option_tag_specs/clean.html.erb +1 -0
  139. data/spec/fixture/app/views/option_tag_specs/collection.html.erb +1 -0
  140. data/spec/fixture/app/views/option_tag_specs/multiple_selects.html.erb +1 -0
  141. data/spec/fixture/app/views/option_tag_specs/no_extra_attributes.html.erb +1 -0
  142. data/spec/fixture/app/views/option_tag_specs/optgroups.html.erb +1 -0
  143. data/spec/fixture/app/views/option_tag_specs/selected.html.erb +1 -0
  144. data/spec/fixture/app/views/option_tag_specs/with_blank.html.erb +1 -0
  145. data/spec/fixture/app/views/option_tag_specs/with_prompt.html.erb +1 -0
  146. data/spec/fixture/app/views/password_field_specs/basic.html.erb +1 -0
  147. data/spec/fixture/app/views/password_field_specs/disabled.html.erb +1 -0
  148. data/spec/fixture/app/views/radio_button_specs/basic.html.erb +1 -0
  149. data/spec/fixture/app/views/radio_button_specs/disabled.html.erb +1 -0
  150. data/spec/fixture/app/views/radio_button_specs/label.html.erb +1 -0
  151. data/spec/fixture/app/views/radio_group_specs/attributes.html.erb +1 -0
  152. data/spec/fixture/app/views/radio_group_specs/basic.html.erb +1 -0
  153. data/spec/fixture/app/views/radio_group_specs/hash.html.erb +1 -0
  154. data/spec/fixture/app/views/radio_group_specs/specific_attributes.html.erb +1 -0
  155. data/spec/fixture/app/views/select_specs/blank.html.erb +1 -0
  156. data/spec/fixture/app/views/select_specs/multiple.html.erb +1 -0
  157. data/spec/fixture/app/views/submit_specs/disabled_submit.html.erb +1 -0
  158. data/spec/fixture/app/views/submit_specs/submit_with_label.html.erb +1 -0
  159. data/spec/fixture/app/views/submit_specs/submit_with_values.html.erb +1 -0
  160. data/spec/fixture/app/views/tag_helper/nested_tags.html.erb +5 -0
  161. data/spec/fixture/app/views/tag_helper/tag_with_attributes.html.erb +1 -0
  162. data/spec/fixture/app/views/tag_helper/tag_with_content.html.erb +1 -0
  163. data/spec/fixture/app/views/tag_helper/tag_with_content_in_the_block.html.erb +3 -0
  164. data/spec/fixture/app/views/text_area_specs/basic.html.erb +1 -0
  165. data/spec/fixture/app/views/text_area_specs/disabled.html.erb +1 -0
  166. data/spec/fixture/app/views/text_area_specs/label.html.erb +1 -0
  167. data/spec/fixture/app/views/text_area_specs/nil.html.erb +1 -0
  168. data/spec/fixture/app/views/text_field_specs/basic.html.erb +1 -0
  169. data/spec/fixture/app/views/text_field_specs/class.html.erb +1 -0
  170. data/spec/fixture/app/views/text_field_specs/disabled.html.erb +1 -0
  171. data/spec/fixture/app/views/text_field_specs/label.html.erb +1 -0
  172. data/spec/fixture/config/environments/development.rb +6 -0
  173. data/spec/fixture/config/environments/production.rb +5 -0
  174. data/spec/fixture/config/environments/test.rb +6 -0
  175. data/spec/fixture/config/init.rb +46 -0
  176. data/spec/fixture/config/rack.rb +11 -0
  177. data/spec/fixture/config/router.rb +36 -0
  178. data/spec/fixture/log/merb.main.pid +1 -0
  179. data/spec/fixture/log/merb_test.log +624 -0
  180. data/spec/fixture/public/images/merb.jpg +0 -0
  181. data/spec/fixture/public/merb.fcgi +4 -0
  182. data/spec/fixture/public/stylesheets/master.css +119 -0
  183. data/spec/merb_helpers_config_spec.rb +82 -0
  184. data/spec/merb_helpers_date_time_spec.rb +257 -0
  185. data/spec/merb_helpers_form_spec.rb +1266 -0
  186. data/spec/merb_helpers_tag_helper_spec.rb +46 -0
  187. data/spec/merb_helpers_text_spec.rb +67 -0
  188. data/spec/numeric_extlib_spec.rb +135 -0
  189. data/spec/ordinalize_spec.rb +51 -0
  190. data/spec/spec_helper.rb +149 -0
  191. data/spec/time_dsl_spec.rb +43 -0
  192. metadata +303 -0
@@ -0,0 +1,448 @@
1
+ # Form helpers provide a number of methods to simplify the creation of HTML forms.
2
+ # They can work directly with models (bound) or standalone (unbound).
3
+ module Merb::Helpers::Form
4
+
5
+ def _singleton_form_context
6
+ self._default_builder = Merb::Helpers::Form::Builder::ResourcefulFormWithErrors unless self._default_builder
7
+ @_singleton_form_context ||=
8
+ self._default_builder.new(nil, nil, self)
9
+ end
10
+
11
+ def form_contexts
12
+ @_form_contexts ||= []
13
+ end
14
+
15
+ def current_form_context
16
+ form_contexts.last || _singleton_form_context
17
+ end
18
+
19
+ def _new_form_context(name, builder)
20
+ if name.is_a?(String) || name.is_a?(Symbol)
21
+ ivar = instance_variable_get("@#{name}")
22
+ else
23
+ ivar, name = name, name.class.to_s.snake_case
24
+ end
25
+ builder ||= current_form_context.class if current_form_context
26
+ (builder || self._default_builder).new(ivar, name, self)
27
+ end
28
+
29
+ def with_form_context(name, builder)
30
+ form_contexts.push(_new_form_context(name, builder))
31
+ ret = yield
32
+ form_contexts.pop
33
+ ret
34
+ end
35
+
36
+ # Generates a form tag, which accepts a block that is not directly based on resource attributes
37
+ #
38
+ # ==== Parameters
39
+ # attrs<Hash>:: HTML attributes
40
+ #
41
+ # ==== Returns
42
+ # String:: HTML
43
+ #
44
+ # ==== Notes
45
+ # * Block helpers use the <%= =%> syntax
46
+ # * a multipart enctype is automatically set if the form contains a file upload field
47
+ #
48
+ # ==== Example
49
+ # <%= form :action => url(:controller => "foo", :action => "bar", :id => 1) do %>
50
+ # <%= text_field :name => "first_name", :label => "First Name" %>
51
+ # <%= submit "Create" %>
52
+ # <% end =%>
53
+ #
54
+ # Generates the HTML:
55
+ #
56
+ # <form action="/foo/bar/1" method="post">
57
+ # <label for="first_name">First Name</label>
58
+ # <input type="text" id="first_name" name="first_name" />
59
+ # <input type="submit" value="Create" />
60
+ # </form>
61
+ def form(*args, &blk)
62
+ _singleton_form_context.form(*args, &blk)
63
+ end
64
+
65
+ # Generates a resource specific form tag which accepts a block, this also provides automatic resource routing.
66
+ #
67
+ # ==== Parameters
68
+ # name<Symbol>:: Model or Resource
69
+ # attrs<Hash>:: HTML attributes
70
+ #
71
+ # ==== Returns
72
+ # String:: HTML
73
+ #
74
+ # ==== Notes
75
+ # * Block helpers use the <%= =%> syntax
76
+ #
77
+ # ==== Example
78
+ # <%= form_for @person do %>
79
+ # <%= text_field :first_name, :label => "First Name" %>
80
+ # <%= text_field :last_name, :label => "Last Name" %>
81
+ # <%= submit "Create" %>
82
+ # <% end =%>
83
+ #
84
+ # The HTML generated for this would be:
85
+ #
86
+ # <form action="/people" method="post">
87
+ # <label for="person_first_name">First Name</label>
88
+ # <input type="text" id="person_first_name" name="person[first_name]" />
89
+ # <label for="person_last_name">Last Name</label>
90
+ # <input type="text" id="person_last_name" name="person[last_name]" />
91
+ # <input type="submit" value="Create" />
92
+ # </form>
93
+ def form_for(name, attrs = {}, &blk)
94
+ with_form_context(name, attrs.delete(:builder)) do
95
+ current_form_context.form(attrs, &blk)
96
+ end
97
+ end
98
+
99
+ # Creates a scope around a specific resource object like form_for, but doesnt create the form tags themselves.
100
+ # This makes fields_for suitable for specifying additional resource objects in the same form.
101
+ #
102
+ # ==== Examples
103
+ # <%= form_for @person do %>
104
+ # <%= text_field :first_name, :label => "First Name" %>
105
+ # <%= text_field :last_name, :label => "Last Name" %>
106
+ # <% fields_for :permission do %>
107
+ # <%= check_box :is_admin, :label => "Administrator" %>
108
+ # <% end %>
109
+ # <%= submit "Create" %>
110
+ # <% end =%>
111
+ def fields_for(name, attrs = {}, &blk)
112
+ attrs ||= {}
113
+ with_form_context(name, attrs.delete(:builder)) do
114
+ current_form_context.concat(attrs, &blk)
115
+ end
116
+ end
117
+
118
+ # Provides the ability to create quick fieldsets as blocks for your forms.
119
+ #
120
+ # ==== Parameters
121
+ # attrs<Hash>:: HTML attributes and options
122
+ #
123
+ # ==== Options
124
+ # +legend+:: Adds a legend tag within the fieldset
125
+ #
126
+ # ==== Returns
127
+ # String:: HTML
128
+ #
129
+ # ==== Notes
130
+ # Block helpers use the <%= =%> syntax
131
+ #
132
+ # ==== Example
133
+ # <%= fieldset :legend => "Customer Options" do %>
134
+ # ...your form elements
135
+ # <% end =%>
136
+ #
137
+ # Generates the HTML:
138
+ #
139
+ # <fieldset>
140
+ # <legend>Customer Options</legend>
141
+ # ...your form elements
142
+ # </fieldset>
143
+ def fieldset(attrs = {}, &blk)
144
+ _singleton_form_context.fieldset(attrs, &blk)
145
+ end
146
+
147
+ def fieldset_for(name, attrs = {}, &blk)
148
+ with_form_context(name, attrs.delete(:builder)) do
149
+ current_form_context.fieldset(attrs, &blk)
150
+ end
151
+ end
152
+
153
+ # Provides a generic HTML checkbox input tag.
154
+ # There are two ways this tag can be generated, based on the
155
+ # option :boolean. If not set to true, a "magic" input is generated.
156
+ # Otherwise, an input is created that can be easily used for passing
157
+ # an array of values to the application.
158
+ #
159
+ # ==== Parameters
160
+ # method<Symbol>:: Resource attribute
161
+ # attrs<Hash>:: HTML attributes and options
162
+ #
163
+ # ==== Returns
164
+ # String:: HTML
165
+ #
166
+ # ==== Example
167
+ # <%= check_box :name => "is_activated", :value => "1" %>
168
+ # <%= check_box :name => "choices[]", :boolean => false, :value => "dog" %>
169
+ # <%= check_box :name => "choices[]", :boolean => false, :value => "cat" %>
170
+ # <%= check_box :name => "choices[]", :boolean => false, :value => "weasle" %>
171
+ #
172
+ # Used with a model:
173
+ #
174
+ # <%= check_box :is_activated, :label => "Activated?" %>
175
+ def check_box; end
176
+
177
+ # Provides a HTML file input
178
+ #
179
+ # ==== Parameters
180
+ # name<Symbol>:: Model or Resource
181
+ # attrs<Hash>:: HTML attributes
182
+ #
183
+ # ==== Returns
184
+ # String:: HTML
185
+ #
186
+ # ==== Example
187
+ # <%= file_field :name => "file", :label => "File" %>
188
+ #
189
+ # Used with a model:
190
+ #
191
+ # <%= file_field :file, :label => "Choose a file" %>
192
+ def file_field; end
193
+
194
+ # Provides a HTML hidden input field
195
+ #
196
+ # ==== Parameters
197
+ # name<Symbol>:: Model or Resource
198
+ # attrs<Hash>:: HTML attributes
199
+ #
200
+ # ==== Returns
201
+ # String:: HTML
202
+ #
203
+ # ==== Example
204
+ # <%= hidden_field :name => "secret", :value => "some secret value" %>
205
+ #
206
+ # Used with a model:
207
+ #
208
+ # <%= hidden_field :identifier %>
209
+ # # => <input type="hidden" id="person_identifier" name="person[identifier]" value="#{@person.identifier}" />
210
+ def hidden_field; end
211
+
212
+ # Provides a generic HTML label.
213
+ #
214
+ # ==== Parameters
215
+ # attrs<Hash>:: HTML attributes
216
+ #
217
+ # ==== Returns
218
+ # String:: HTML
219
+ #
220
+ # ==== Example
221
+ # <%= label "Full Name", :for => "name" %>
222
+ # => <label for="name">Full Name</label>
223
+ def label(*args)
224
+ current_form_context.label(*args)
225
+ end
226
+
227
+ # Provides a HTML password input.
228
+ #
229
+ # ==== Parameters
230
+ # name<Symbol>:: Model or Resource
231
+ # attrs<Hash>:: HTML attributes
232
+ #
233
+ # ==== Returns
234
+ # String:: HTML
235
+ #
236
+ # ==== Example
237
+ # <%= password_field :name => :password, :label => "Password" %>
238
+ # # => <label for="password">Password</label><input type="password" id="password" name="password" />
239
+ #
240
+ # Used with a model:
241
+ #
242
+ # <%= password_field :password, :label => 'New Password' %>
243
+ def password_field; end
244
+
245
+ # Provides a HTML radio input tag
246
+ #
247
+ # ==== Parameters
248
+ # method<Symbol>:: Resource attribute
249
+ # attrs<Hash>:: HTML attributes and options
250
+ #
251
+ # ==== Returns
252
+ # String:: HTML
253
+ #
254
+ # ==== Example
255
+ # <%= radio_button :name => "radio_options", :value => "1", :label => "One" %>
256
+ # <%= radio_button :name => "radio_options", :value => "2", :label => "Two" %>
257
+ # <%= radio_button :name => "radio_options", :value => "3", :label => "Three", :checked => true %>
258
+ #
259
+ # Used with a model:
260
+ #
261
+ # <%= form_for @person do %>
262
+ # <%= radio_button :first_name %>
263
+ # <% end =%>
264
+ def radio_button; end
265
+
266
+ # Provides a radio group based on a resource attribute.
267
+ # This is generally used within a resource block such as +form_for+.
268
+ #
269
+ # ==== Parameters
270
+ # method<Symbol>:: Resource attribute
271
+ # arr<Array>:: Choices
272
+ #
273
+ # ==== Returns
274
+ # String:: HTML
275
+ #
276
+ # ==== Examples
277
+ # <%# the labels are the options %>
278
+ # <%= radio_group :my_choice, [5,6,7] %>
279
+ #
280
+ # <%# custom labels %>
281
+ # <%= radio_group :my_choice, [{:value => 5, :label => "five"}] %>
282
+ def radio_group; end
283
+
284
+ # Provides a HTML select
285
+ #
286
+ # ==== Parameters
287
+ # method<Symbol>:: Resource attribute
288
+ # attrs<Hash>:: HTML attributes and options
289
+ #
290
+ # ==== Options
291
+ # +prompt+:: Adds an additional option tag with the provided string with no value.
292
+ # +selected+:: The value of a selected object, which may be either a string or an array.
293
+ # +include_blank+:: Adds an additional blank option tag with no value.
294
+ # +collection+:: The collection for the select options
295
+ # +text_method+:: Method to determine text of an option (as a symbol). Ex: :text_method => :name will call .name on your record object for what text to display.
296
+ # +value_method+:: Method to determine value of an option (as a symbol).
297
+ #
298
+ # ==== Returns
299
+ # String:: HTML
300
+ #
301
+ # ==== Example
302
+ # <%= select :name, :collection => %w(one two three) %>
303
+ def select; end
304
+
305
+ # Provides a HTML textarea tag
306
+ #
307
+ # ==== Parameters
308
+ # contents<String>:: Contents of the text area
309
+ # attrs<Hash>:: HTML attributes
310
+ #
311
+ # ==== Returns
312
+ # String:: HTML
313
+ #
314
+ # ==== Example
315
+ # <%= text_area "my comments", :name => "comments" %>
316
+ #
317
+ # Used with a model:
318
+ #
319
+ # <%= text_area :comments %>
320
+ def text_area; end
321
+
322
+ # Provides a HTML text input tag
323
+ #
324
+ # ==== Parameters
325
+ # name<Symbol>:: Model or Resource
326
+ # attrs<Hash>:: HTML attributes
327
+ #
328
+ # ==== Returns
329
+ # String:: HTML
330
+ #
331
+ # ==== Example
332
+ # <%= text_field :name => :fav_color, :label => "Your Favorite Color" %>
333
+ # # => <label for="fav_color">Your Favorite Color</label><input type="text" id="fav_color" name="fav_color" />
334
+ #
335
+ # Used with a model:
336
+ #
337
+ # <%= form_for @person do %>
338
+ # <%= text_field :first_name, :label => "First Name" %>
339
+ # <% end =%>
340
+ def text_field; end
341
+
342
+ # @todo radio_group helper still needs to be implemented
343
+ %w(text_field password_field hidden_field file_field
344
+ text_area select check_box radio_button radio_group).each do |kind|
345
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
346
+ def #{kind}(*args)
347
+ if bound?(*args)
348
+ current_form_context.bound_#{kind}(*args)
349
+ else
350
+ current_form_context.unbound_#{kind}(*args)
351
+ end
352
+ end
353
+ RUBY
354
+ end
355
+
356
+ # Generates a HTML button.
357
+ #
358
+ # ==== Parameters
359
+ # contents<String>:: HTML contained within the button tag
360
+ # attrs<Hash>:: HTML attributes
361
+ #
362
+ # ==== Returns
363
+ # String:: HTML
364
+ #
365
+ # ==== Notes
366
+ # * Buttons do not always work as planned in IE
367
+ # http://www.peterbe.com/plog/button-tag-in-IE
368
+ # * Not all mobile browsers support buttons
369
+ # http://nickcowie.com/2007/time-to-stop-using-the-button-element/
370
+ #
371
+ # ==== Example
372
+ # <%= button "Initiate Launch Sequence" %>
373
+ def button(contents, attrs = {})
374
+ current_form_context.button(contents, attrs)
375
+ end
376
+
377
+ # Generates a HTML delete button.
378
+ #
379
+ # If an object is passed as first parameter, Merb will try to use the resource url for the object
380
+ # If the object doesn't have a resource view, pass a url
381
+ #
382
+ # ==== Parameters
383
+ # object_or_url<Object> or <String>:: Object to delete or URL to send the request to
384
+ # contents<String>:: HTML contained within the button tag
385
+ # attrs<Hash>:: HTML attributes
386
+ #
387
+ # ==== Returns
388
+ # String:: HTML
389
+ #
390
+ # ==== Example
391
+ # <%= delete_button @article, "Delete article now", :class => 'delete-btn' %>
392
+ # <%= delete_button url(:article, @article)%>
393
+ #
394
+ def delete_button(object_or_url, contents="Delete", attrs = {})
395
+ url = object_or_url.is_a?(String) ? object_or_url : url(object_or_url.class.to_s.snake_case.to_sym, object_or_url)
396
+ tag :form, :class => 'delete-btn', :action => url, :method => :post do
397
+ tag(:input, :type => :hidden, :name => "_method", :value => "DELETE") <<
398
+ tag(:input, (contents || 'Delete'), attrs.merge(:type => :submit))
399
+ end
400
+ end
401
+
402
+ # Generates a HTML submit button.
403
+ #
404
+ # ==== Parameters
405
+ # value<String>:: Sets the value="" attribute
406
+ # attrs<Hash>:: HTML attributes
407
+ #
408
+ # ==== Returns
409
+ # String:: HTML
410
+ #
411
+ # ==== Example
412
+ # <%= submit "Process" %>
413
+ def submit(contents, attrs = {})
414
+ current_form_context.submit(contents, attrs)
415
+ end
416
+
417
+ # Provides a HTML formatted display of resource errors in an unordered list with a h2 form submission error
418
+ #
419
+ # ==== Parameters
420
+ # obj<Symbol>:: Model or Resource
421
+ # error_class<String>:: CSS class to use for error container
422
+ # build_li<String>:: Custom li tag to wrap each error in
423
+ # header<String>:: Custom header text for the error container
424
+ # before<Boolean>:: Display the errors before or inside of the form
425
+ #
426
+ # ==== Returns
427
+ # String:: HTML
428
+ #
429
+ # ==== Examples
430
+ # <%= error_messages_for :person %>
431
+ # <%= error_messages_for :person {|errors| "You can has probs nao: #{errors.size} of em!"}
432
+ # <%= error_messages_for :person, lambda{|error| "<li class='aieeee'>#{error.join(' ')}"} %>
433
+ # <%= error_messages_for :person, nil, 'bad_mojo' %>
434
+ def error_messages_for(obj = nil, opts = {})
435
+ current_form_context.error_messages_for(obj, opts[:error_class] || "error",
436
+ opts[:build_li] || "<li>%s</li>",
437
+ opts[:header] || "<h2>Form submission failed because of %s problem%s</h2>",
438
+ opts.key?(:before) ? opts[:before] : true)
439
+ end
440
+ alias error_messages error_messages_for
441
+
442
+ private
443
+
444
+ def bound?(*args)
445
+ args.first.is_a?(Symbol)
446
+ end
447
+
448
+ end
@@ -0,0 +1,24 @@
1
+ load File.dirname(__FILE__) / "form" / "helpers.rb"
2
+ load File.dirname(__FILE__) / "form" / "builder.rb"
3
+
4
+ class Merb::Controller
5
+ class_inheritable_accessor :_default_builder
6
+ include Merb::Helpers::Form
7
+ end
8
+
9
+ class Merb::PartController < Merb::AbstractController
10
+ class_inheritable_accessor :_default_builder
11
+ include Merb::Helpers::Form
12
+ end
13
+
14
+ Merb::BootLoader.after_app_loads do
15
+ class Merb::Controller
16
+ self._default_builder =
17
+ Object.full_const_get(Merb::Plugins.config[:helpers][:default_builder]) rescue Merb::Helpers::Form::Builder::ResourcefulFormWithErrors
18
+ end
19
+
20
+ class Merb::PartController
21
+ self._default_builder =
22
+ Object.full_const_get(Merb::Plugins.config[:helpers][:default_builder]) rescue Merb::Helpers::Form::Builder::ResourcefulFormWithErrors
23
+ end
24
+ end