formtastic 2.0.2 → 2.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/.gitignore +4 -1
  2. data/Appraisals +11 -0
  3. data/CHANGELOG +2 -2
  4. data/Gemfile +0 -2
  5. data/README.textile +183 -151
  6. data/Rakefile +9 -5
  7. data/app/assets/stylesheets/formtastic.css +16 -3
  8. data/formtastic.gemspec +6 -2
  9. data/gemfiles/rails-3.0.gemfile +7 -0
  10. data/gemfiles/rails-3.1.gemfile +7 -0
  11. data/gemfiles/rails-3.2.gemfile +7 -0
  12. data/lib/formtastic.rb +10 -2
  13. data/lib/formtastic/actions.rb +11 -0
  14. data/lib/formtastic/actions/base.rb +156 -0
  15. data/lib/formtastic/actions/button_action.rb +72 -0
  16. data/lib/formtastic/actions/buttonish.rb +17 -0
  17. data/lib/formtastic/actions/input_action.rb +68 -0
  18. data/lib/formtastic/actions/link_action.rb +87 -0
  19. data/lib/formtastic/engine.rb +5 -1
  20. data/lib/formtastic/form_builder.rb +3 -0
  21. data/lib/formtastic/helpers.rb +2 -1
  22. data/lib/formtastic/helpers/action_helper.rb +109 -0
  23. data/lib/formtastic/helpers/actions_helper.rb +168 -0
  24. data/lib/formtastic/helpers/buttons_helper.rb +22 -9
  25. data/lib/formtastic/helpers/errors_helper.rb +0 -54
  26. data/lib/formtastic/helpers/fieldset_wrapper.rb +10 -5
  27. data/lib/formtastic/helpers/form_helper.rb +2 -2
  28. data/lib/formtastic/helpers/input_helper.rb +1 -10
  29. data/lib/formtastic/helpers/inputs_helper.rb +6 -3
  30. data/lib/formtastic/i18n.rb +3 -2
  31. data/lib/formtastic/inputs/base.rb +11 -3
  32. data/lib/formtastic/inputs/base/choices.rb +6 -1
  33. data/lib/formtastic/inputs/base/collections.rb +36 -13
  34. data/lib/formtastic/inputs/base/grouped_collections.rb +1 -1
  35. data/lib/formtastic/inputs/base/numeric.rb +50 -0
  36. data/lib/formtastic/inputs/base/options.rb +1 -1
  37. data/lib/formtastic/inputs/base/placeholder.rb +17 -0
  38. data/lib/formtastic/inputs/base/stringish.rb +2 -7
  39. data/lib/formtastic/inputs/base/timeish.rb +21 -5
  40. data/lib/formtastic/inputs/base/validations.rb +1 -1
  41. data/lib/formtastic/inputs/base/wrapping.rb +10 -3
  42. data/lib/formtastic/inputs/boolean_input.rb +10 -2
  43. data/lib/formtastic/inputs/check_boxes_input.rb +18 -9
  44. data/lib/formtastic/inputs/country_input.rb +2 -2
  45. data/lib/formtastic/inputs/date_input.rb +19 -1
  46. data/lib/formtastic/inputs/datetime_input.rb +1 -1
  47. data/lib/formtastic/inputs/email_input.rb +2 -1
  48. data/lib/formtastic/inputs/file_input.rb +1 -1
  49. data/lib/formtastic/inputs/hidden_input.rb +1 -1
  50. data/lib/formtastic/inputs/number_input.rb +6 -36
  51. data/lib/formtastic/inputs/password_input.rb +2 -1
  52. data/lib/formtastic/inputs/phone_input.rb +3 -2
  53. data/lib/formtastic/inputs/radio_input.rb +1 -1
  54. data/lib/formtastic/inputs/range_input.rb +8 -32
  55. data/lib/formtastic/inputs/search_input.rb +2 -1
  56. data/lib/formtastic/inputs/select_input.rb +56 -28
  57. data/lib/formtastic/inputs/string_input.rb +3 -1
  58. data/lib/formtastic/inputs/text_input.rb +5 -4
  59. data/lib/formtastic/inputs/time_input.rb +4 -8
  60. data/lib/formtastic/inputs/time_zone_input.rb +1 -1
  61. data/lib/formtastic/inputs/url_input.rb +2 -1
  62. data/lib/formtastic/localized_string.rb +6 -94
  63. data/lib/formtastic/localizer.rb +110 -0
  64. data/lib/formtastic/version.rb +1 -1
  65. data/lib/generators/formtastic/form/form_generator.rb +105 -0
  66. data/lib/generators/templates/_form.html.erb +2 -2
  67. data/lib/generators/templates/_form.html.haml +4 -4
  68. data/lib/generators/templates/_form.html.slim +2 -2
  69. data/lib/generators/templates/formtastic.rb +4 -0
  70. data/lib/locale/en.yml +2 -0
  71. data/sample/basic_inputs.html +22 -0
  72. data/spec/actions/button_action_spec.rb +63 -0
  73. data/spec/actions/generic_action_spec.rb +484 -0
  74. data/spec/actions/input_action_spec.rb +59 -0
  75. data/spec/actions/link_action_spec.rb +92 -0
  76. data/spec/builder/semantic_fields_for_spec.rb +14 -0
  77. data/spec/generators/formtastic/form/form_generator_spec.rb +118 -0
  78. data/spec/generators/formtastic/install/install_generator_spec.rb +47 -0
  79. data/spec/helpers/action_helper_spec.rb +365 -0
  80. data/spec/helpers/actions_helper_spec.rb +143 -0
  81. data/spec/helpers/buttons_helper_spec.rb +39 -23
  82. data/spec/helpers/commit_button_helper_spec.rb +153 -93
  83. data/spec/helpers/inputs_helper_spec.rb +14 -0
  84. data/spec/i18n_spec.rb +11 -0
  85. data/spec/inputs/boolean_input_spec.rb +31 -2
  86. data/spec/inputs/check_boxes_input_spec.rb +29 -1
  87. data/spec/inputs/date_input_spec.rb +95 -0
  88. data/spec/inputs/datetime_input_spec.rb +49 -0
  89. data/spec/inputs/email_input_spec.rb +28 -0
  90. data/spec/inputs/file_input_spec.rb +28 -0
  91. data/spec/inputs/hidden_input_spec.rb +28 -0
  92. data/spec/inputs/include_blank_spec.rb +53 -45
  93. data/spec/inputs/number_input_spec.rb +34 -4
  94. data/spec/inputs/password_input_spec.rb +28 -0
  95. data/spec/inputs/phone_input_spec.rb +28 -0
  96. data/spec/inputs/placeholder_spec.rb +10 -10
  97. data/spec/inputs/radio_input_spec.rb +51 -6
  98. data/spec/inputs/range_input_spec.rb +30 -2
  99. data/spec/inputs/search_input_spec.rb +27 -0
  100. data/spec/inputs/select_input_spec.rb +52 -6
  101. data/spec/inputs/string_input_spec.rb +28 -0
  102. data/spec/inputs/text_input_spec.rb +27 -0
  103. data/spec/inputs/time_input_spec.rb +67 -1
  104. data/spec/inputs/time_zone_input_spec.rb +28 -0
  105. data/spec/inputs/url_input_spec.rb +28 -0
  106. data/spec/inputs/with_options_spec.rb +43 -0
  107. data/spec/spec_helper.rb +22 -6
  108. data/spec/support/custom_macros.rb +6 -134
  109. data/spec/support/test_environment.rb +0 -1
  110. metadata +104 -17
  111. data/lib/formtastic/helpers/semantic_form_helper.rb +0 -11
  112. data/lib/formtastic/inputs/numeric_input.rb +0 -21
  113. data/lib/formtastic/railtie.rb +0 -12
  114. data/lib/formtastic/semantic_form_builder.rb +0 -11
  115. data/spec/builder/errors_spec.rb +0 -203
  116. data/spec/inputs/numeric_input_spec.rb +0 -41
data/.gitignore CHANGED
@@ -4,10 +4,13 @@ coverage
4
4
  coverage.data
5
5
  pkg
6
6
  *~
7
+ *.swp
7
8
  *watchr.rb
8
9
  log/*
9
10
  .rvmrc
10
11
  .bundle
11
12
  Gemfile.lock
12
13
  .yardoc
13
- doc/
14
+ doc/
15
+ tmp
16
+ gemfiles/*.lock
data/Appraisals ADDED
@@ -0,0 +1,11 @@
1
+ appraise 'rails-3.0' do
2
+ gem 'rails', '~> 3.0.0'
3
+ end
4
+
5
+ appraise 'rails-3.1' do
6
+ gem 'rails', '~> 3.1.0'
7
+ end
8
+
9
+ appraise 'rails-3.2' do
10
+ gem 'rails', '~> 3.2.0.rc2'
11
+ end
data/CHANGELOG CHANGED
@@ -1,6 +1,6 @@
1
- 2.0.2
1
+ HEAD
2
2
 
3
- * fixed MongoMapper argument errors on associations
3
+ * Fixed that MongoMapper does not use `associations(method)`. `.associations` is an accessor.
4
4
 
5
5
  2.0.1
6
6
 
data/Gemfile CHANGED
@@ -1,5 +1,3 @@
1
1
  source :rubygems
2
2
 
3
- gem 'rake', '< 0.9'
4
-
5
3
  gemspec
data/README.textile CHANGED
@@ -17,31 +17,32 @@ h2. The Story
17
17
  One day, I finally had enough, so I opened up my text editor, and wrote a DSL for how I'd like to author forms:
18
18
 
19
19
  <pre>
20
- <%= semantic_form_for @article do |form| %>
21
-
22
- <%= form.inputs :name => "Basic" do %>
23
- <%= form.input :title %>
24
- <%= form.input :body %>
25
- <%= form.input :section %>
26
- <%= form.input :publication_state, :as => :radio %>
27
- <%= form.input :category %>
28
- <%= form.input :allow_comments, :label => "Allow commenting on this article" %>
20
+ <%= semantic_form_for @article do |f| %>
21
+
22
+ <%= f.inputs :name => "Basic" do %>
23
+ <%= f.input :title %>
24
+ <%= f.input :body %>
25
+ <%= f.input :section %>
26
+ <%= f.input :publication_state, :as => :radio %>
27
+ <%= f.input :category %>
28
+ <%= f.input :allow_comments, :label => "Allow commenting on this article" %>
29
29
  <% end %>
30
30
 
31
- <%= form.inputs :name => "Advanced" do %>
32
- <%= form.input :keywords, :required => false, :hint => "Example: ruby, rails, forms" %>
33
- <%= form.input :extract, :required => false %>
34
- <%= form.input :description, :required => false %>
35
- <%= form.input :url_title, :required => false %>
31
+ <%= f.inputs :name => "Advanced" do %>
32
+ <%= f.input :keywords, :required => false, :hint => "Example: ruby, rails, forms" %>
33
+ <%= f.input :extract, :required => false %>
34
+ <%= f.input :description, :required => false %>
35
+ <%= f.input :url_title, :required => false %>
36
36
  <% end %>
37
37
 
38
- <%= form.inputs :name => "Author", :for => :author do |author_form| %>
38
+ <%= f.inputs :name => "Author", :for => :author do |author_form| %>
39
39
  <%= author_form.input :first_name %>
40
40
  <%= author_form.input :last_name %>
41
41
  <% end %>
42
42
 
43
- <%= form.buttons do %>
44
- <%= form.commit_button %>
43
+ <%= f.actions do %>
44
+ <%= f.action :submit, :as => :button %>
45
+ <%= f.action :cancel, :as => :link %>
45
46
  <% end %>
46
47
 
47
48
  <% end %>
@@ -52,25 +53,25 @@ I also wrote the accompanying HTML output I expected, favoring something very si
52
53
 
53
54
  h2. It's awesome because...
54
55
 
55
- * it can handle @belongs_to@ associations (like Post belongs_to :author), rendering a select or set of radio inputs with choices from the parent model.
56
- * it can handle @has_many@ and @has_and_belongs_to_many@ associations (like: Post has_many :tags), rendering a multi-select with choices from the child models.
57
- * it's Rails 3 compatible (including nested forms).
58
- * it has internationalization (I18n)!
59
- * it's _really_ quick to get started with a basic form in place (4 lines), then go back to add in more detail if you need it.
60
- * there's heaps of elements, id and class attributes for you to hook in your CSS and JS.
61
- * it handles real world stuff like inline hints, inline error messages & help text.
62
- * it doesn't hijack or change any of the standard Rails form inputs, so you can still use them as expected (even mix and match).
63
- * it's got absolutely awesome spec coverage.
64
- * there's a bunch of people using and working on it (it's not just one developer building half a solution).
65
- * it has growing HTML5 support (new inputs like email/phone/search, new attributes like required/min/max/step/placeholder)
56
+ * It can handle @belongs_to@ associations (like Post belongs_to :author), rendering a select or set of radio inputs with choices from the parent model.
57
+ * It can handle @has_many@ and @has_and_belongs_to_many@ associations (like: Post has_many :tags), rendering a multi-select with choices from the child models.
58
+ * It's Rails 3 compatible (including nested forms).
59
+ * It has internationalization (I18n)!
60
+ * It's _really_ quick to get started with a basic form in place (4 lines), then go back to add in more detail if you need it.
61
+ * There's heaps of elements, id and class attributes for you to hook in your CSS and JS.
62
+ * It handles real world stuff like inline hints, inline error messages & help text.
63
+ * It doesn't hijack or change any of the standard Rails form inputs, so you can still use them as expected (even mix and match).
64
+ * It's got absolutely awesome spec coverage.
65
+ * There's a bunch of people using and working on it (it's not just one developer building half a solution).
66
+ * It has growing HTML5 support (new inputs like email/phone/search, new attributes like required/min/max/step/placeholder)
66
67
 
67
68
 
68
69
  h2. Opinions
69
70
 
70
- * it should be easier to do things the right way than the wrong way.
71
- * sometimes _more mark-up_ is better.
72
- * elements and attribute hooks are _gold_ for stylesheet authors.
73
- * make the common things we do easy, yet ensure uncommon things are still possible.
71
+ * It should be easier to do things the right way than the wrong way.
72
+ * Sometimes _more mark-up_ is better.
73
+ * Elements and attribute hooks are _gold_ for stylesheet authors.
74
+ * Make the common things we do easy, yet ensure uncommon things are still possible.
74
75
 
75
76
 
76
77
  h2. Documentation
@@ -139,39 +140,40 @@ h2. Usage
139
140
 
140
141
  Forms are really boring to code... you want to get onto the good stuff as fast as possible.
141
142
 
142
- This renders a set of inputs (one for _most_ columns in the database table, and one for each ActiveRecord @belongs_to@-association), followed by a submit button:
143
+ This renders a set of inputs (one for _most_ columns in the database table, and one for each ActiveRecord @belongs_to@-association), followed by default action buttons (an input submit button):
143
144
 
144
145
  <pre>
145
- <%= semantic_form_for @user do |form| %>
146
- <%= form.inputs %>
147
- <%= form.buttons %>
146
+ <%= semantic_form_for @user do |f| %>
147
+ <%= f.inputs %>
148
+ <%= f.actions %>
148
149
  <% end %>
149
150
  </pre>
150
151
 
151
152
  This is a great way to get something up fast, but like scaffolding, it's *not recommended for production*. Don't be so lazy!
152
153
 
153
- To specify the order of the fields, skip some of the fields or even add in fields that Formtastic couldn't infer. You can pass in a list of field names to @inputs@ and list of button names to @buttons@:
154
+ To specify the order of the fields, skip some of the fields or even add in fields that Formtastic couldn't infer. You can pass in a list of field names to @inputs@ and list of action names to @actions@:
154
155
 
155
156
  <pre>
156
- <%= semantic_form_for @user do |form| %>
157
- <%= form.inputs :title, :body, :section, :categories, :created_at %>
158
- <%= form.buttons :commit %>
157
+ <%= semantic_form_for @user do |f| %>
158
+ <%= f.inputs :title, :body, :section, :categories, :created_at %>
159
+ <%= f.actions :submit, :cancel %>
159
160
  <% end %>
160
161
  </pre>
161
162
 
162
- You probably want control over the input type Formtastic uses for each field. You can expand the @inputs@ and @buttons@ to block helper format and use the @:as@ option to specify an exact input type:
163
+ You probably want control over the input type Formtastic uses for each field. You can expand the @inputs@ and @actions@ to block helper format and use the @:as@ option to specify an exact input type:
163
164
 
164
165
  <pre>
165
- <%= semantic_form_for @post do |form| %>
166
- <%= form.inputs do %>
167
- <%= form.input :title %>
168
- <%= form.input :body %>
169
- <%= form.input :section, :as => :radio %>
170
- <%= form.input :categories %>
171
- <%= form.input :created_at, :as => :string %>
166
+ <%= semantic_form_for @post do |f| %>
167
+ <%= f.inputs do %>
168
+ <%= f.input :title %>
169
+ <%= f.input :body %>
170
+ <%= f.input :section, :as => :radio %>
171
+ <%= f.input :categories %>
172
+ <%= f.input :created_at, :as => :string %>
172
173
  <% end %>
173
- <%= form.buttons do %>
174
- <%= form.commit_button %>
174
+ <%= f.actions do %>
175
+ <%= f.action :submit, :as => :button %>
176
+ <%= f.action :cancel, :as => :link %>
175
177
  <% end %>
176
178
  <% end %>
177
179
  </pre>
@@ -179,20 +181,20 @@ You probably want control over the input type Formtastic uses for each field. Yo
179
181
  If you want to customize the label text, or render some hint text below the field, specify which fields are required/optional, or break the form into two fieldsets, the DSL is pretty comprehensive:
180
182
 
181
183
  <pre>
182
- <%= semantic_form_for @post do |form| %>
183
- <%= form.inputs "Basic", :id => "basic" do %>
184
- <%= form.input :title %>
185
- <%= form.input :body %>
184
+ <%= semantic_form_for @post do |f| %>
185
+ <%= f.inputs "Basic", :id => "basic" do %>
186
+ <%= f.input :title %>
187
+ <%= f.input :body %>
186
188
  <% end %>
187
- <%= form.inputs :name => "Advanced Options", :id => "advanced" do %>
188
- <%= form.input :slug, :label => "URL Title", :hint => "Created automatically if left blank", :required => false %>
189
- <%= form.input :section, :as => :radio %>
190
- <%= form.input :user, :label => "Author", :member_label => :full_name %>
191
- <%= form.input :categories, :required => false %>
192
- <%= form.input :created_at, :as => :string, :label => "Publication Date", :required => false %>
189
+ <%= f.inputs :name => "Advanced Options", :id => "advanced" do %>
190
+ <%= f.input :slug, :label => "URL Title", :hint => "Created automatically if left blank", :required => false %>
191
+ <%= f.input :section, :as => :radio %>
192
+ <%= f.input :user, :label => "Author", :member_label => :full_name %>
193
+ <%= f.input :categories, :required => false %>
194
+ <%= f.input :created_at, :as => :string, :label => "Publication Date", :required => false %>
193
195
  <% end %>
194
- <%= form.buttons do %>
195
- <%= form.commit_button %>
196
+ <%= f.actions do %>
197
+ <%= f.action(:submit) %>
196
198
  <% end %>
197
199
  <% end %>
198
200
  </pre>
@@ -200,91 +202,99 @@ If you want to customize the label text, or render some hint text below the fiel
200
202
  You can create forms for nested resources:
201
203
 
202
204
  <pre>
203
- <%= semantic_form_for [@author, @post] do |form| %>
205
+ <%= semantic_form_for [@author, @post] do |f| %>
204
206
  </pre>
205
207
 
206
208
  Nested forms are also supported (don't forget your models need to be setup correctly with @accepts_nested_attributes_for@). You can do it in the Rails way:
207
209
 
208
210
  <pre>
209
- <%= semantic_form_for @post do |form| %>
210
- <%= form.inputs :title, :body, :created_at %>
211
- <%= form.semantic_fields_for :author do |author| %>
211
+ <%= semantic_form_for @post do |f| %>
212
+ <%= f.inputs :title, :body, :created_at %>
213
+ <%= f.semantic_fields_for :author do |author| %>
212
214
  <%= author.inputs :first_name, :last_name, :name => "Author" %>
213
215
  <% end %>
214
- <%= form.buttons %>
216
+ <%= f.actions %>
215
217
  <% end %>
216
218
  </pre>
217
219
 
218
220
  Or the Formtastic way with the @:for@ option:
219
221
 
220
222
  <pre>
221
- <%= semantic_form_for @post do |form| %>
222
- <%= form.inputs :title, :body, :created_at %>
223
- <%= form.inputs :first_name, :last_name, :for => :author, :name => "Author" %>
224
- <%= form.buttons %>
223
+ <%= semantic_form_for @post do |f| %>
224
+ <%= f.inputs :title, :body, :created_at %>
225
+ <%= f.inputs :first_name, :last_name, :for => :author, :name => "Author" %>
226
+ <%= f.actions %>
225
227
  <% end %>
226
228
  </pre>
227
229
 
228
- When working in has many association, you can even supply @"%i"@ in your fieldset name that it will be properly interpolated with the child index. For example:
230
+ When working in has many association, you can even supply @"%i"@ in your fieldset name; they will be properly interpolated with the child index. For example:
229
231
 
230
232
  <pre>
231
- <%= semantic_form_for @post do |form| %>
232
- <%= form.inputs %>
233
- <%= form.inputs :name => 'Category #%i', :for => :categories %>
234
- <%= form.buttons %>
233
+ <%= semantic_form_for @post do |f| %>
234
+ <%= f.inputs %>
235
+ <%= f.inputs :name => 'Category #%i', :for => :categories %>
236
+ <%= f.actions %>
235
237
  <% end %>
236
238
  </pre>
237
239
 
238
- If you have more than one form on the same page, it may lead to HTML invalidation because of the way HTML element id attributes are assigned. You can provide
239
- a namespace for your form to ensure uniqueness of id attributes on form elements. The namespace attribute will be prefixed with underscore on the generate html id. For example:
240
+ If you have more than one form on the same page, it may lead to HTML invalidation because of the way HTML element id attributes are assigned. You can provide a namespace for your form to ensure uniqueness of id attributes on form elements. The namespace attribute will be prefixed with underscore on the generate HTML id. For example:
240
241
 
241
242
  <pre>
242
- <%= semantic_form_for(@post, :namespace => 'cat_form') do |form| %>
243
- <%= form.input :title %> # id="cat_form_post_title"
244
- <%= form.input :body %> # id="cat_form_post_body"
245
- <%= form.input :created_at %> # id="cat_form_post_created_at"
246
- <%= form.buttons %>
243
+ <%= semantic_form_for(@post, :namespace => 'cat_form') do |f| %>
244
+ <%= f.inputs do %>
245
+ <%= f.input :title %> # id="cat_form_post_title"
246
+ <%= f.input :body %> # id="cat_form_post_body"
247
+ <%= f.input :created_at %> # id="cat_form_post_created_at"
248
+ <% end %>
249
+ <%= f.actions %>
247
250
  <% end %>
248
251
  </pre>
249
252
 
250
- Customize HTML attributes for any input using the @:input_html@ option. Typically this is used to disable the input, change the size of a text field, change the rows in a textarea, or even to add a special class to an input to attach special behavior like "autogrow":http://plugins.jquery.com/project/autogrow textareas:
253
+ Customize HTML attributes for any input using the @:input_html@ option. Typically this is used to disable the input, change the size of a text field, change the rows in a textarea, or even to add a special class to an input to attach special behavior like "autogrow":http://plugins.jquery.com/project/autogrowtextarea textareas:
251
254
 
252
255
  <pre>
253
- <%= semantic_form_for @post do |form| %>
254
- <%= form.input :title, :input_html => { :cols => 10 } %>
255
- <%= form.input :body, :input_html => { :class => 'autogrow', :rows => 10, :cols => 20, :maxlength => 10 } %>
256
- <%= form.input :created_at, :input_html => { :disabled => true } %>
257
- <%= form.buttons %>
256
+ <%= semantic_form_for @post do |f| %>
257
+ <%= f.inputs do %>
258
+ <%= f.input :title, :input_html => { :size => 10 } %>
259
+ <%= f.input :body, :input_html => { :class => 'autogrow', :rows => 10, :cols => 20, :maxlength => 10 } %>
260
+ <%= f.input :created_at, :input_html => { :disabled => true } %>
261
+ <%= f.input :updated_at, :input_html => { :readonly => true } %>
262
+ <% end %>
263
+ <%= f.actions %>
258
264
  <% end %>
259
265
  </pre>
260
266
 
261
- The same can be done for buttons with the @:button_html@ option:
267
+ The same can be done for actions with the @:button_html@ option:
262
268
 
263
269
  <pre>
264
- <%= semantic_form_for @post do |form| %>
270
+ <%= semantic_form_for @post do |f| %>
265
271
  ...
266
- <%= form.buttons do %>
267
- <%= form.commit_button :button_html => { :class => "primary", :disable_with => 'Wait...' } %>
272
+ <%= f.actions do %>
273
+ <%= f.action :submit, :button_html => { :class => "primary", :disable_with => 'Wait...' } %>
268
274
  <% end %>
269
275
  <% end %>
270
276
  </pre>
271
277
 
272
- Customize the HTML attributes for the @<li>@ wrapper around every input with the @:wrapper_html@ option hash. There's one special key in the hash (@:class@), which will actually _append_ your string of classes to the existing classes provided by Formtastic (like @"required string error"@).
278
+ Customize the HTML attributes for the @<li>@ wrapper around every input with the @:wrapper_html@ option hash. There's one special key in the hash: (@:class@), which will actually _append_ your string of classes to the existing classes provided by Formtastic (like @"required string error"@).
273
279
 
274
280
  <pre>
275
- <%= semantic_form_for @post do |form| %>
276
- <%= form.input :title, :wrapper_html => { :class => "important" } %>
277
- <%= form.input :body %>
278
- <%= form.input :description, :wrapper_html => { :style => "display:none;" } %>
281
+ <%= semantic_form_for @post do |f| %>
282
+ <%= f.inputs do %>
283
+ <%= f.input :title, :wrapper_html => { :class => "important" } %>
284
+ <%= f.input :body %>
285
+ <%= f.input :description, :wrapper_html => { :style => "display:none;" } %>
286
+ <% end %>
279
287
  ...
280
288
  <% end %>
281
289
  </pre>
282
290
 
283
- Customize the default class used for hints on each attribute or globally in the @config/formtastic.rb@ file. Similarly you can customize the error classes on an attribute level or globally.
291
+ Customize the default class used for hints on each attribute or globally in the @config/initializers/formtastic.rb@ file. Similarly, you can customize the error classes on an attribute level or globally.
284
292
 
285
293
  <pre>
286
- <%= semantic_form_for @post do |form| %>
287
- <%= form.input :title, :hint_class => 'custom-html-class', :error_class => 'custom-error-class' %>
294
+ <%= semantic_form_for @post do |f| %>
295
+ <%= f.inputs do %>
296
+ <%= f.input :title, :hint_class => 'custom-html-class', :error_class => 'custom-error-class' %>
297
+ <% end %>
288
298
  <% end %>
289
299
  </pre>
290
300
 
@@ -349,15 +359,17 @@ h2. Internationalization (I18n)
349
359
 
350
360
  h3. Basic Localization
351
361
 
352
- Formtastic got some neat I18n-features. ActiveRecord object names and attributes are, by default, taken from calling @@object.human_name@ and @@object.human_attribute_name(attr)@ respectively. There are a few words specific to Formtastic that can be translated. See @lib/locale/en.yml@ for more information.
362
+ Formtastic has some neat I18n-features. ActiveRecord object names and attributes are, by default, taken from calling @@object.human_name@ and @@object.human_attribute_name(attr)@ respectively. There are a few words specific to Formtastic that can be translated. See @lib/locale/en.yml@ for more information.
353
363
 
354
364
  Basic localization (labels only, with ActiveRecord):
355
365
 
356
366
  <pre>
357
- <%= semantic_form_for @post do |form| %>
358
- <%= form.input :title %> # => :label => I18n.t('activerecord.attributes.user.title') or 'Title'
359
- <%= form.input :body %> # => :label => I18n.t('activerecord.attributes.user.body') or 'Body'
360
- <%= form.input :section %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
367
+ <%= semantic_form_for @post do |f| %>
368
+ <%= f.inputs do %>
369
+ <%= f.input :title %> # => :label => I18n.t('activerecord.attributes.user.title') or 'Title'
370
+ <%= f.input :body %> # => :label => I18n.t('activerecord.attributes.user.body') or 'Body'
371
+ <%= f.input :section %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
372
+ <% end %>
361
373
  <% end %>
362
374
  </pre>
363
375
 
@@ -388,7 +400,7 @@ Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the
388
400
  title: "Edit title"
389
401
  hints:
390
402
  post:
391
- title: "Choose a good title for you post."
403
+ title: "Choose a good title for your post."
392
404
  body: "Write something inspiring here."
393
405
  placeholders:
394
406
  post:
@@ -399,20 +411,22 @@ Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the
399
411
  actions:
400
412
  create: "Create my %{model}"
401
413
  update: "Save changes"
414
+ reset: "Reset form"
415
+ cancel: "Cancel and go back"
402
416
  dummie: "Launch!"
403
417
  </pre>
404
418
 
405
419
  *3. ...and now you'll get:*
406
420
 
407
421
  <pre>
408
- <%= semantic_form_for Post.new do |form| %>
409
- <%= form.inputs do %>
410
- <%= form.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for you post."
411
- <%= form.input :body %> # => :label => "Write something...", :hint => "Write something inspiring here."
412
- <%= form.input :section %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
422
+ <%= semantic_form_for Post.new do |f| %>
423
+ <%= f.inputs do %>
424
+ <%= f.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for your post."
425
+ <%= f.input :body %> # => :label => "Write something...", :hint => "Write something inspiring here."
426
+ <%= f.input :section %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
413
427
  <% end %>
414
- <%= form.buttons do %>
415
- <%= form.commit_button %> # => "Create my %{model}"
428
+ <%= f.actions do %>
429
+ <%= f.action(:submit) %> # => "Create my %{model}"
416
430
  <% end %>
417
431
  <% end %>
418
432
  </pre>
@@ -422,8 +436,8 @@ Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the
422
436
  _Note: Slightly different because Formtastic can't guess how you group fields in a form. Legend text can be set with first (as in the sample below) specified value, or :name/:title options - depending on what flavor is preferred._
423
437
 
424
438
  <pre>
425
- <%= semantic_form_for @post do |form| %>
426
- <%= form.inputs :post_details do %> # => :title => "Post details"
439
+ <%= semantic_form_for @post do |f| %>
440
+ <%= f.inputs :post_details do %> # => :title => "Post details"
427
441
  # ...
428
442
  <% end %>
429
443
  # ...
@@ -433,14 +447,14 @@ _Note: Slightly different because Formtastic can't guess how you group fields in
433
447
  *5. Override I18n settings:*
434
448
 
435
449
  <pre>
436
- <%= semantic_form_for @post do |form| %>
437
- <%= form.inputs do %>
438
- <%= form.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for you post."
439
- <%= form.input :body, :hint => false %> # => :label => "Write something..."
440
- <%= form.input :section, :label => 'Some section' %> # => :label => 'Some section'
450
+ <%= semantic_form_for @post do |f| %>
451
+ <%= f.inputs do %>
452
+ <%= f.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for your post."
453
+ <%= f.input :body, :hint => false %> # => :label => "Write something..."
454
+ <%= f.input :section, :label => 'Some section' %> # => :label => 'Some section'
441
455
  <% end %>
442
- <%= form.buttons do %>
443
- <%= form.commit_button :dummie %> # => "Launch!"
456
+ <%= f.actions do %>
457
+ <%= f.actions(:submit, :label => :dummie) %> # => "Launch!"
444
458
  <% end %>
445
459
  <% end %>
446
460
  </pre>
@@ -454,21 +468,21 @@ If I18n-lookups is disabled, i.e.:
454
468
  ...then you can enable I18n within the forms instead:
455
469
 
456
470
  <pre>
457
- <%= semantic_form_for @post do |form| %>
458
- <%= form.inputs do %>
459
- <%= form.input :title, :label => true %> # => :label => "Choose a title..."
460
- <%= form.input :body, :label => true %> # => :label => "Write something..."
461
- <%= form.input :section, :label => true %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
471
+ <%= semantic_form_for @post do |f| %>
472
+ <%= f.inputs do %>
473
+ <%= f.input :title, :label => true %> # => :label => "Choose a title..."
474
+ <%= f.input :body, :label => true %> # => :label => "Write something..."
475
+ <%= f.input :section, :label => true %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
462
476
  <% end %>
463
- <%= form.buttons do %>
464
- <%= form.commit_button true %> # => "Update %{model}" (if we are in edit that is...)
477
+ <%= f.actions do %>
478
+ <%= f.action :submit, :label => true %> # => "Update %{model}" (if we are in edit that is...)
465
479
  <% end %>
466
480
  <% end %>
467
481
  </pre>
468
482
 
469
483
  *6. Advanced I18n lookups*
470
484
 
471
- For more flexible forms; Formtastic find translations using a bottom-up approach taking the following variables in account:
485
+ For more flexible forms; Formtastic finds translations using a bottom-up approach taking the following variables in account:
472
486
 
473
487
  * @MODEL@, e.g. "post"
474
488
  * @ACTION@, e.g. "edit"
@@ -506,15 +520,25 @@ h2. Semantic errors
506
520
  You can show errors on base (by default) and any other attribute just passing it name to semantic_errors method:
507
521
 
508
522
  <pre>
509
- <%= semantic_form_for @post do |form| %>
510
- <%= form.semantic_errors :state %>
523
+ <%= semantic_form_for @post do |f| %>
524
+ <%= f.semantic_errors :state %>
511
525
  <% end %>
512
526
  </pre>
513
527
 
514
528
 
515
529
  h2. Modified & Custom Inputs
516
530
 
517
- If you want to change the behaviour of an input, you can subclass it in your app. For example, to tweak @StringInput@, create a new file @app/inputs/string_input.rb@:
531
+ You can modify existing inputs, subclass them, or create your own from scratch. Here's the basic process:
532
+
533
+ * Create a file in @app/inputs@ with a filename ending in @_input.rb@. For example, @app/inputs/hat_size_input.rb@. Formtastic will automatically look in @app/inputs@ and find the file.
534
+ * In that file, declare a classname ending in @Input@. For example, @class HatSizeInput@. It must have a @to_html@ method for rendering.
535
+ * To use that input, leave off the word "input" in your @as@ statement. For example, @f.input(:size, :as => :hat_size)@
536
+
537
+ Specific examples follow.
538
+
539
+ h3. Changing Existing Input Behavior
540
+
541
+ To modify the behavior of @StringInput@, subclass it in a new file, @app/inputs/string_input.rb@:
518
542
 
519
543
  <pre>
520
544
  class StringInput < Formtastic::Inputs::StringInput
@@ -525,10 +549,13 @@ If you want to change the behaviour of an input, you can subclass it in your app
525
549
  end
526
550
  </pre>
527
551
 
528
- To create your own new types of inputs based on existing inputs, the process is similar:
552
+ You can use your modified version with @:as => :string@.
553
+
554
+ h3. Creating New Inputs Based on Existing Ones
555
+
556
+ To create your own new types of inputs based on existing inputs, the process is similar. For example, to create @FlexibleTextInput@ based on @StringInput@, put the following in @app/inputs/flexible_text_input.rb@:
529
557
 
530
558
  <pre>
531
- # f.input(:body, :as => :flexible_text)
532
559
  class FlexibleTextInput < Formtastic::Inputs::StringInput
533
560
  def input_html_options
534
561
  super.merge(:class => "flexible-text-area")
@@ -536,10 +563,13 @@ To create your own new types of inputs based on existing inputs, the process is
536
563
  end
537
564
  </pre>
538
565
 
539
- To create your own new types of inputs from scratch:
566
+ You can use your new input with @:as => :flexible_text@.
567
+
568
+ h3. Creating New Inputs From Scratch
569
+
570
+ To create a custom @DatePickerInput@ from scratch, put the following in @app/inputs/date_picker_input.rb@:
540
571
 
541
572
  <pre>
542
- # f.input(:created_at, :as => :date_picker)
543
573
  class DatePickerInput
544
574
  include Formtastic::Inputs::Base
545
575
  def to_html
@@ -548,12 +578,16 @@ To create your own new types of inputs from scratch:
548
578
  end
549
579
  </pre>
550
580
 
581
+ You can use your new input with @:as => :date_picker@.
582
+
583
+ h3. Don't subclass Formtastic::FormBuilder anymore
584
+
551
585
  It was previously recommended in Formtastic 1.x to subclass Formtastic::FormBuilder to add your own inputs. This is no longer recommended in Formtastic 2, and will not work as expected.
552
586
 
553
587
 
554
588
  h2. Security
555
589
 
556
- By default Formtastic escapes html entities in both labels and hints unless a string is marked as html_safe. If you are using an older rails version which doesn't know html_safe, or you want to globally turn this feature off, you can set the following in your initializer:
590
+ By default, Formtastic escapes HTML entities in both labels and hints unless a string is marked as html_safe. If you are using an older rails version which doesn't know html_safe, or you want to globally turn this feature off, you can set the following in your initializer:
557
591
 
558
592
  Formtastic::FormBuilder.escape_html_entities_in_hints_and_labels = false
559
593
 
@@ -562,33 +596,31 @@ h2. Dependencies
562
596
 
563
597
  There are none, but...
564
598
 
565
- * if you want to use the @:country@ input, you'll need to install the "country-select plugin":https://github.com/chrislerum/country_select (or any other country_select plugin with the same API).
599
+ * If you want to use the @:country@ input, you'll need to install the "country-select plugin":https://github.com/chrislerum/country_select (or any other country_select plugin with the same API).
566
600
  * "rspec":http://github.com/dchelimsky/rspec/, "rspec_hpricot_matchers":http://rubyforge.org/projects/rspec-hpricot/ and "rcov":http://github.com/relevance/rcov gems (plus any of their own dependencies) are required for the test suite.
567
601
 
568
602
 
569
603
  h2. How to contribute
570
604
 
571
- Please ensure that you provide appropriate spec/test coverage and ensure the documentation is up-to-date. Bonus points if you perform your changes in a clean topic branch rather than master, and if you create a pull request for your changes to be discussed and reviewed.
572
-
573
- Please also keep your commits *atomic* so that they are more likely to apply cleanly. That means that each commit should contain the smallest possible logical change. Don't commit two features at once, don't update the gemspec at the same time you add a feature, don't fix a whole bunch of whitespace in a file at the same time you change a few lines, etc, etc.
605
+ * Fork the project on Github
606
+ * Create a topic branch for your changes
607
+ * Ensure that all tests pass (`bundle exec rake`)
608
+ * Ensure that the changes in your branch are as atomic as possible
609
+ * Create a pull request on Github
574
610
 
575
- For significant changes, you may wish to discuss your idea on the Formtastic Google group before coding to ensure that your change is likely to be accepted. Formtastic relies heavily on i18n, so if you're unsure of the impact this has on your changes, please discuss them with the group.
576
-
577
- See below for installation of a development environment.
611
+ For significant changes, you may wish to discuss your idea on the Formtastic Google group before coding to ensure that your change is likely to be accepted. Formtastic relies heavily on i18n, so if you're unsure of the impact this has on your changes, please discuss them with the group.
578
612
 
579
613
 
580
614
  h2. Google Group, Twitter, etc
581
615
 
582
616
  Please join the "Formtastic Google Group":http://groups.google.com.au/group/formtastic, especially if you'd like to talk about a new feature, or report a bug.
583
617
 
584
- You can also "follow @formtastic on Twitter":http://twitter.com/formtastic for announcements, tutorials and awesome Formtastic links.
618
+ You can also follow "@justinfrench":http://twitter.com/formtastic or "@formtastic":http://twitter.com/formtastic on Twitter for announcements, tutorials and links.
585
619
 
586
620
  h2. Project Info
587
621
 
588
- Formtastic was created by "Justin French":http://www.justinfrench.com with contributions from over 100 awesome developers.
589
-
590
- Run @git shortlog -n -s@ to see the awesome.
622
+ Formtastic was created by "Justin French":http://www.justinfrench.com with contributions from around 150 awesome developers. Run @git shortlog -n -s@ to see the awesome.
591
623
 
592
624
  The project is hosted on Github: "http://github.com/justinfrench/formtastic":http://github.com/justinfrench/formtastic, where your contributions, forkings, comments, issues and feedback are greatly welcomed.
593
625
 
594
- Copyright (c) 2007-2010 Justin French, released under the MIT license.
626
+ Copyright (c) 2007-2012 Justin French, released under the MIT license.