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.
- data/.gitignore +4 -1
- data/Appraisals +11 -0
- data/CHANGELOG +2 -2
- data/Gemfile +0 -2
- data/README.textile +183 -151
- data/Rakefile +9 -5
- data/app/assets/stylesheets/formtastic.css +16 -3
- data/formtastic.gemspec +6 -2
- data/gemfiles/rails-3.0.gemfile +7 -0
- data/gemfiles/rails-3.1.gemfile +7 -0
- data/gemfiles/rails-3.2.gemfile +7 -0
- data/lib/formtastic.rb +10 -2
- data/lib/formtastic/actions.rb +11 -0
- data/lib/formtastic/actions/base.rb +156 -0
- data/lib/formtastic/actions/button_action.rb +72 -0
- data/lib/formtastic/actions/buttonish.rb +17 -0
- data/lib/formtastic/actions/input_action.rb +68 -0
- data/lib/formtastic/actions/link_action.rb +87 -0
- data/lib/formtastic/engine.rb +5 -1
- data/lib/formtastic/form_builder.rb +3 -0
- data/lib/formtastic/helpers.rb +2 -1
- data/lib/formtastic/helpers/action_helper.rb +109 -0
- data/lib/formtastic/helpers/actions_helper.rb +168 -0
- data/lib/formtastic/helpers/buttons_helper.rb +22 -9
- data/lib/formtastic/helpers/errors_helper.rb +0 -54
- data/lib/formtastic/helpers/fieldset_wrapper.rb +10 -5
- data/lib/formtastic/helpers/form_helper.rb +2 -2
- data/lib/formtastic/helpers/input_helper.rb +1 -10
- data/lib/formtastic/helpers/inputs_helper.rb +6 -3
- data/lib/formtastic/i18n.rb +3 -2
- data/lib/formtastic/inputs/base.rb +11 -3
- data/lib/formtastic/inputs/base/choices.rb +6 -1
- data/lib/formtastic/inputs/base/collections.rb +36 -13
- data/lib/formtastic/inputs/base/grouped_collections.rb +1 -1
- data/lib/formtastic/inputs/base/numeric.rb +50 -0
- data/lib/formtastic/inputs/base/options.rb +1 -1
- data/lib/formtastic/inputs/base/placeholder.rb +17 -0
- data/lib/formtastic/inputs/base/stringish.rb +2 -7
- data/lib/formtastic/inputs/base/timeish.rb +21 -5
- data/lib/formtastic/inputs/base/validations.rb +1 -1
- data/lib/formtastic/inputs/base/wrapping.rb +10 -3
- data/lib/formtastic/inputs/boolean_input.rb +10 -2
- data/lib/formtastic/inputs/check_boxes_input.rb +18 -9
- data/lib/formtastic/inputs/country_input.rb +2 -2
- data/lib/formtastic/inputs/date_input.rb +19 -1
- data/lib/formtastic/inputs/datetime_input.rb +1 -1
- data/lib/formtastic/inputs/email_input.rb +2 -1
- data/lib/formtastic/inputs/file_input.rb +1 -1
- data/lib/formtastic/inputs/hidden_input.rb +1 -1
- data/lib/formtastic/inputs/number_input.rb +6 -36
- data/lib/formtastic/inputs/password_input.rb +2 -1
- data/lib/formtastic/inputs/phone_input.rb +3 -2
- data/lib/formtastic/inputs/radio_input.rb +1 -1
- data/lib/formtastic/inputs/range_input.rb +8 -32
- data/lib/formtastic/inputs/search_input.rb +2 -1
- data/lib/formtastic/inputs/select_input.rb +56 -28
- data/lib/formtastic/inputs/string_input.rb +3 -1
- data/lib/formtastic/inputs/text_input.rb +5 -4
- data/lib/formtastic/inputs/time_input.rb +4 -8
- data/lib/formtastic/inputs/time_zone_input.rb +1 -1
- data/lib/formtastic/inputs/url_input.rb +2 -1
- data/lib/formtastic/localized_string.rb +6 -94
- data/lib/formtastic/localizer.rb +110 -0
- data/lib/formtastic/version.rb +1 -1
- data/lib/generators/formtastic/form/form_generator.rb +105 -0
- data/lib/generators/templates/_form.html.erb +2 -2
- data/lib/generators/templates/_form.html.haml +4 -4
- data/lib/generators/templates/_form.html.slim +2 -2
- data/lib/generators/templates/formtastic.rb +4 -0
- data/lib/locale/en.yml +2 -0
- data/sample/basic_inputs.html +22 -0
- data/spec/actions/button_action_spec.rb +63 -0
- data/spec/actions/generic_action_spec.rb +484 -0
- data/spec/actions/input_action_spec.rb +59 -0
- data/spec/actions/link_action_spec.rb +92 -0
- data/spec/builder/semantic_fields_for_spec.rb +14 -0
- data/spec/generators/formtastic/form/form_generator_spec.rb +118 -0
- data/spec/generators/formtastic/install/install_generator_spec.rb +47 -0
- data/spec/helpers/action_helper_spec.rb +365 -0
- data/spec/helpers/actions_helper_spec.rb +143 -0
- data/spec/helpers/buttons_helper_spec.rb +39 -23
- data/spec/helpers/commit_button_helper_spec.rb +153 -93
- data/spec/helpers/inputs_helper_spec.rb +14 -0
- data/spec/i18n_spec.rb +11 -0
- data/spec/inputs/boolean_input_spec.rb +31 -2
- data/spec/inputs/check_boxes_input_spec.rb +29 -1
- data/spec/inputs/date_input_spec.rb +95 -0
- data/spec/inputs/datetime_input_spec.rb +49 -0
- data/spec/inputs/email_input_spec.rb +28 -0
- data/spec/inputs/file_input_spec.rb +28 -0
- data/spec/inputs/hidden_input_spec.rb +28 -0
- data/spec/inputs/include_blank_spec.rb +53 -45
- data/spec/inputs/number_input_spec.rb +34 -4
- data/spec/inputs/password_input_spec.rb +28 -0
- data/spec/inputs/phone_input_spec.rb +28 -0
- data/spec/inputs/placeholder_spec.rb +10 -10
- data/spec/inputs/radio_input_spec.rb +51 -6
- data/spec/inputs/range_input_spec.rb +30 -2
- data/spec/inputs/search_input_spec.rb +27 -0
- data/spec/inputs/select_input_spec.rb +52 -6
- data/spec/inputs/string_input_spec.rb +28 -0
- data/spec/inputs/text_input_spec.rb +27 -0
- data/spec/inputs/time_input_spec.rb +67 -1
- data/spec/inputs/time_zone_input_spec.rb +28 -0
- data/spec/inputs/url_input_spec.rb +28 -0
- data/spec/inputs/with_options_spec.rb +43 -0
- data/spec/spec_helper.rb +22 -6
- data/spec/support/custom_macros.rb +6 -134
- data/spec/support/test_environment.rb +0 -1
- metadata +104 -17
- data/lib/formtastic/helpers/semantic_form_helper.rb +0 -11
- data/lib/formtastic/inputs/numeric_input.rb +0 -21
- data/lib/formtastic/railtie.rb +0 -12
- data/lib/formtastic/semantic_form_builder.rb +0 -11
- data/spec/builder/errors_spec.rb +0 -203
- data/spec/inputs/numeric_input_spec.rb +0 -41
data/.gitignore
CHANGED
data/Appraisals
ADDED
data/CHANGELOG
CHANGED
data/Gemfile
CHANGED
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 |
|
21
|
-
|
22
|
-
<%=
|
23
|
-
<%=
|
24
|
-
<%=
|
25
|
-
<%=
|
26
|
-
<%=
|
27
|
-
<%=
|
28
|
-
<%=
|
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
|
-
<%=
|
32
|
-
<%=
|
33
|
-
<%=
|
34
|
-
<%=
|
35
|
-
<%=
|
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
|
-
<%=
|
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
|
-
<%=
|
44
|
-
<%=
|
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
|
-
*
|
56
|
-
*
|
57
|
-
*
|
58
|
-
*
|
59
|
-
*
|
60
|
-
*
|
61
|
-
*
|
62
|
-
*
|
63
|
-
*
|
64
|
-
*
|
65
|
-
*
|
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
|
-
*
|
71
|
-
*
|
72
|
-
*
|
73
|
-
*
|
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
|
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 |
|
146
|
-
<%=
|
147
|
-
<%=
|
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
|
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 |
|
157
|
-
<%=
|
158
|
-
<%=
|
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 @
|
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 |
|
166
|
-
<%=
|
167
|
-
<%=
|
168
|
-
<%=
|
169
|
-
<%=
|
170
|
-
<%=
|
171
|
-
<%=
|
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
|
-
<%=
|
174
|
-
<%=
|
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 |
|
183
|
-
<%=
|
184
|
-
<%=
|
185
|
-
<%=
|
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
|
-
<%=
|
188
|
-
<%=
|
189
|
-
<%=
|
190
|
-
<%=
|
191
|
-
<%=
|
192
|
-
<%=
|
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
|
-
<%=
|
195
|
-
<%=
|
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 |
|
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 |
|
210
|
-
<%=
|
211
|
-
<%=
|
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
|
-
<%=
|
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 |
|
222
|
-
<%=
|
223
|
-
<%=
|
224
|
-
<%=
|
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
|
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 |
|
232
|
-
<%=
|
233
|
-
<%=
|
234
|
-
<%=
|
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 |
|
243
|
-
<%=
|
244
|
-
|
245
|
-
|
246
|
-
|
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/
|
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 |
|
254
|
-
<%=
|
255
|
-
|
256
|
-
|
257
|
-
|
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
|
267
|
+
The same can be done for actions with the @:button_html@ option:
|
262
268
|
|
263
269
|
<pre>
|
264
|
-
<%= semantic_form_for @post do |
|
270
|
+
<%= semantic_form_for @post do |f| %>
|
265
271
|
...
|
266
|
-
<%=
|
267
|
-
<%=
|
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 |
|
276
|
-
<%=
|
277
|
-
|
278
|
-
|
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 |
|
287
|
-
<%=
|
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
|
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 |
|
358
|
-
<%=
|
359
|
-
|
360
|
-
|
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
|
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 |
|
409
|
-
<%=
|
410
|
-
<%=
|
411
|
-
<%=
|
412
|
-
<%=
|
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
|
-
<%=
|
415
|
-
<%=
|
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 |
|
426
|
-
<%=
|
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 |
|
437
|
-
<%=
|
438
|
-
<%=
|
439
|
-
<%=
|
440
|
-
<%=
|
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
|
-
<%=
|
443
|
-
<%=
|
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 |
|
458
|
-
<%=
|
459
|
-
<%=
|
460
|
-
<%=
|
461
|
-
<%=
|
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
|
-
<%=
|
464
|
-
<%=
|
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
|
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 |
|
510
|
-
<%=
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
*
|
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
|
-
|
572
|
-
|
573
|
-
|
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.
|
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
|
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
|
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-
|
626
|
+
Copyright (c) 2007-2012 Justin French, released under the MIT license.
|