simple_form 2.0.0 → 3.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of simple_form might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +97 -198
- data/MIT-LICENSE +1 -1
- data/README.md +572 -296
- data/lib/generators/simple_form/install_generator.rb +17 -7
- data/lib/generators/simple_form/templates/README +3 -4
- data/lib/generators/simple_form/templates/_form.html.erb +1 -0
- data/lib/generators/simple_form/templates/_form.html.haml +1 -0
- data/lib/generators/simple_form/templates/config/initializers/{simple_form.rb.tt → simple_form.rb} +57 -63
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +155 -0
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +111 -0
- data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +14 -7
- data/lib/simple_form/action_view_extensions/builder.rb +5 -305
- data/lib/simple_form/action_view_extensions/form_helper.rb +18 -20
- data/lib/simple_form/components/errors.rb +30 -3
- data/lib/simple_form/components/hints.rb +10 -3
- data/lib/simple_form/components/html5.rb +17 -3
- data/lib/simple_form/components/label_input.rb +21 -2
- data/lib/simple_form/components/labels.rb +16 -11
- data/lib/simple_form/components/maxlength.rb +19 -12
- data/lib/simple_form/components/min_max.rb +4 -2
- data/lib/simple_form/components/minlength.rb +48 -0
- data/lib/simple_form/components/pattern.rb +5 -4
- data/lib/simple_form/components/placeholders.rb +3 -2
- data/lib/simple_form/components/readonly.rb +3 -2
- data/lib/simple_form/components.rb +15 -11
- data/lib/simple_form/error_notification.rb +4 -3
- data/lib/simple_form/form_builder.rb +283 -105
- data/lib/simple_form/helpers/autofocus.rb +1 -0
- data/lib/simple_form/helpers/disabled.rb +1 -0
- data/lib/simple_form/helpers/readonly.rb +1 -0
- data/lib/simple_form/helpers/required.rb +1 -0
- data/lib/simple_form/helpers/validators.rb +4 -3
- data/lib/simple_form/helpers.rb +7 -6
- data/lib/simple_form/i18n_cache.rb +1 -0
- data/lib/simple_form/inputs/base.rb +76 -23
- data/lib/simple_form/inputs/block_input.rb +3 -2
- data/lib/simple_form/inputs/boolean_input.rb +55 -16
- data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -1
- data/lib/simple_form/inputs/collection_input.rb +41 -18
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +11 -19
- data/lib/simple_form/inputs/collection_select_input.rb +5 -2
- data/lib/simple_form/inputs/date_time_input.rb +23 -12
- data/lib/simple_form/inputs/file_input.rb +5 -2
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +16 -3
- data/lib/simple_form/inputs/hidden_input.rb +5 -2
- data/lib/simple_form/inputs/numeric_input.rb +4 -8
- data/lib/simple_form/inputs/password_input.rb +6 -4
- data/lib/simple_form/inputs/priority_input.rb +5 -2
- data/lib/simple_form/inputs/range_input.rb +2 -1
- data/lib/simple_form/inputs/string_input.rb +6 -4
- data/lib/simple_form/inputs/text_input.rb +6 -3
- data/lib/simple_form/inputs.rb +20 -17
- data/lib/simple_form/map_type.rb +1 -0
- data/lib/simple_form/railtie.rb +15 -0
- data/lib/simple_form/tags.rb +69 -0
- data/lib/simple_form/version.rb +2 -1
- data/lib/simple_form/wrappers/builder.rb +12 -35
- data/lib/simple_form/wrappers/leaf.rb +29 -0
- data/lib/simple_form/wrappers/many.rb +12 -7
- data/lib/simple_form/wrappers/root.rb +7 -4
- data/lib/simple_form/wrappers/single.rb +12 -3
- data/lib/simple_form/wrappers.rb +3 -1
- data/lib/simple_form.rb +118 -63
- data/test/action_view_extensions/builder_test.rb +230 -164
- data/test/action_view_extensions/form_helper_test.rb +107 -39
- data/test/components/label_test.rb +105 -87
- data/test/form_builder/association_test.rb +131 -62
- data/test/form_builder/button_test.rb +15 -14
- data/test/form_builder/error_notification_test.rb +11 -10
- data/test/form_builder/error_test.rb +188 -34
- data/test/form_builder/general_test.rb +247 -102
- data/test/form_builder/hint_test.rb +59 -32
- data/test/form_builder/input_field_test.rb +138 -25
- data/test/form_builder/label_test.rb +84 -13
- data/test/form_builder/wrapper_test.rb +236 -33
- data/test/generators/simple_form_generator_test.rb +15 -4
- data/test/inputs/boolean_input_test.rb +147 -13
- data/test/inputs/collection_check_boxes_input_test.rb +166 -71
- data/test/inputs/collection_radio_buttons_input_test.rb +229 -113
- data/test/inputs/collection_select_input_test.rb +222 -85
- data/test/inputs/datetime_input_test.rb +134 -47
- data/test/inputs/disabled_test.rb +62 -21
- data/test/inputs/discovery_test.rb +70 -10
- data/test/inputs/file_input_test.rb +4 -3
- data/test/inputs/general_test.rb +90 -26
- data/test/inputs/grouped_collection_select_input_test.rb +88 -23
- data/test/inputs/hidden_input_test.rb +7 -5
- data/test/inputs/numeric_input_test.rb +56 -46
- data/test/inputs/priority_input_test.rb +31 -16
- data/test/inputs/readonly_test.rb +68 -27
- data/test/inputs/required_test.rb +63 -18
- data/test/inputs/string_input_test.rb +76 -51
- data/test/inputs/text_input_test.rb +21 -8
- data/test/simple_form_test.rb +9 -0
- data/test/support/discovery_inputs.rb +39 -2
- data/test/support/misc_helpers.rb +176 -20
- data/test/support/mock_controller.rb +13 -7
- data/test/support/models.rb +187 -71
- data/test/test_helper.rb +38 -39
- metadata +53 -39
- data/lib/simple_form/core_ext/hash.rb +0 -16
- data/test/support/mock_response.rb +0 -14
data/README.md
CHANGED
|
@@ -1,179 +1,93 @@
|
|
|
1
|
-
|
|
2
|
-
[](http://travis-ci.org/plataformatec/simple_form)
|
|
1
|
+

|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
By [Plataformatec](http://plataformatec.com.br/).
|
|
4
|
+
|
|
5
|
+
Rails forms made easy.
|
|
6
|
+
|
|
7
|
+
**Simple Form** aims to be as flexible as possible while helping you with powerful components to create
|
|
8
|
+
your forms. The basic goal of **Simple Form** is to not touch your way of defining the layout, letting
|
|
6
9
|
you find the better design for your eyes. Most of the DSL was inherited from Formtastic,
|
|
7
10
|
which we are thankful for and should make you feel right at home.
|
|
8
11
|
|
|
9
12
|
INFO: This README is [also available in a friendly navigable format](http://simple-form.plataformatec.com.br/)
|
|
10
|
-
and refers to **
|
|
11
|
-
check this branch:
|
|
12
|
-
|
|
13
|
-
https://github.com/plataformatec/simple_form/tree/v1.5
|
|
13
|
+
and refers to **Simple Form** 3.1. For older releases, check the related branch for your version.
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
17
17
|
Add it to your Gemfile:
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
```ruby
|
|
20
|
+
gem 'simple_form'
|
|
21
|
+
```
|
|
20
22
|
|
|
21
23
|
Run the following command to install it:
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
```console
|
|
26
|
+
bundle install
|
|
27
|
+
```
|
|
24
28
|
|
|
25
29
|
Run the generator:
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
[country_select gem](https://rubygems.org/gems/country_select), add it to your Gemfile:
|
|
31
|
-
|
|
32
|
-
`gem 'country_select'`
|
|
33
|
-
|
|
34
|
-
## Configuration
|
|
35
|
-
|
|
36
|
-
**SimpleForm** has several configuration options. You can read and change them in the initializer
|
|
37
|
-
created by **SimpleForm**, so if you haven't executed the command below yet, please do:
|
|
38
|
-
|
|
39
|
-
`rails generate simple_form:install`
|
|
31
|
+
```console
|
|
32
|
+
rails generate simple_form:install
|
|
33
|
+
```
|
|
40
34
|
|
|
41
|
-
###
|
|
35
|
+
### Bootstrap
|
|
42
36
|
|
|
43
|
-
**
|
|
37
|
+
**Simple Form** can be easily integrated to the [Bootstrap](http://getbootstrap.com/).
|
|
44
38
|
To do that you have to use the `bootstrap` option in the install generator, like this:
|
|
45
39
|
|
|
46
|
-
|
|
40
|
+
```console
|
|
41
|
+
rails generate simple_form:install --bootstrap
|
|
42
|
+
```
|
|
47
43
|
|
|
48
|
-
You have to be sure that you added a copy of the [
|
|
44
|
+
You have to be sure that you added a copy of the [Bootstrap](http://getbootstrap.com/)
|
|
49
45
|
assets on your application.
|
|
50
46
|
|
|
51
47
|
For more information see the generator output, our
|
|
52
48
|
[example application code](https://github.com/rafaelfranca/simple_form-bootstrap) and
|
|
53
49
|
[the live example app](http://simple-form-bootstrap.plataformatec.com.br/).
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
### The wrappers API
|
|
58
|
-
|
|
59
|
-
With **SimpleForm** you can configure how your components will be rendered using the wrappers API.
|
|
60
|
-
The syntax looks like this:
|
|
61
|
-
|
|
62
|
-
```ruby
|
|
63
|
-
config.wrappers :tag => :div, :class => :input,
|
|
64
|
-
:error_class => :field_with_errors do |b|
|
|
51
|
+
### Zurb Foundation 5
|
|
65
52
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
b.optional :pattern
|
|
69
|
-
b.use :maxlength
|
|
70
|
-
b.use :placeholder
|
|
71
|
-
b.use :readonly
|
|
53
|
+
To generate wrappers that are compatible with [Zurb Foundation 5](http://foundation.zurb.com/), pass
|
|
54
|
+
the `foundation` option to the generator, like this:
|
|
72
55
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
b.use :hint, :wrap_with => { :tag => :span, :class => :hint }
|
|
76
|
-
b.use :error, :wrap_with => { :tag => :span, :class => :error }
|
|
77
|
-
end
|
|
56
|
+
```console
|
|
57
|
+
rails generate simple_form:install --foundation
|
|
78
58
|
```
|
|
79
59
|
|
|
80
|
-
|
|
60
|
+
Please note that the Foundation wrapper does not support the `:hint` option by default. In order to
|
|
61
|
+
enable hints, please uncomment the appropriate line in `config/initializers/simple_form_foundation.rb`.
|
|
62
|
+
You will need to provide your own CSS styles for hints.
|
|
81
63
|
|
|
82
|
-
|
|
83
|
-
add extra information to your components.
|
|
64
|
+
Please see the [instructions on how to install Foundation in a Rails app](http://foundation.zurb.com/docs/applications.html).
|
|
84
65
|
|
|
85
|
-
|
|
66
|
+
### Country Select
|
|
86
67
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
b.use :placeholder
|
|
90
|
-
b.use :label_input
|
|
91
|
-
b.wrapper :tag => :div, :class => 'separator' do |component|
|
|
92
|
-
component.use :hint, :wrap_with => { :tag => :span, :class => :hint }
|
|
93
|
-
component.use :error, :wrap_with => { :tag => :span, :class => :error }
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
this will wrap the hint and error components within a `div` tag using the class `'separator'`.
|
|
99
|
-
|
|
100
|
-
If you want to customize the custom _Form components_ on demand you can give it a name like this:
|
|
101
|
-
|
|
102
|
-
```ruby
|
|
103
|
-
config.wrappers do |b|
|
|
104
|
-
b.use :placeholder
|
|
105
|
-
b.use :label_input
|
|
106
|
-
b.wrapper :my_wrapper, :tag => :div, :class => 'separator' do |component|
|
|
107
|
-
component.use :hint, :wrap_with => { :tag => :span, :class => :hint }
|
|
108
|
-
component.use :error, :wrap_with => { :tag => :span, :class => :error }
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
and now you can pass options to your `input` calls to customize the `:my_wrapper` _Form component_.
|
|
114
|
-
|
|
115
|
-
```ruby
|
|
116
|
-
# Completely turns off the custom wrapper
|
|
117
|
-
f.input :name, :my_wrapper => false
|
|
118
|
-
|
|
119
|
-
# Configure the html
|
|
120
|
-
f.input :name, :my_wrapper_html => { :id => 'special_id' }
|
|
121
|
-
|
|
122
|
-
# Configure the tag
|
|
123
|
-
f.input :name, :my_wrapper_tag => :p
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
You can also define more than one wrapper and pick one to render in a specific form or input.
|
|
127
|
-
To define another wrapper you have to give it a name, as the follow:
|
|
128
|
-
|
|
129
|
-
```ruby
|
|
130
|
-
config.wrappers :small do |b|
|
|
131
|
-
b.use :placeholder
|
|
132
|
-
b.use :label_input
|
|
133
|
-
end
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
and use it in this way:
|
|
68
|
+
If you want to use the country select, you will need the
|
|
69
|
+
[country_select gem](https://rubygems.org/gems/country_select), add it to your Gemfile:
|
|
137
70
|
|
|
138
71
|
```ruby
|
|
139
|
-
|
|
140
|
-
simple_form_for @user, :wrapper => :small do |f|
|
|
141
|
-
f.input :name
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
# Specifying to one input
|
|
145
|
-
simple_form_for @user do |f|
|
|
146
|
-
f.input :name, :wrapper => :small
|
|
147
|
-
end
|
|
72
|
+
gem 'country_select'
|
|
148
73
|
```
|
|
149
74
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
default values to `false` or use the `optional` method. Is preferible to use the `optional` syntax:
|
|
75
|
+
If you don't want to use the gem you can easily override this behaviour by mapping the
|
|
76
|
+
country inputs to something else, with a line like this in your `simple_form.rb` initializer:
|
|
153
77
|
|
|
154
78
|
```ruby
|
|
155
|
-
config.
|
|
156
|
-
b.use :placeholder
|
|
157
|
-
b.use :label_input
|
|
158
|
-
b.wrapper :tag => :div, :class => 'separator' do |component|
|
|
159
|
-
component.optional :hint, :wrap_with => { :tag => :span, :class => :hint }
|
|
160
|
-
component.use :error, :wrap_with => { :tag => :span, :class => :error }
|
|
161
|
-
end
|
|
162
|
-
end
|
|
79
|
+
config.input_mappings = { /country/ => :string }
|
|
163
80
|
```
|
|
164
81
|
|
|
165
|
-
By setting it as `optional`, a hint will only be generated when `:hint => true` is explicitly used.
|
|
166
|
-
The same for placehold.
|
|
167
|
-
|
|
168
82
|
## Usage
|
|
169
83
|
|
|
170
|
-
**
|
|
84
|
+
**Simple Form** was designed to be customized as you need to. Basically it's a stack of components that
|
|
171
85
|
are invoked to create a complete html input for you, which by default contains label, hints, errors
|
|
172
86
|
and the input itself. It does not aim to create a lot of different logic from the default Rails
|
|
173
|
-
form helpers, as they do a great
|
|
174
|
-
maps your input type (retrieved from the column definition in the database) to
|
|
87
|
+
form helpers, as they do a great job by themselves. Instead, **Simple Form** acts as a DSL and just
|
|
88
|
+
maps your input type (retrieved from the column definition in the database) to a specific helper method.
|
|
175
89
|
|
|
176
|
-
To start using **
|
|
90
|
+
To start using **Simple Form** you just have to use the helper it provides:
|
|
177
91
|
|
|
178
92
|
```erb
|
|
179
93
|
<%= simple_form_for @user do |f| %>
|
|
@@ -186,26 +100,27 @@ To start using **SimpleForm** you just have to use the helper it provides:
|
|
|
186
100
|
This will generate an entire form with labels for user name and password as well, and render errors
|
|
187
101
|
by default when you render the form with invalid data (after submitting for example).
|
|
188
102
|
|
|
189
|
-
You can overwrite the default label by passing it to the input method. You can also add a hint
|
|
190
|
-
even a placeholder:
|
|
103
|
+
You can overwrite the default label by passing it to the input method. You can also add a hint,
|
|
104
|
+
an error, or even a placeholder. For boolean inputs, you can add an inline label as well:
|
|
191
105
|
|
|
192
106
|
```erb
|
|
193
107
|
<%= simple_form_for @user do |f| %>
|
|
194
|
-
<%= f.input :username, :
|
|
195
|
-
<%= f.input :password, :
|
|
196
|
-
<%= f.input :email, :
|
|
108
|
+
<%= f.input :username, label: 'Your username please', error: 'Username is mandatory, please specify one' %>
|
|
109
|
+
<%= f.input :password, hint: 'No special characters.' %>
|
|
110
|
+
<%= f.input :email, placeholder: 'user@domain.com' %>
|
|
111
|
+
<%= f.input :remember_me, inline_label: 'Yes, remember me' %>
|
|
197
112
|
<%= f.button :submit %>
|
|
198
113
|
<% end %>
|
|
199
114
|
```
|
|
200
115
|
|
|
201
|
-
In some cases you may want to disable labels, hints or
|
|
116
|
+
In some cases you may want to disable labels, hints or errors. Or you may want to configure the html
|
|
202
117
|
of any of them:
|
|
203
118
|
|
|
204
119
|
```erb
|
|
205
120
|
<%= simple_form_for @user do |f| %>
|
|
206
|
-
<%= f.input :username, :
|
|
207
|
-
<%= f.input :password, :
|
|
208
|
-
<%= f.input :password_confirmation, :
|
|
121
|
+
<%= f.input :username, label_html: { class: 'my_class' } %>
|
|
122
|
+
<%= f.input :password, hint: false, error_html: { id: 'password_error'} %>
|
|
123
|
+
<%= f.input :password_confirmation, label: false %>
|
|
209
124
|
<%= f.button :submit %>
|
|
210
125
|
<% end %>
|
|
211
126
|
```
|
|
@@ -215,9 +130,9 @@ option, for instance:
|
|
|
215
130
|
|
|
216
131
|
```erb
|
|
217
132
|
<%= simple_form_for @user do |f| %>
|
|
218
|
-
<%= f.input :username, :
|
|
219
|
-
<%= f.input :password, :
|
|
220
|
-
<%= f.input :remember_me, :
|
|
133
|
+
<%= f.input :username, input_html: { class: 'special' } %>
|
|
134
|
+
<%= f.input :password, input_html: { maxlength: 20 } %>
|
|
135
|
+
<%= f.input :remember_me, input_html: { value: '1' } %>
|
|
221
136
|
<%= f.button :submit %>
|
|
222
137
|
<% end %>
|
|
223
138
|
```
|
|
@@ -227,77 +142,91 @@ you can use the `:defaults` option in `simple_form_for`. Specific options in `in
|
|
|
227
142
|
overwrite the defaults:
|
|
228
143
|
|
|
229
144
|
```erb
|
|
230
|
-
<%= simple_form_for @user, :
|
|
231
|
-
<%= f.input :username, :
|
|
232
|
-
<%= f.input :password, :
|
|
233
|
-
<%= f.input :remember_me, :
|
|
145
|
+
<%= simple_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f| %>
|
|
146
|
+
<%= f.input :username, input_html: { class: 'special' } %>
|
|
147
|
+
<%= f.input :password, input_html: { maxlength: 20 } %>
|
|
148
|
+
<%= f.input :remember_me, input_html: { value: '1' } %>
|
|
234
149
|
<%= f.button :submit %>
|
|
235
150
|
<% end %>
|
|
236
151
|
```
|
|
237
152
|
|
|
238
|
-
Since **
|
|
153
|
+
Since **Simple Form** generates a wrapper div around your label and input by default, you can pass
|
|
239
154
|
any html attribute to that wrapper as well using the `:wrapper_html` option, like so:
|
|
240
155
|
|
|
241
156
|
```erb
|
|
242
157
|
<%= simple_form_for @user do |f| %>
|
|
243
|
-
<%= f.input :username, :
|
|
244
|
-
<%= f.input :password, :
|
|
245
|
-
<%= f.input :remember_me, :
|
|
158
|
+
<%= f.input :username, wrapper_html: { class: 'username' } %>
|
|
159
|
+
<%= f.input :password, wrapper_html: { id: 'password' } %>
|
|
160
|
+
<%= f.input :remember_me, wrapper_html: { class: 'options' } %>
|
|
246
161
|
<%= f.button :submit %>
|
|
247
162
|
<% end %>
|
|
248
163
|
```
|
|
249
164
|
|
|
250
|
-
|
|
251
|
-
|
|
165
|
+
Required fields are marked with an * prepended to their labels.
|
|
166
|
+
|
|
167
|
+
By default all inputs are required. When the form object includes `ActiveModel::Validations`
|
|
168
|
+
(which, for example, happens with Active Record models), fields are required only when there is `presence` validation.
|
|
169
|
+
Otherwise, **Simple Form** will mark fields as optional. For performance reasons, this
|
|
170
|
+
detection is skipped on validations that make use of conditional options, such as `:if` and `:unless`.
|
|
171
|
+
|
|
172
|
+
And of course, the `required` property of any input can be overwritten as needed:
|
|
252
173
|
|
|
253
174
|
```erb
|
|
254
175
|
<%= simple_form_for @user do |f| %>
|
|
255
|
-
<%= f.input :name, :
|
|
176
|
+
<%= f.input :name, required: false %>
|
|
256
177
|
<%= f.input :username %>
|
|
257
178
|
<%= f.input :password %>
|
|
258
179
|
<%= f.button :submit %>
|
|
259
180
|
<% end %>
|
|
260
181
|
```
|
|
261
182
|
|
|
262
|
-
**
|
|
183
|
+
By default, **Simple Form** will look at the column type in the database and use an
|
|
184
|
+
appropriate input for the column. For example, a column created with type
|
|
185
|
+
`:text` in the database will use a `textarea` input by default. See the section
|
|
186
|
+
[Available input types and defaults for each column
|
|
187
|
+
type](https://github.com/plataformatec/simple_form#available-input-types-and-defaults-for-each-column-type)
|
|
188
|
+
for a complete list of defaults.
|
|
189
|
+
|
|
190
|
+
**Simple Form** also lets you overwrite the default input type it creates:
|
|
263
191
|
|
|
264
192
|
```erb
|
|
265
193
|
<%= simple_form_for @user do |f| %>
|
|
266
194
|
<%= f.input :username %>
|
|
267
195
|
<%= f.input :password %>
|
|
268
|
-
<%= f.input :description, :
|
|
269
|
-
<%= f.input :accepts, :
|
|
196
|
+
<%= f.input :description, as: :text %>
|
|
197
|
+
<%= f.input :accepts, as: :radio_buttons %>
|
|
270
198
|
<%= f.button :submit %>
|
|
271
199
|
<% end %>
|
|
272
200
|
```
|
|
273
201
|
|
|
274
202
|
So instead of a checkbox for the *accepts* attribute, you'll have a pair of radio buttons with yes/no
|
|
275
|
-
labels and a
|
|
276
|
-
attributes using
|
|
203
|
+
labels and a textarea instead of a text field for the description. You can also render boolean
|
|
204
|
+
attributes using `as: :select` to show a dropdown.
|
|
277
205
|
|
|
278
|
-
It is also possible to give the `:disabled` option to **
|
|
279
|
-
the wrapper as disabled with a
|
|
206
|
+
It is also possible to give the `:disabled` option to **Simple Form**, and it'll automatically mark
|
|
207
|
+
the wrapper as disabled with a CSS class, so you can style labels, hints and other components inside
|
|
280
208
|
the wrapper as well:
|
|
281
209
|
|
|
282
210
|
```erb
|
|
283
211
|
<%= simple_form_for @user do |f| %>
|
|
284
|
-
<%= f.input :username, :
|
|
212
|
+
<%= f.input :username, disabled: true, hint: 'You cannot change your username.' %>
|
|
285
213
|
<%= f.button :submit %>
|
|
286
214
|
<% end %>
|
|
287
215
|
```
|
|
288
216
|
|
|
289
|
-
**
|
|
217
|
+
**Simple Form** inputs accept the same options as their corresponding input type helper in Rails:
|
|
290
218
|
|
|
291
219
|
```erb
|
|
292
220
|
<%= simple_form_for @user do |f| %>
|
|
293
|
-
<%= f.input :date_of_birth, :
|
|
294
|
-
:
|
|
295
|
-
:
|
|
221
|
+
<%= f.input :date_of_birth, as: :date, start_year: Date.today.year - 90,
|
|
222
|
+
end_year: Date.today.year - 12, discard_day: true,
|
|
223
|
+
order: [:month, :year] %>
|
|
224
|
+
<%= f.input :accepts, as: :boolean, checked_value: true, unchecked_value: false %>
|
|
296
225
|
<%= f.button :submit %>
|
|
297
226
|
<% end %>
|
|
298
227
|
```
|
|
299
228
|
|
|
300
|
-
**
|
|
229
|
+
**Simple Form** also allows you to use label, hint, input_field, error and full_error helpers
|
|
301
230
|
(please take a look at the rdocs for each method for more info):
|
|
302
231
|
|
|
303
232
|
```erb
|
|
@@ -305,7 +234,7 @@ the wrapper as well:
|
|
|
305
234
|
<%= f.label :username %>
|
|
306
235
|
<%= f.input_field :username %>
|
|
307
236
|
<%= f.hint 'No special characters, please!' %>
|
|
308
|
-
<%= f.error :username, :
|
|
237
|
+
<%= f.error :username, id: 'user_name_error' %>
|
|
309
238
|
<%= f.full_error :token %>
|
|
310
239
|
<%= f.submit 'Save' %>
|
|
311
240
|
<% end %>
|
|
@@ -313,6 +242,61 @@ the wrapper as well:
|
|
|
313
242
|
|
|
314
243
|
Any extra option passed to these methods will be rendered as html option.
|
|
315
244
|
|
|
245
|
+
### Stripping away all wrapper divs
|
|
246
|
+
|
|
247
|
+
**Simple Form** also allows you to strip away all the div wrappers around the `<input>` field that is
|
|
248
|
+
generated with the usual `f.input`.
|
|
249
|
+
The easiest way to achieve this is to use `f.input_field`.
|
|
250
|
+
|
|
251
|
+
Example:
|
|
252
|
+
|
|
253
|
+
```ruby
|
|
254
|
+
simple_form_for @user do |f|
|
|
255
|
+
f.input_field :name
|
|
256
|
+
f.input_field :remember_me, as: :boolean
|
|
257
|
+
end
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
```html
|
|
261
|
+
<form>
|
|
262
|
+
...
|
|
263
|
+
<input class="string required" id="user_name" maxlength="255" name="user[name]" size="255" type="text">
|
|
264
|
+
<input name="user[remember_me]" type="hidden" value="0">
|
|
265
|
+
<label class="checkbox">
|
|
266
|
+
<input class="boolean optional" id="user_published" name="user[remember_me]" type="checkbox" value="1">
|
|
267
|
+
</label>
|
|
268
|
+
</form>
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
For check boxes and radio buttons you can remove the label changing `boolean_style` from default value `:nested` to `:inline`.
|
|
272
|
+
|
|
273
|
+
Example:
|
|
274
|
+
|
|
275
|
+
```ruby
|
|
276
|
+
simple_form_for @user do |f|
|
|
277
|
+
f.input_field :name
|
|
278
|
+
f.input_field :remember_me, as: :boolean, boolean_style: :inline
|
|
279
|
+
end
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
```html
|
|
283
|
+
<form>
|
|
284
|
+
...
|
|
285
|
+
<input class="string required" id="user_name" maxlength="255" name="user[name]" size="255" type="text">
|
|
286
|
+
<input name="user[remember_me]" type="hidden" value="0">
|
|
287
|
+
<input class="boolean optional" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1">
|
|
288
|
+
</form>
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Produces:
|
|
292
|
+
|
|
293
|
+
```html
|
|
294
|
+
<input class="string required" id="user_name" maxlength="100"
|
|
295
|
+
name="user[name]" size="100" type="text" value="Carlos" />
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
To view the actual RDocs for this, check them out here - http://rubydoc.info/github/plataformatec/simple_form/master/SimpleForm/FormBuilder:input_field
|
|
299
|
+
|
|
316
300
|
### Collections
|
|
317
301
|
|
|
318
302
|
And what if you want to create a select containing the age from 18 to 60 in your form? You can do it
|
|
@@ -321,91 +305,86 @@ overriding the `:collection` option:
|
|
|
321
305
|
```erb
|
|
322
306
|
<%= simple_form_for @user do |f| %>
|
|
323
307
|
<%= f.input :user %>
|
|
324
|
-
<%= f.input :age, :
|
|
308
|
+
<%= f.input :age, collection: 18..60 %>
|
|
325
309
|
<%= f.button :submit %>
|
|
326
310
|
<% end %>
|
|
327
311
|
```
|
|
328
312
|
|
|
329
313
|
Collections can be arrays or ranges, and when a `:collection` is given the `:select` input will be
|
|
330
|
-
rendered by default, so we don't need to pass the
|
|
331
|
-
are `:radio_buttons` and `:check_boxes`. Those are added by **
|
|
332
|
-
helpers (read Extra Helpers
|
|
314
|
+
rendered by default, so we don't need to pass the `as: :select` option. Other types of collection
|
|
315
|
+
are `:radio_buttons` and `:check_boxes`. Those are added by **Simple Form** to Rails set of form
|
|
316
|
+
helpers (read Extra Helpers section below for more information).
|
|
333
317
|
|
|
334
318
|
Collection inputs accept two other options beside collections:
|
|
335
319
|
|
|
336
|
-
*
|
|
320
|
+
* *label_method* => the label method to be applied to the collection to retrieve the label (use this
|
|
337
321
|
instead of the `text_method` option in `collection_select`)
|
|
338
322
|
|
|
339
|
-
*
|
|
323
|
+
* *value_method* => the value method to be applied to the collection to retrieve the value
|
|
340
324
|
|
|
341
325
|
Those methods are useful to manipulate the given collection. Both of these options also accept
|
|
342
326
|
lambda/procs in case you want to calculate the value or label in a special way eg. custom
|
|
343
|
-
translation.
|
|
344
|
-
|
|
327
|
+
translation. You can also define a `to_label` method on your model as **Simple Form** will search for
|
|
328
|
+
and use `:to_label` as a `:label_method` first if it is found.
|
|
329
|
+
|
|
330
|
+
By default, **Simple Form** will use the first item from an array as the label and the second one as the value.
|
|
331
|
+
If you want to change this behavior you must make it explicit, like this:
|
|
332
|
+
|
|
333
|
+
```erb
|
|
334
|
+
<%= simple_form_for @user do |f| %>
|
|
335
|
+
<%= f.input :gender, as: :radio_buttons, collection: [['0', 'female'], ['1', 'male']], label_method: :second, value_method: :first %>
|
|
336
|
+
<% end %>
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
All other options given are sent straight to the underlying helper. For example, you can give prompt as:
|
|
345
340
|
|
|
346
341
|
```ruby
|
|
347
|
-
f.input :age, :
|
|
342
|
+
f.input :age, collection: 18..60, prompt: "Select your age", selected: 21
|
|
348
343
|
```
|
|
344
|
+
Extra options are passed into helper [`collection_select`](http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select).
|
|
345
|
+
|
|
346
|
+
You may also find it useful to explicitly pass a value to the optional `:selected`, especially if passing a collection of nested objects.
|
|
349
347
|
|
|
350
348
|
It is also possible to create grouped collection selects, that will use the html *optgroup* tags, like this:
|
|
351
349
|
|
|
352
350
|
```ruby
|
|
353
|
-
f.input :country_id, :
|
|
351
|
+
f.input :country_id, collection: @continents, as: :grouped_select, group_method: :countries
|
|
354
352
|
```
|
|
355
353
|
|
|
356
354
|
Grouped collection inputs accept the same `:label_method` and `:value_method` options, which will be
|
|
357
355
|
used to retrieve label/value attributes for the `option` tags. Besides that, you can give:
|
|
358
356
|
|
|
359
|
-
*
|
|
357
|
+
* *group_method* => the method to be called on the given collection to generate the options for
|
|
360
358
|
each group (required)
|
|
361
359
|
|
|
362
|
-
*
|
|
363
|
-
for the _optgroup_ (**
|
|
360
|
+
* *group_label_method* => the label method to be applied on the given collection to retrieve the label
|
|
361
|
+
for the _optgroup_ (**Simple Form** will attempt to guess the best one the same way it does with
|
|
364
362
|
`:label_method`)
|
|
365
363
|
|
|
366
364
|
### Priority
|
|
367
365
|
|
|
368
|
-
**
|
|
369
|
-
`:priority` as option to select which time zones and/or countries should be given higher priority:
|
|
366
|
+
**Simple Form** also supports `:time_zone` and `:country`. When using such helpers, you can give
|
|
367
|
+
`:priority` as an option to select which time zones and/or countries should be given higher priority:
|
|
370
368
|
|
|
371
369
|
```ruby
|
|
372
|
-
f.input :residence_country, :
|
|
373
|
-
f.input :time_zone, :
|
|
370
|
+
f.input :residence_country, priority: [ "Brazil" ]
|
|
371
|
+
f.input :time_zone, priority: /US/
|
|
374
372
|
```
|
|
375
373
|
|
|
376
|
-
Those values can also be configured with a default value to be used site
|
|
374
|
+
Those values can also be configured with a default value to be used on the site through the
|
|
377
375
|
`SimpleForm.country_priority` and `SimpleForm.time_zone_priority` helpers.
|
|
378
376
|
|
|
379
377
|
Note: While using `country_select` if you want to restrict to only a subset of countries for a specific
|
|
380
378
|
drop down then you may use the `:collection` option:
|
|
381
379
|
|
|
382
380
|
```ruby
|
|
383
|
-
f.input :shipping_country, :
|
|
381
|
+
f.input :shipping_country, priority: [ "Brazil" ], collection: [ "Australia", "Brazil", "New Zealand"]
|
|
384
382
|
```
|
|
385
383
|
|
|
386
|
-
###
|
|
384
|
+
### Associations
|
|
387
385
|
|
|
388
|
-
**
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
```ruby
|
|
392
|
-
SimpleForm.wrapper_tag = :p
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
And now, you no longer need to wrap your `f.input` calls anymore:
|
|
396
|
-
|
|
397
|
-
```erb
|
|
398
|
-
<%= simple_form_for @user do |f| %>
|
|
399
|
-
<%= f.input :username %>
|
|
400
|
-
<%= f.input :password %>
|
|
401
|
-
<%= f.button :submit %>
|
|
402
|
-
<% end %>
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
## Associations
|
|
406
|
-
|
|
407
|
-
To deal with associations, **SimpleForm** can generate select inputs, a series of radios buttons or check boxes.
|
|
408
|
-
Lets see how it works: imagine you have a user model that belongs to a company and has_and_belongs_to_many
|
|
386
|
+
To deal with associations, **Simple Form** can generate select inputs, a series of radios buttons or checkboxes.
|
|
387
|
+
Lets see how it works: imagine you have a user model that belongs to a company and `has_and_belongs_to_many`
|
|
409
388
|
roles. The structure would be something like:
|
|
410
389
|
|
|
411
390
|
```ruby
|
|
@@ -436,11 +415,11 @@ Now we have the user form:
|
|
|
436
415
|
|
|
437
416
|
Simple enough, right? This is going to render a `:select` input for choosing the `:company`, and another
|
|
438
417
|
`:select` input with `:multiple` option for the `:roles`. You can, of course, change it to use radio
|
|
439
|
-
buttons and
|
|
418
|
+
buttons and checkboxes as well:
|
|
440
419
|
|
|
441
420
|
```ruby
|
|
442
|
-
f.association :company, :
|
|
443
|
-
f.association :roles, :
|
|
421
|
+
f.association :company, as: :radio_buttons
|
|
422
|
+
f.association :roles, as: :check_boxes
|
|
444
423
|
```
|
|
445
424
|
|
|
446
425
|
The association helper just invokes `input` under the hood, so all options available to `:select`,
|
|
@@ -448,12 +427,21 @@ The association helper just invokes `input` under the hood, so all options avail
|
|
|
448
427
|
the collection by hand, all together with the prompt:
|
|
449
428
|
|
|
450
429
|
```ruby
|
|
451
|
-
f.association :company, :
|
|
430
|
+
f.association :company, collection: Company.active.order(:name), prompt: "Choose a Company"
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
In case you want to declare different labels and values:
|
|
434
|
+
|
|
435
|
+
```ruby
|
|
436
|
+
f.association :company, label_method: :company_name, value_method: :id, include_blank: false
|
|
452
437
|
```
|
|
453
438
|
|
|
454
|
-
|
|
439
|
+
Please note that the association helper is currently only tested with Active Record. It currently
|
|
440
|
+
does not work well with Mongoid and depending on the ORM you're using your mileage may vary.
|
|
455
441
|
|
|
456
|
-
|
|
442
|
+
### Buttons
|
|
443
|
+
|
|
444
|
+
All web forms need buttons, right? **Simple Form** wraps them in the DSL, acting like a proxy:
|
|
457
445
|
|
|
458
446
|
```erb
|
|
459
447
|
<%= simple_form_for @user do |f| %>
|
|
@@ -464,28 +452,45 @@ All web forms need buttons, right? **SimpleForm** wraps them in the DSL, acting
|
|
|
464
452
|
|
|
465
453
|
The above will simply call submit. You choose to use it or not, it's just a question of taste.
|
|
466
454
|
|
|
467
|
-
|
|
455
|
+
The button method also accepts optional parameters, that are delegated to the underlying submit call:
|
|
456
|
+
|
|
457
|
+
```erb
|
|
458
|
+
<%= f.button :submit, "Custom Button Text", class: "my-button" %>
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
To create a `<button>` element, use the following syntax:
|
|
462
|
+
|
|
463
|
+
```erb
|
|
464
|
+
<%= f.button :button, "Custom Button Text" %>
|
|
465
|
+
|
|
466
|
+
<%= f.button :button do %>
|
|
467
|
+
Custom Button Text
|
|
468
|
+
<% end %>
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Wrapping Rails Form Helpers
|
|
468
472
|
|
|
469
|
-
Say you wanted to use a rails form helper but still wrap it in **
|
|
473
|
+
Say you wanted to use a rails form helper but still wrap it in **Simple Form** goodness? You can, by
|
|
470
474
|
calling input with a block like so:
|
|
471
475
|
|
|
472
476
|
```erb
|
|
473
477
|
<%= f.input :role do %>
|
|
474
|
-
<%= f.select :role, Role.all.map { |r| [r.name, r.id, { :
|
|
478
|
+
<%= f.select :role, Role.all.map { |r| [r.name, r.id, { class: r.company.id }] }, include_blank: true %>
|
|
475
479
|
<% end %>
|
|
476
480
|
```
|
|
477
481
|
|
|
478
482
|
In the above example, we're taking advantage of Rails 3's select method that allows us to pass in a
|
|
479
483
|
hash of additional attributes for each option.
|
|
480
484
|
|
|
481
|
-
|
|
485
|
+
### Extra helpers
|
|
482
486
|
|
|
483
|
-
**
|
|
487
|
+
**Simple Form** also comes with some extra helpers you can use inside rails default forms without relying
|
|
484
488
|
on `simple_form_for` helper. They are listed below.
|
|
485
489
|
|
|
486
|
-
|
|
490
|
+
#### Simple Fields For
|
|
487
491
|
|
|
488
|
-
Wrapper to use
|
|
492
|
+
Wrapper to use **Simple Form** inside a default rails form. It works in the same way that the `fields_for`
|
|
493
|
+
Rails helper, but change the builder to use the `SimpleForm::FormBuilder`.
|
|
489
494
|
|
|
490
495
|
```ruby
|
|
491
496
|
form_for @user do |f|
|
|
@@ -496,7 +501,7 @@ form_for @user do |f|
|
|
|
496
501
|
end
|
|
497
502
|
```
|
|
498
503
|
|
|
499
|
-
|
|
504
|
+
#### Collection Radio Buttons
|
|
500
505
|
|
|
501
506
|
Creates a collection of radio inputs with labels associated (same API as `collection_select`):
|
|
502
507
|
|
|
@@ -513,9 +518,9 @@ end
|
|
|
513
518
|
<label class="collection_radio_buttons" for="user_options_false">No</label>
|
|
514
519
|
```
|
|
515
520
|
|
|
516
|
-
|
|
521
|
+
#### Collection Check Boxes
|
|
517
522
|
|
|
518
|
-
Creates a collection of
|
|
523
|
+
Creates a collection of checkboxes with labels associated (same API as `collection_select`):
|
|
519
524
|
|
|
520
525
|
```ruby
|
|
521
526
|
form_for @user do |f|
|
|
@@ -540,47 +545,50 @@ form_for @user do |f|
|
|
|
540
545
|
end
|
|
541
546
|
```
|
|
542
547
|
|
|
543
|
-
##
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
548
|
+
## Available input types and defaults for each column type
|
|
549
|
+
|
|
550
|
+
The following table shows the html element you will get for each attribute
|
|
551
|
+
according to its database definition. These defaults can be changed by
|
|
552
|
+
specifying the helper method in the column `Mapping` as the `as:` option.
|
|
553
|
+
|
|
554
|
+
Mapping | Generated HTML Element | Database Column Type
|
|
555
|
+
--------------- |--------------------------------------|---------------------
|
|
556
|
+
`boolean` | `input[type=checkbox]` | `boolean`
|
|
557
|
+
`string` | `input[type=text]` | `string`
|
|
558
|
+
`email` | `input[type=email]` | `string` with `name =~ /email/`
|
|
559
|
+
`url` | `input[type=url]` | `string` with `name =~ /url/`
|
|
560
|
+
`tel` | `input[type=tel]` | `string` with `name =~ /phone/`
|
|
561
|
+
`password` | `input[type=password]` | `string` with `name =~ /password/`
|
|
562
|
+
`search` | `input[type=search]` | -
|
|
563
|
+
`uuid` | `input[type=text]` | `uuid`
|
|
564
|
+
`text` | `textarea` | `text`
|
|
565
|
+
`file` | `input[type=file]` | `string` responding to file methods
|
|
566
|
+
`hidden` | `input[type=hidden]` | -
|
|
567
|
+
`integer` | `input[type=number]` | `integer`
|
|
568
|
+
`float` | `input[type=number]` | `float`
|
|
569
|
+
`decimal` | `input[type=number]` | `decimal`
|
|
570
|
+
`range` | `input[type=range]` | -
|
|
571
|
+
`datetime` | `datetime select` | `datetime/timestamp`
|
|
572
|
+
`date` | `date select` | `date`
|
|
573
|
+
`time` | `time select` | `time`
|
|
574
|
+
`select` | `select` | `belongs_to`/`has_many`/`has_and_belongs_to_many` associations
|
|
575
|
+
`radio_buttons` | collection of `input[type=radio]` | `belongs_to` associations
|
|
576
|
+
`check_boxes` | collection of `input[type=checkbox]` | `has_many`/`has_and_belongs_to_many` associations
|
|
577
|
+
`country` | `select` (countries as options) | `string` with `name =~ /country/`
|
|
578
|
+
`time_zone` | `select` (timezones as options) | `string` with `name =~ /time_zone/`
|
|
573
579
|
|
|
574
580
|
## Custom inputs
|
|
575
581
|
|
|
576
|
-
It is very easy to add custom inputs to **
|
|
582
|
+
It is very easy to add custom inputs to **Simple Form**. For instance, if you want to add a custom input
|
|
577
583
|
that extends the string one, you just need to add this file:
|
|
578
584
|
|
|
579
585
|
```ruby
|
|
580
586
|
# app/inputs/currency_input.rb
|
|
581
587
|
class CurrencyInput < SimpleForm::Inputs::Base
|
|
582
|
-
def input
|
|
583
|
-
|
|
588
|
+
def input(wrapper_options)
|
|
589
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
|
590
|
+
|
|
591
|
+
"$ #{@builder.text_field(attribute_name, merged_input_options)}".html_safe
|
|
584
592
|
end
|
|
585
593
|
end
|
|
586
594
|
```
|
|
@@ -588,31 +596,65 @@ end
|
|
|
588
596
|
And use it in your views:
|
|
589
597
|
|
|
590
598
|
```ruby
|
|
591
|
-
f.input :money, :
|
|
599
|
+
f.input :money, as: :currency
|
|
592
600
|
```
|
|
601
|
+
Note, you may have to create the `app/inputs/` directory and restart your webserver.
|
|
593
602
|
|
|
594
|
-
You can also redefine existing **
|
|
603
|
+
You can also redefine existing **Simple Form** inputs by creating a new class with the same name. For
|
|
595
604
|
instance, if you want to wrap date/time/datetime in a div, you can do:
|
|
596
605
|
|
|
597
606
|
```ruby
|
|
598
607
|
# app/inputs/date_time_input.rb
|
|
599
608
|
class DateTimeInput < SimpleForm::Inputs::DateTimeInput
|
|
600
|
-
def input
|
|
601
|
-
|
|
609
|
+
def input(wrapper_options)
|
|
610
|
+
template.content_tag(:div, super)
|
|
611
|
+
end
|
|
612
|
+
end
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
Or if you want to add a class to all the select fields you can do:
|
|
616
|
+
|
|
617
|
+
```ruby
|
|
618
|
+
# app/inputs/collection_select_input.rb
|
|
619
|
+
class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
|
|
620
|
+
def input_html_classes
|
|
621
|
+
super.push('chosen')
|
|
602
622
|
end
|
|
603
623
|
end
|
|
604
624
|
```
|
|
605
625
|
|
|
626
|
+
If needed, you can namespace your custom inputs in a module and tell **Simple Form** to look for
|
|
627
|
+
their definitions in this module. This can avoid conflicts with other form libraries (like Formtastic) that look up
|
|
628
|
+
the global context to find inputs definition too.
|
|
629
|
+
|
|
630
|
+
```ruby
|
|
631
|
+
# app/inputs/custom_inputs/numeric_input
|
|
632
|
+
module CustomInputs
|
|
633
|
+
class NumericInput < SimpleForm::Inputs::NumericInput
|
|
634
|
+
def input_html_classes
|
|
635
|
+
super.push('no-spinner')
|
|
636
|
+
end
|
|
637
|
+
end
|
|
638
|
+
end
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
And in the **SimpleForm** initializer :
|
|
642
|
+
|
|
643
|
+
```ruby
|
|
644
|
+
# config/simple_form.rb
|
|
645
|
+
config.custom_inputs_namespaces << "CustomInputs"
|
|
646
|
+
```
|
|
647
|
+
|
|
606
648
|
## Custom form builder
|
|
607
649
|
|
|
608
|
-
You can create a custom form builder that uses **
|
|
650
|
+
You can create a custom form builder that uses **Simple Form**.
|
|
609
651
|
|
|
610
652
|
Create a helper method that calls `simple_form_for` with a custom builder:
|
|
611
653
|
|
|
612
654
|
```ruby
|
|
613
655
|
def custom_form_for(object, *args, &block)
|
|
614
656
|
options = args.extract_options!
|
|
615
|
-
simple_form_for(object, *(args << options.merge(:
|
|
657
|
+
simple_form_for(object, *(args << options.merge(builder: CustomFormBuilder)), &block)
|
|
616
658
|
end
|
|
617
659
|
```
|
|
618
660
|
|
|
@@ -621,15 +663,14 @@ Create a form builder class that inherits from `SimpleForm::FormBuilder`.
|
|
|
621
663
|
```ruby
|
|
622
664
|
class CustomFormBuilder < SimpleForm::FormBuilder
|
|
623
665
|
def input(attribute_name, options = {}, &block)
|
|
624
|
-
options
|
|
625
|
-
super
|
|
666
|
+
super(attribute_name, options.merge(label: false), &block)
|
|
626
667
|
end
|
|
627
668
|
end
|
|
628
669
|
```
|
|
629
670
|
|
|
630
671
|
## I18n
|
|
631
672
|
|
|
632
|
-
**
|
|
673
|
+
**Simple Form** uses all power of I18n API to lookup labels, hints, prompts and placeholders. To customize your
|
|
633
674
|
forms you can create a locale file like this:
|
|
634
675
|
|
|
635
676
|
```yaml
|
|
@@ -647,12 +688,18 @@ en:
|
|
|
647
688
|
user:
|
|
648
689
|
username: 'Your username'
|
|
649
690
|
password: '****'
|
|
691
|
+
include_blanks:
|
|
692
|
+
user:
|
|
693
|
+
age: 'Rather not say'
|
|
694
|
+
prompts:
|
|
695
|
+
user:
|
|
696
|
+
role: 'Select your role'
|
|
650
697
|
```
|
|
651
698
|
|
|
652
699
|
And your forms will use this information to render the components for you.
|
|
653
700
|
|
|
654
|
-
**
|
|
655
|
-
|
|
701
|
+
**Simple Form** also lets you be more specific, separating lookups through actions.
|
|
702
|
+
Let's say you want a different label for new and edit actions, the locale file would
|
|
656
703
|
be something like:
|
|
657
704
|
|
|
658
705
|
```yaml
|
|
@@ -667,7 +714,7 @@ en:
|
|
|
667
714
|
password: 'Change password'
|
|
668
715
|
```
|
|
669
716
|
|
|
670
|
-
This way **
|
|
717
|
+
This way **Simple Form** will figure out the right translation for you, based on the action being
|
|
671
718
|
rendered. And to be a little bit DRYer with your locale file, you can specify defaults for all
|
|
672
719
|
models under the 'defaults' key:
|
|
673
720
|
|
|
@@ -690,37 +737,43 @@ en:
|
|
|
690
737
|
password: '****'
|
|
691
738
|
```
|
|
692
739
|
|
|
693
|
-
**
|
|
694
|
-
specific is found inside the model key.
|
|
695
|
-
the new syntax, just move "labels.#{attribute}" to "labels.defaults.#{attribute}".
|
|
740
|
+
**Simple Form** will always look for a default attribute translation under the "defaults" key if no
|
|
741
|
+
specific is found inside the model key.
|
|
696
742
|
|
|
697
|
-
In addition, **
|
|
743
|
+
In addition, **Simple Form** will fallback to default `human_attribute_name` from Rails when no other
|
|
698
744
|
translation is found for labels. Finally, you can also overwrite any label, hint or placeholder
|
|
699
745
|
inside your view, just by passing the option manually. This way the I18n lookup will be skipped.
|
|
700
746
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
747
|
+
For `:prompt` and `:include_blank` the I18n lookup is optional and to enable it is necessary to pass
|
|
748
|
+
`:translate` as value.
|
|
749
|
+
|
|
750
|
+
```ruby
|
|
751
|
+
f.input :role, prompt: :translate
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
**Simple Form** also has support for translating options in collection helpers. For instance, given a
|
|
755
|
+
User with a `:role` attribute, you might want to create a select box showing translated labels
|
|
756
|
+
that would post either `:admin` or `:editor` as value. With **Simple Form** you could create an input
|
|
704
757
|
like this:
|
|
705
758
|
|
|
706
759
|
```ruby
|
|
707
|
-
f.input :
|
|
760
|
+
f.input :role, collection: [:admin, :editor]
|
|
708
761
|
```
|
|
709
762
|
|
|
710
|
-
And **
|
|
763
|
+
And **Simple Form** will try a lookup like this in your locale file, to find the right labels to show:
|
|
711
764
|
|
|
712
765
|
```yaml
|
|
713
766
|
en:
|
|
714
767
|
simple_form:
|
|
715
768
|
options:
|
|
716
769
|
user:
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
770
|
+
role:
|
|
771
|
+
admin: 'Administrator'
|
|
772
|
+
editor: 'Editor'
|
|
720
773
|
```
|
|
721
774
|
|
|
722
775
|
You can also use the `defaults` key as you would do with labels, hints and placeholders. It is
|
|
723
|
-
important to notice that **
|
|
776
|
+
important to notice that **Simple Form** will only do the lookup for options if you give a collection
|
|
724
777
|
composed of symbols only. This is to avoid constant lookups to I18n.
|
|
725
778
|
|
|
726
779
|
It's also possible to translate buttons, using Rails' built-in I18n support:
|
|
@@ -738,9 +791,202 @@ There are other options that can be configured through I18n API, such as require
|
|
|
738
791
|
Be sure to check our locale file or the one copied to your application after you run
|
|
739
792
|
`rails generate simple_form:install`.
|
|
740
793
|
|
|
794
|
+
It should be noted that translations for labels, hints and placeholders for a namespaced model, e.g.
|
|
795
|
+
`Admin::User`, should be placed under `admin_user`, not under `admin/user`. This is different from
|
|
796
|
+
how translations for namespaced model and attribute names are defined:
|
|
797
|
+
|
|
798
|
+
```yaml
|
|
799
|
+
en:
|
|
800
|
+
activerecord:
|
|
801
|
+
models:
|
|
802
|
+
admin/user: User
|
|
803
|
+
attributes:
|
|
804
|
+
admin/user:
|
|
805
|
+
name: Name
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
They should be placed under `admin/user`. Form labels, hints and placeholders for those attributes,
|
|
809
|
+
though, should be placed under `admin_user`:
|
|
810
|
+
|
|
811
|
+
```yaml
|
|
812
|
+
en:
|
|
813
|
+
simple_form:
|
|
814
|
+
labels:
|
|
815
|
+
admin_user:
|
|
816
|
+
name: Name
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
This difference exists because **Simple Form** relies on `object_name` provided by Rails'
|
|
820
|
+
FormBuilder to determine the translation path for a given object instead of `i18n_key` from the
|
|
821
|
+
object itself. Thus, similarly, if a form for an `Admin::User` object is defined by calling
|
|
822
|
+
`simple_form_for @admin_user, as: :some_user`, **Simple Form** will look for translations
|
|
823
|
+
under `some_user` instead of `admin_user`.
|
|
824
|
+
|
|
825
|
+
When translating `simple_fields_for` attributes be sure to use the same name you pass to it, e.g. `simple_fields_for :posts` should be placed under `posts` not `post`:
|
|
826
|
+
|
|
827
|
+
```yaml
|
|
828
|
+
en:
|
|
829
|
+
simple_form:
|
|
830
|
+
labels:
|
|
831
|
+
posts:
|
|
832
|
+
title: 'Post title'
|
|
833
|
+
hints:
|
|
834
|
+
posts:
|
|
835
|
+
title: 'A good title'
|
|
836
|
+
placeholders:
|
|
837
|
+
posts:
|
|
838
|
+
title: 'Once upon a time...'
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
## Configuration
|
|
842
|
+
|
|
843
|
+
**Simple Form** has several configuration options. You can read and change them in the initializer
|
|
844
|
+
created by **Simple Form**, so if you haven't executed the command below yet, please do:
|
|
845
|
+
|
|
846
|
+
`rails generate simple_form:install`
|
|
847
|
+
|
|
848
|
+
### The wrappers API
|
|
849
|
+
|
|
850
|
+
With **Simple Form** you can configure how your components will be rendered using the wrappers API.
|
|
851
|
+
The syntax looks like this:
|
|
852
|
+
|
|
853
|
+
```ruby
|
|
854
|
+
config.wrappers tag: :div, class: :input,
|
|
855
|
+
error_class: :field_with_errors do |b|
|
|
856
|
+
|
|
857
|
+
# Form extensions
|
|
858
|
+
b.use :html5
|
|
859
|
+
b.optional :pattern
|
|
860
|
+
b.use :maxlength
|
|
861
|
+
b.use :placeholder
|
|
862
|
+
b.use :readonly
|
|
863
|
+
|
|
864
|
+
# Form components
|
|
865
|
+
b.use :label_input
|
|
866
|
+
b.use :hint, wrap_with: { tag: :span, class: :hint }
|
|
867
|
+
b.use :error, wrap_with: { tag: :span, class: :error }
|
|
868
|
+
end
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
The _Form components_ will generate the form tags like labels, inputs, hints or errors contents.
|
|
872
|
+
The available components are:
|
|
873
|
+
|
|
874
|
+
```ruby
|
|
875
|
+
:label # The <label> tag alone
|
|
876
|
+
:input # The <input> tag alone
|
|
877
|
+
:label_input # The <label> and the <input> tags
|
|
878
|
+
:hint # The hint for the input
|
|
879
|
+
:error # The error for the input
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
The _Form extensions_ are used to generate some attributes or perform some lookups on the model to
|
|
883
|
+
add extra information to your components.
|
|
884
|
+
|
|
885
|
+
You can create new _Form components_ using the wrappers API as in the following example:
|
|
886
|
+
|
|
887
|
+
```ruby
|
|
888
|
+
config.wrappers do |b|
|
|
889
|
+
b.use :placeholder
|
|
890
|
+
b.use :label_input
|
|
891
|
+
b.wrapper tag: :div, class: 'separator' do |component|
|
|
892
|
+
component.use :hint, wrap_with: { tag: :span, class: :hint }
|
|
893
|
+
component.use :error, wrap_with: { tag: :span, class: :error }
|
|
894
|
+
end
|
|
895
|
+
end
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
this will wrap the hint and error components within a `div` tag using the class `'separator'`.
|
|
899
|
+
|
|
900
|
+
You can customize _Form components_ passing options to them:
|
|
901
|
+
|
|
902
|
+
```ruby
|
|
903
|
+
config.wrappers do |b|
|
|
904
|
+
b.use :label_input, class: 'label-input-class'
|
|
905
|
+
end
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
This you set the input and label class to `'label-input-class'`.
|
|
909
|
+
|
|
910
|
+
If you want to customize the custom _Form components_ on demand you can give it a name like this:
|
|
911
|
+
|
|
912
|
+
```ruby
|
|
913
|
+
config.wrappers do |b|
|
|
914
|
+
b.use :placeholder
|
|
915
|
+
b.use :label_input
|
|
916
|
+
b.wrapper :my_wrapper, tag: :div, class: 'separator', html: { id: 'my_wrapper_id' } do |component|
|
|
917
|
+
component.use :hint, wrap_with: { tag: :span, class: :hint }
|
|
918
|
+
component.use :error, wrap_with: { tag: :span, class: :error }
|
|
919
|
+
end
|
|
920
|
+
end
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
and now you can pass options to your `input` calls to customize the `:my_wrapper` _Form component_.
|
|
924
|
+
|
|
925
|
+
```ruby
|
|
926
|
+
# Completely turns off the custom wrapper
|
|
927
|
+
f.input :name, my_wrapper: false
|
|
928
|
+
|
|
929
|
+
# Configure the html
|
|
930
|
+
f.input :name, my_wrapper_html: { id: 'special_id' }
|
|
931
|
+
|
|
932
|
+
# Configure the tag
|
|
933
|
+
f.input :name, my_wrapper_tag: :p
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
You can also define more than one wrapper and pick one to render in a specific form or input.
|
|
937
|
+
To define another wrapper you have to give it a name, as the follow:
|
|
938
|
+
|
|
939
|
+
```ruby
|
|
940
|
+
config.wrappers :small do |b|
|
|
941
|
+
b.use :placeholder
|
|
942
|
+
b.use :label_input
|
|
943
|
+
end
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
and use it in this way:
|
|
947
|
+
|
|
948
|
+
```ruby
|
|
949
|
+
# Specifying to whole form
|
|
950
|
+
simple_form_for @user, wrapper: :small do |f|
|
|
951
|
+
f.input :name
|
|
952
|
+
end
|
|
953
|
+
|
|
954
|
+
# Specifying to one input
|
|
955
|
+
simple_form_for @user do |f|
|
|
956
|
+
f.input :name, wrapper: :small
|
|
957
|
+
end
|
|
958
|
+
```
|
|
959
|
+
|
|
960
|
+
**Simple Form** also allows you to use optional elements. For instance, let's suppose you want to use
|
|
961
|
+
hints or placeholders, but you don't want them to be generated automatically. You can set their
|
|
962
|
+
default values to `false` or use the `optional` method. Is preferable to use the `optional` syntax:
|
|
963
|
+
|
|
964
|
+
```ruby
|
|
965
|
+
config.wrappers placeholder: false do |b|
|
|
966
|
+
b.use :placeholder
|
|
967
|
+
b.use :label_input
|
|
968
|
+
b.wrapper tag: :div, class: 'separator' do |component|
|
|
969
|
+
component.optional :hint, wrap_with: { tag: :span, class: :hint }
|
|
970
|
+
component.use :error, wrap_with: { tag: :span, class: :error }
|
|
971
|
+
end
|
|
972
|
+
end
|
|
973
|
+
```
|
|
974
|
+
|
|
975
|
+
By setting it as `optional`, a hint will only be generated when `hint: true` is explicitly used.
|
|
976
|
+
The same for placeholder.
|
|
977
|
+
|
|
978
|
+
It is also possible to give the option `:unless_blank` to the wrapper if you want to render it only
|
|
979
|
+
when the content is present.
|
|
980
|
+
|
|
981
|
+
```ruby
|
|
982
|
+
b.wrapper tag: :span, class: 'hint', unless_blank: true do |component|
|
|
983
|
+
component.optional :hint
|
|
984
|
+
end
|
|
985
|
+
```
|
|
986
|
+
|
|
741
987
|
## HTML 5 Notice
|
|
742
988
|
|
|
743
|
-
By default, **
|
|
989
|
+
By default, **Simple Form** will generate input field types and attributes that are supported in HTML5,
|
|
744
990
|
but are considered invalid HTML for older document types such as HTML4 or XHTML1.0. The HTML5
|
|
745
991
|
extensions include the new field types such as email, number, search, url, tel, and the new
|
|
746
992
|
attributes such as required, autofocus, maxlength, min, max, step.
|
|
@@ -750,10 +996,25 @@ required attribute to force a value into an input and will prevent form submissi
|
|
|
750
996
|
Depending on the design of the application this may or may not be desired. In many cases it can
|
|
751
997
|
break existing UI's.
|
|
752
998
|
|
|
753
|
-
It is possible to disable all HTML 5 extensions in **
|
|
999
|
+
It is possible to disable all HTML 5 extensions in **Simple Form** by removing the `html5`
|
|
1000
|
+
component from the wrapper used to render the inputs.
|
|
1001
|
+
|
|
1002
|
+
For example, change:
|
|
1003
|
+
|
|
1004
|
+
```ruby
|
|
1005
|
+
config.wrappers tag: :div do |b|
|
|
1006
|
+
b.use :html5
|
|
1007
|
+
|
|
1008
|
+
b.use :label_input
|
|
1009
|
+
end
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
To:
|
|
754
1013
|
|
|
755
1014
|
```ruby
|
|
756
|
-
|
|
1015
|
+
config.wrappers tag: :div do |b|
|
|
1016
|
+
b.use :label_input
|
|
1017
|
+
end
|
|
757
1018
|
```
|
|
758
1019
|
|
|
759
1020
|
If you want to have all other HTML 5 features, such as the new field types, you can disable only
|
|
@@ -770,14 +1031,23 @@ help you to use some generic javascript validation.
|
|
|
770
1031
|
You can also add `novalidate` to a specific form by setting the option on the form itself:
|
|
771
1032
|
|
|
772
1033
|
```erb
|
|
773
|
-
<%= simple_form_for(resource, :
|
|
1034
|
+
<%= simple_form_for(resource, html: { novalidate: true }) do |form| %>
|
|
774
1035
|
```
|
|
775
1036
|
|
|
776
|
-
Please notice that
|
|
777
|
-
which is an HTML 5 feature. We believe most of the newest browsers are handling this attribute
|
|
778
|
-
and if they aren't, any plugin you use would take of
|
|
779
|
-
|
|
780
|
-
list in **
|
|
1037
|
+
Please notice that none of the configurations above will disable the `placeholder` component,
|
|
1038
|
+
which is an HTML 5 feature. We believe most of the newest browsers are handling this attribute
|
|
1039
|
+
just fine, and if they aren't, any plugin you use would take care of applying the placeholder.
|
|
1040
|
+
In any case, you can disable it if you really want to, by removing the placeholder component
|
|
1041
|
+
from the components list in the **Simple Form** configuration file.
|
|
1042
|
+
|
|
1043
|
+
HTML 5 date / time inputs are not generated by **Simple Form** by default, so using `date`,
|
|
1044
|
+
`time` or `datetime` will all generate select boxes using normal Rails helpers. We believe
|
|
1045
|
+
browsers are not totally ready for these yet, but you can easily opt-in on a per-input basis
|
|
1046
|
+
by passing the html5 option:
|
|
1047
|
+
|
|
1048
|
+
```erb
|
|
1049
|
+
<%= f.input :expires_at, as: :date, html5: true %>
|
|
1050
|
+
```
|
|
781
1051
|
|
|
782
1052
|
## Information
|
|
783
1053
|
|
|
@@ -790,17 +1060,14 @@ http://groups.google.com/group/plataformatec-simpleform
|
|
|
790
1060
|
|
|
791
1061
|
### RDocs
|
|
792
1062
|
|
|
793
|
-
You can view the **
|
|
1063
|
+
You can view the **Simple Form** documentation in RDoc format here:
|
|
794
1064
|
|
|
795
1065
|
http://rubydoc.info/github/plataformatec/simple_form/master/frames
|
|
796
1066
|
|
|
797
|
-
If you need to use **SimpleForm** with Rails 2.3, you can always run `gem server` from the command line
|
|
798
|
-
after you install the gem to access the old documentation.
|
|
799
|
-
|
|
800
1067
|
### Bug reports
|
|
801
1068
|
|
|
802
1069
|
If you discover any bugs, feel free to create an issue on GitHub. Please add as much information as
|
|
803
|
-
possible to help us fixing the
|
|
1070
|
+
possible to help us in fixing the potential bug. We also encourage you to help even more by forking and
|
|
804
1071
|
sending us a pull request.
|
|
805
1072
|
|
|
806
1073
|
https://github.com/plataformatec/simple_form/issues
|
|
@@ -810,7 +1077,16 @@ https://github.com/plataformatec/simple_form/issues
|
|
|
810
1077
|
* José Valim (https://github.com/josevalim)
|
|
811
1078
|
* Carlos Antonio da Silva (https://github.com/carlosantoniodasilva)
|
|
812
1079
|
* Rafael Mendonça França (https://github.com/rafaelfranca)
|
|
1080
|
+
* Vasiliy Ermolovich (https://github.com/nashby)
|
|
1081
|
+
|
|
1082
|
+
[](http://badge.fury.io/rb/simple_form)
|
|
1083
|
+
[](http://travis-ci.org/plataformatec/simple_form)
|
|
1084
|
+
[](https://codeclimate.com/github/plataformatec/simple_form)
|
|
1085
|
+
[](http://inch-ci.org/github/plataformatec/simple_form)
|
|
813
1086
|
|
|
814
1087
|
## License
|
|
815
1088
|
|
|
816
|
-
MIT License. Copyright
|
|
1089
|
+
MIT License. Copyright 2009-2018 Plataformatec. http://plataformatec.com.br
|
|
1090
|
+
|
|
1091
|
+
You are not granted rights or licenses to the trademarks of the Plataformatec, including without
|
|
1092
|
+
limitation the Simple Form name or logo.
|