simple_form 3.0.4 → 5.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +199 -33
  3. data/MIT-LICENSE +2 -1
  4. data/README.md +453 -128
  5. data/lib/generators/simple_form/install_generator.rb +4 -3
  6. data/lib/generators/simple_form/templates/README +3 -5
  7. data/lib/generators/simple_form/templates/_form.html.erb +2 -0
  8. data/lib/generators/simple_form/templates/_form.html.haml +2 -0
  9. data/lib/generators/simple_form/templates/_form.html.slim +1 -0
  10. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +47 -16
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +418 -23
  12. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +101 -5
  13. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
  14. data/lib/simple_form/action_view_extensions/builder.rb +2 -0
  15. data/lib/simple_form/action_view_extensions/form_helper.rb +10 -3
  16. data/lib/simple_form/components/errors.rb +39 -6
  17. data/lib/simple_form/components/hints.rb +3 -2
  18. data/lib/simple_form/components/html5.rb +16 -5
  19. data/lib/simple_form/components/label_input.rb +21 -2
  20. data/lib/simple_form/components/labels.rb +22 -11
  21. data/lib/simple_form/components/maxlength.rb +9 -5
  22. data/lib/simple_form/components/min_max.rb +2 -1
  23. data/lib/simple_form/components/minlength.rb +38 -0
  24. data/lib/simple_form/components/pattern.rb +2 -1
  25. data/lib/simple_form/components/placeholders.rb +4 -3
  26. data/lib/simple_form/components/readonly.rb +2 -1
  27. data/lib/simple_form/components.rb +2 -0
  28. data/lib/simple_form/error_notification.rb +1 -0
  29. data/lib/simple_form/form_builder.rb +220 -89
  30. data/lib/simple_form/helpers/autofocus.rb +1 -0
  31. data/lib/simple_form/helpers/disabled.rb +1 -0
  32. data/lib/simple_form/helpers/readonly.rb +1 -0
  33. data/lib/simple_form/helpers/required.rb +1 -0
  34. data/lib/simple_form/helpers/validators.rb +2 -1
  35. data/lib/simple_form/helpers.rb +6 -5
  36. data/lib/simple_form/i18n_cache.rb +1 -0
  37. data/lib/simple_form/inputs/base.rb +62 -16
  38. data/lib/simple_form/inputs/block_input.rb +2 -1
  39. data/lib/simple_form/inputs/boolean_input.rb +40 -16
  40. data/lib/simple_form/inputs/collection_check_boxes_input.rb +3 -2
  41. data/lib/simple_form/inputs/collection_input.rb +37 -14
  42. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +9 -13
  43. data/lib/simple_form/inputs/collection_select_input.rb +5 -2
  44. data/lib/simple_form/inputs/color_input.rb +14 -0
  45. data/lib/simple_form/inputs/date_time_input.rb +24 -9
  46. data/lib/simple_form/inputs/file_input.rb +5 -2
  47. data/lib/simple_form/inputs/grouped_collection_select_input.rb +16 -3
  48. data/lib/simple_form/inputs/hidden_input.rb +5 -2
  49. data/lib/simple_form/inputs/numeric_input.rb +6 -4
  50. data/lib/simple_form/inputs/password_input.rb +6 -3
  51. data/lib/simple_form/inputs/priority_input.rb +5 -6
  52. data/lib/simple_form/inputs/range_input.rb +2 -1
  53. data/lib/simple_form/inputs/rich_text_area_input.rb +12 -0
  54. data/lib/simple_form/inputs/string_input.rb +7 -4
  55. data/lib/simple_form/inputs/text_input.rb +6 -3
  56. data/lib/simple_form/inputs.rb +3 -0
  57. data/lib/simple_form/map_type.rb +1 -0
  58. data/lib/simple_form/railtie.rb +8 -0
  59. data/lib/simple_form/tags.rb +13 -2
  60. data/lib/simple_form/version.rb +2 -1
  61. data/lib/simple_form/wrappers/builder.rb +7 -6
  62. data/lib/simple_form/wrappers/leaf.rb +29 -0
  63. data/lib/simple_form/wrappers/many.rb +7 -6
  64. data/lib/simple_form/wrappers/root.rb +10 -3
  65. data/lib/simple_form/wrappers/single.rb +7 -4
  66. data/lib/simple_form/wrappers.rb +2 -0
  67. data/lib/simple_form.rb +137 -21
  68. data/test/action_view_extensions/builder_test.rb +64 -45
  69. data/test/action_view_extensions/form_helper_test.rb +36 -16
  70. data/test/components/custom_components_test.rb +62 -0
  71. data/test/components/label_test.rb +70 -41
  72. data/test/form_builder/association_test.rb +85 -37
  73. data/test/form_builder/button_test.rb +11 -10
  74. data/test/form_builder/error_notification_test.rb +2 -1
  75. data/test/form_builder/error_test.rb +146 -33
  76. data/test/form_builder/general_test.rb +183 -81
  77. data/test/form_builder/hint_test.rb +24 -18
  78. data/test/form_builder/input_field_test.rb +105 -75
  79. data/test/form_builder/label_test.rb +68 -13
  80. data/test/form_builder/wrapper_test.rb +197 -22
  81. data/test/generators/simple_form_generator_test.rb +8 -7
  82. data/test/inputs/boolean_input_test.rb +97 -6
  83. data/test/inputs/collection_check_boxes_input_test.rb +117 -25
  84. data/test/inputs/collection_radio_buttons_input_test.rb +176 -54
  85. data/test/inputs/collection_select_input_test.rb +189 -77
  86. data/test/inputs/color_input_test.rb +10 -0
  87. data/test/inputs/datetime_input_test.rb +121 -50
  88. data/test/inputs/disabled_test.rb +29 -15
  89. data/test/inputs/discovery_test.rb +79 -6
  90. data/test/inputs/file_input_test.rb +3 -2
  91. data/test/inputs/general_test.rb +23 -22
  92. data/test/inputs/grouped_collection_select_input_test.rb +54 -17
  93. data/test/inputs/hidden_input_test.rb +5 -4
  94. data/test/inputs/numeric_input_test.rb +48 -44
  95. data/test/inputs/priority_input_test.rb +17 -16
  96. data/test/inputs/readonly_test.rb +20 -19
  97. data/test/inputs/required_test.rb +58 -13
  98. data/test/inputs/rich_text_area_input_test.rb +15 -0
  99. data/test/inputs/string_input_test.rb +58 -36
  100. data/test/inputs/text_input_test.rb +20 -7
  101. data/test/simple_form_test.rb +9 -0
  102. data/test/support/discovery_inputs.rb +40 -2
  103. data/test/support/misc_helpers.rb +113 -5
  104. data/test/support/mock_controller.rb +7 -1
  105. data/test/support/models.rb +162 -39
  106. data/test/test_helper.rb +19 -4
  107. metadata +51 -43
data/README.md CHANGED
@@ -1,10 +1,4 @@
1
- ![Simple Form Logo](https://raw.github.com/plataformatec/simple_form/master/simple_form.png)
2
-
3
- By [Plataformatec](http://plataformatec.com.br/).
4
-
5
- [![Gem Version](https://fury-badge.herokuapp.com/rb/simple_form.png)](http://badge.fury.io/rb/simple_form)
6
- [![Build Status](https://api.travis-ci.org/plataformatec/simple_form.png?branch=master)](http://travis-ci.org/plataformatec/simple_form)
7
- [![Code Climate](https://codeclimate.com/github/plataformatec/simple_form.png)](https://codeclimate.com/github/plataformatec/simple_form)
1
+ ![Simple Form Logo](https://raw.github.com/heartcombo/simple_form/master/simple_form.png)
8
2
 
9
3
  Rails forms made easy.
10
4
 
@@ -13,8 +7,7 @@ your forms. The basic goal of **Simple Form** is to not touch your way of defini
13
7
  you find the better design for your eyes. Most of the DSL was inherited from Formtastic,
14
8
  which we are thankful for and should make you feel right at home.
15
9
 
16
- INFO: This README is [also available in a friendly navigable format](http://simple-form.plataformatec.com.br/)
17
- and refers to **Simple Form** 3.0. For older releases, check the related branch for your version.
10
+ INFO: This README refers to **Simple Form** 5.0. For older releases, check the related branch for your version.
18
11
 
19
12
  ## Installation
20
13
 
@@ -36,34 +29,25 @@ Run the generator:
36
29
  rails generate simple_form:install
37
30
  ```
38
31
 
39
- Also, if you want to use the country select, you will need the
40
- [country_select gem](https://rubygems.org/gems/country_select), add it to your Gemfile:
41
-
42
- ```ruby
43
- gem 'country_select'
44
- ```
45
-
46
- ### Twitter Bootstrap
32
+ ### Bootstrap
47
33
 
48
- **Simple Form** can be easily integrated to the [Twitter Bootstrap](http://twitter.github.com/bootstrap).
34
+ **Simple Form** can be easily integrated to the [Bootstrap](http://getbootstrap.com/).
49
35
  To do that you have to use the `bootstrap` option in the install generator, like this:
50
36
 
51
37
  ```console
52
38
  rails generate simple_form:install --bootstrap
53
39
  ```
54
40
 
55
- You have to be sure that you added a copy of the [Twitter Bootstrap](http://twitter.github.com/bootstrap)
41
+ You have to be sure that you added a copy of the [Bootstrap](http://getbootstrap.com/)
56
42
  assets on your application.
57
43
 
58
44
  For more information see the generator output, our
59
45
  [example application code](https://github.com/rafaelfranca/simple_form-bootstrap) and
60
46
  [the live example app](http://simple-form-bootstrap.plataformatec.com.br/).
61
47
 
62
- **NOTE**: **Simple Form** integration requires Twitter Bootstrap version 2.0 or higher.
48
+ ### Zurb Foundation 5
63
49
 
64
- ### Zurb Foundation 3
65
-
66
- To generate wrappers that are compatible with [Zurb Foundation 3](http://foundation.zurb.com/), pass
50
+ To generate wrappers that are compatible with [Zurb Foundation 5](http://foundation.zurb.com/), pass
67
51
  the `foundation` option to the generator, like this:
68
52
 
69
53
  ```console
@@ -74,14 +58,30 @@ Please note that the Foundation wrapper does not support the `:hint` option by d
74
58
  enable hints, please uncomment the appropriate line in `config/initializers/simple_form_foundation.rb`.
75
59
  You will need to provide your own CSS styles for hints.
76
60
 
77
- Please see the [instructions on how to install Foundation in a Rails app](http://foundation.zurb.com/old-docs/f3/rails.php).
61
+ Please see the [instructions on how to install Foundation in a Rails app](http://foundation.zurb.com/docs/applications.html).
62
+
63
+ ### Country Select
64
+
65
+ If you want to use the country select, you will need the
66
+ [country_select gem](https://rubygems.org/gems/country_select), add it to your Gemfile:
67
+
68
+ ```ruby
69
+ gem 'country_select'
70
+ ```
71
+
72
+ If you don't want to use the gem you can easily override this behaviour by mapping the
73
+ country inputs to something else, with a line like this in your `simple_form.rb` initializer:
74
+
75
+ ```ruby
76
+ config.input_mappings = { /country/ => :string }
77
+ ```
78
78
 
79
79
  ## Usage
80
80
 
81
81
  **Simple Form** was designed to be customized as you need to. Basically it's a stack of components that
82
82
  are invoked to create a complete html input for you, which by default contains label, hints, errors
83
83
  and the input itself. It does not aim to create a lot of different logic from the default Rails
84
- form helpers, as they do a great work by themselves. Instead, **Simple Form** acts as a DSL and just
84
+ form helpers, as they do a great job by themselves. Instead, **Simple Form** acts as a DSL and just
85
85
  maps your input type (retrieved from the column definition in the database) to a specific helper method.
86
86
 
87
87
  To start using **Simple Form** you just have to use the helper it provides:
@@ -97,12 +97,12 @@ To start using **Simple Form** you just have to use the helper it provides:
97
97
  This will generate an entire form with labels for user name and password as well, and render errors
98
98
  by default when you render the form with invalid data (after submitting for example).
99
99
 
100
- You can overwrite the default label by passing it to the input method. You can also add a hint or
101
- even a placeholder. For boolean inputs, you can add an inline label as well:
100
+ You can overwrite the default label by passing it to the input method. You can also add a hint,
101
+ an error, or even a placeholder. For boolean inputs, you can add an inline label as well:
102
102
 
103
103
  ```erb
104
104
  <%= simple_form_for @user do |f| %>
105
- <%= f.input :username, label: 'Your username please' %>
105
+ <%= f.input :username, label: 'Your username please', error: 'Username is mandatory, please specify one' %>
106
106
  <%= f.input :password, hint: 'No special characters.' %>
107
107
  <%= f.input :email, placeholder: 'user@domain.com' %>
108
108
  <%= f.input :remember_me, inline_label: 'Yes, remember me' %>
@@ -110,12 +110,12 @@ even a placeholder. For boolean inputs, you can add an inline label as well:
110
110
  <% end %>
111
111
  ```
112
112
 
113
- In some cases you may want to disable labels, hints or error. Or you may want to configure the html
113
+ In some cases you may want to disable labels, hints or errors. Or you may want to configure the html
114
114
  of any of them:
115
115
 
116
116
  ```erb
117
117
  <%= simple_form_for @user do |f| %>
118
- <%= f.input :username, label_html: { class: 'my_class' } %>
118
+ <%= f.input :username, label_html: { class: 'my_class' }, hint_html: { class: 'hint_class' } %>
119
119
  <%= f.input :password, hint: false, error_html: { id: 'password_error'} %>
120
120
  <%= f.input :password_confirmation, label: false %>
121
121
  <%= f.button :submit %>
@@ -161,8 +161,9 @@ any html attribute to that wrapper as well using the `:wrapper_html` option, lik
161
161
 
162
162
  Required fields are marked with an * prepended to their labels.
163
163
 
164
- By default all inputs are required. When the form object has `presence` validations attached to its
165
- fields, **Simple Form** tells required and optional fields apart. For performance reasons, this
164
+ By default all inputs are required. When the form object includes `ActiveModel::Validations`
165
+ (which, for example, happens with Active Record models), fields are required only when there is `presence` validation.
166
+ Otherwise, **Simple Form** will mark fields as optional. For performance reasons, this
166
167
  detection is skipped on validations that make use of conditional options, such as `:if` and `:unless`.
167
168
 
168
169
  And of course, the `required` property of any input can be overwritten as needed:
@@ -176,6 +177,13 @@ And of course, the `required` property of any input can be overwritten as needed
176
177
  <% end %>
177
178
  ```
178
179
 
180
+ By default, **Simple Form** will look at the column type in the database and use an
181
+ appropriate input for the column. For example, a column created with type
182
+ `:text` in the database will use a `textarea` input by default. See the section
183
+ [Available input types and defaults for each column
184
+ type](https://github.com/heartcombo/simple_form#available-input-types-and-defaults-for-each-column-type)
185
+ for a complete list of defaults.
186
+
179
187
  **Simple Form** also lets you overwrite the default input type it creates:
180
188
 
181
189
  ```erb
@@ -189,11 +197,11 @@ And of course, the `required` property of any input can be overwritten as needed
189
197
  ```
190
198
 
191
199
  So instead of a checkbox for the *accepts* attribute, you'll have a pair of radio buttons with yes/no
192
- labels and a text area instead of a text field for the description. You can also render boolean
200
+ labels and a textarea instead of a text field for the description. You can also render boolean
193
201
  attributes using `as: :select` to show a dropdown.
194
202
 
195
203
  It is also possible to give the `:disabled` option to **Simple Form**, and it'll automatically mark
196
- the wrapper as disabled with a css class, so you can style labels, hints and other components inside
204
+ the wrapper as disabled with a CSS class, so you can style labels, hints and other components inside
197
205
  the wrapper as well:
198
206
 
199
207
  ```erb
@@ -203,13 +211,14 @@ the wrapper as well:
203
211
  <% end %>
204
212
  ```
205
213
 
206
- **Simple Form** accepts same options as their corresponding input type helper in Rails:
214
+ **Simple Form** inputs accept the same options as their corresponding input type helper in Rails:
207
215
 
208
216
  ```erb
209
217
  <%= simple_form_for @user do |f| %>
210
218
  <%= f.input :date_of_birth, as: :date, start_year: Date.today.year - 90,
211
219
  end_year: Date.today.year - 12, discard_day: true,
212
220
  order: [:month, :year] %>
221
+ <%= f.input :accepts, as: :boolean, checked_value: true, unchecked_value: false %>
213
222
  <%= f.button :submit %>
214
223
  <% end %>
215
224
  ```
@@ -241,17 +250,42 @@ Example:
241
250
  ```ruby
242
251
  simple_form_for @user do |f|
243
252
  f.input_field :name
253
+ f.input_field :remember_me, as: :boolean
244
254
  end
245
255
  ```
246
256
 
247
- Produces:
257
+ ```html
258
+ <form>
259
+ ...
260
+ <input class="string required" id="user_name" maxlength="255" name="user[name]" size="255" type="text">
261
+ <input name="user[remember_me]" type="hidden" value="0">
262
+ <label class="checkbox">
263
+ <input class="boolean optional" id="user_published" name="user[remember_me]" type="checkbox" value="1">
264
+ </label>
265
+ </form>
266
+ ```
267
+
268
+ For check boxes and radio buttons you can remove the label changing `boolean_style` from default value `:nested` to `:inline`.
269
+
270
+ Example:
271
+
272
+ ```ruby
273
+ simple_form_for @user do |f|
274
+ f.input_field :name
275
+ f.input_field :remember_me, as: :boolean, boolean_style: :inline
276
+ end
277
+ ```
248
278
 
249
279
  ```html
250
- <input class="string required" id="user_name" maxlength="100"
251
- name="user[name]" size="100" type="text" value="Carlos" />
280
+ <form>
281
+ ...
282
+ <input class="string required" id="user_name" maxlength="255" name="user[name]" size="255" type="text">
283
+ <input name="user[remember_me]" type="hidden" value="0">
284
+ <input class="boolean optional" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1">
285
+ </form>
252
286
  ```
253
287
 
254
- To view the actual RDocs for this, check them out here - http://rubydoc.info/github/plataformatec/simple_form/master/SimpleForm/FormBuilder:input_field
288
+ To view the actual RDocs for this, check them out here - http://rubydoc.info/github/heartcombo/simple_form/master/SimpleForm/FormBuilder:input_field
255
289
 
256
290
  ### Collections
257
291
 
@@ -269,23 +303,37 @@ overriding the `:collection` option:
269
303
  Collections can be arrays or ranges, and when a `:collection` is given the `:select` input will be
270
304
  rendered by default, so we don't need to pass the `as: :select` option. Other types of collection
271
305
  are `:radio_buttons` and `:check_boxes`. Those are added by **Simple Form** to Rails set of form
272
- helpers (read Extra Helpers session below for more information).
306
+ helpers (read Extra Helpers section below for more information).
273
307
 
274
308
  Collection inputs accept two other options beside collections:
275
309
 
276
- * _label_method_ => the label method to be applied to the collection to retrieve the label (use this
310
+ * *label_method* => the label method to be applied to the collection to retrieve the label (use this
277
311
  instead of the `text_method` option in `collection_select`)
278
312
 
279
- * _value_method_ => the value method to be applied to the collection to retrieve the value
313
+ * *value_method* => the value method to be applied to the collection to retrieve the value
280
314
 
281
315
  Those methods are useful to manipulate the given collection. Both of these options also accept
282
316
  lambda/procs in case you want to calculate the value or label in a special way eg. custom
283
- translation. All other options given are sent straight to the underlying helper. For example, you
284
- can give prompt as:
317
+ translation. You can also define a `to_label` method on your model as **Simple Form** will search for
318
+ and use `:to_label` as a `:label_method` first if it is found.
319
+
320
+ By default, **Simple Form** will use the first item from an array as the label and the second one as the value.
321
+ If you want to change this behavior you must make it explicit, like this:
322
+
323
+ ```erb
324
+ <%= simple_form_for @user do |f| %>
325
+ <%= f.input :gender, as: :radio_buttons, collection: [['0', 'female'], ['1', 'male']], label_method: :second, value_method: :first %>
326
+ <% end %>
327
+ ```
328
+
329
+ All other options given are sent straight to the underlying helper. For example, you can give prompt as:
285
330
 
286
331
  ```ruby
287
- f.input :age, collection: 18..60, prompt: "Select your age"
332
+ f.input :age, collection: 18..60, prompt: "Select your age", selected: 21
288
333
  ```
334
+ Extra options are passed into helper [`collection_select`](http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select).
335
+
336
+ You may also find it useful to explicitly pass a value to the optional `:selected`, especially if passing a collection of nested objects.
289
337
 
290
338
  It is also possible to create grouped collection selects, that will use the html *optgroup* tags, like this:
291
339
 
@@ -296,24 +344,24 @@ f.input :country_id, collection: @continents, as: :grouped_select, group_method:
296
344
  Grouped collection inputs accept the same `:label_method` and `:value_method` options, which will be
297
345
  used to retrieve label/value attributes for the `option` tags. Besides that, you can give:
298
346
 
299
- * _group_method_ => the method to be called on the given collection to generate the options for
347
+ * *group_method* => the method to be called on the given collection to generate the options for
300
348
  each group (required)
301
349
 
302
- * _group_label_method_ => the label method to be applied on the given collection to retrieve the label
350
+ * *group_label_method* => the label method to be applied on the given collection to retrieve the label
303
351
  for the _optgroup_ (**Simple Form** will attempt to guess the best one the same way it does with
304
352
  `:label_method`)
305
353
 
306
354
  ### Priority
307
355
 
308
356
  **Simple Form** also supports `:time_zone` and `:country`. When using such helpers, you can give
309
- `:priority` as option to select which time zones and/or countries should be given higher priority:
357
+ `:priority` as an option to select which time zones and/or countries should be given higher priority:
310
358
 
311
359
  ```ruby
312
360
  f.input :residence_country, priority: [ "Brazil" ]
313
361
  f.input :time_zone, priority: /US/
314
362
  ```
315
363
 
316
- Those values can also be configured with a default value to be used site use through the
364
+ Those values can also be configured with a default value to be used on the site through the
317
365
  `SimpleForm.country_priority` and `SimpleForm.time_zone_priority` helpers.
318
366
 
319
367
  Note: While using `country_select` if you want to restrict to only a subset of countries for a specific
@@ -325,8 +373,8 @@ f.input :shipping_country, priority: [ "Brazil" ], collection: [ "Australia", "B
325
373
 
326
374
  ### Associations
327
375
 
328
- To deal with associations, **Simple Form** can generate select inputs, a series of radios buttons or check boxes.
329
- Lets see how it works: imagine you have a user model that belongs to a company and has_and_belongs_to_many
376
+ To deal with associations, **Simple Form** can generate select inputs, a series of radios buttons or checkboxes.
377
+ Lets see how it works: imagine you have a user model that belongs to a company and `has_and_belongs_to_many`
330
378
  roles. The structure would be something like:
331
379
 
332
380
  ```ruby
@@ -357,7 +405,7 @@ Now we have the user form:
357
405
 
358
406
  Simple enough, right? This is going to render a `:select` input for choosing the `:company`, and another
359
407
  `:select` input with `:multiple` option for the `:roles`. You can, of course, change it to use radio
360
- buttons and check boxes as well:
408
+ buttons and checkboxes as well:
361
409
 
362
410
  ```ruby
363
411
  f.association :company, as: :radio_buttons
@@ -369,7 +417,7 @@ The association helper just invokes `input` under the hood, so all options avail
369
417
  the collection by hand, all together with the prompt:
370
418
 
371
419
  ```ruby
372
- f.association :company, collection: Company.active.all(order: 'name'), prompt: "Choose a Company"
420
+ f.association :company, collection: Company.active.order(:name), prompt: "Choose a Company"
373
421
  ```
374
422
 
375
423
  In case you want to declare different labels and values:
@@ -394,6 +442,22 @@ All web forms need buttons, right? **Simple Form** wraps them in the DSL, acting
394
442
 
395
443
  The above will simply call submit. You choose to use it or not, it's just a question of taste.
396
444
 
445
+ The button method also accepts optional parameters, that are delegated to the underlying submit call:
446
+
447
+ ```erb
448
+ <%= f.button :submit, "Custom Button Text", class: "my-button" %>
449
+ ```
450
+
451
+ To create a `<button>` element, use the following syntax:
452
+
453
+ ```erb
454
+ <%= f.button :button, "Custom Button Text" %>
455
+
456
+ <%= f.button :button do %>
457
+ Custom Button Text
458
+ <% end %>
459
+ ```
460
+
397
461
  ### Wrapping Rails Form Helpers
398
462
 
399
463
  Say you wanted to use a rails form helper but still wrap it in **Simple Form** goodness? You can, by
@@ -433,7 +497,7 @@ Creates a collection of radio inputs with labels associated (same API as `collec
433
497
 
434
498
  ```ruby
435
499
  form_for @user do |f|
436
- f.collection_radio_buttons :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
500
+ f.collection_radio_buttons :options, [[true, 'Yes'], [false, 'No']], :first, :last
437
501
  end
438
502
  ```
439
503
 
@@ -446,11 +510,11 @@ end
446
510
 
447
511
  #### Collection Check Boxes
448
512
 
449
- Creates a collection of check boxes with labels associated (same API as `collection_select`):
513
+ Creates a collection of checkboxes with labels associated (same API as `collection_select`):
450
514
 
451
515
  ```ruby
452
516
  form_for @user do |f|
453
- f.collection_check_boxes :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
517
+ f.collection_check_boxes :options, [[true, 'Yes'], [false, 'No']], :first, :last
454
518
  end
455
519
  ```
456
520
 
@@ -471,37 +535,49 @@ form_for @user do |f|
471
535
  end
472
536
  ```
473
537
 
474
- ## Mappings/Inputs available
475
-
476
- **Simple Form** comes with a lot of default mappings:
477
-
478
- ```text
479
- Mapping Input Column Type
480
-
481
- boolean check box boolean
482
- string text field string
483
- email email field string with name matching "email"
484
- url url field string with name matching "url"
485
- tel tel field string with name matching "phone"
486
- password password field string with name matching "password"
487
- search search -
488
- text text area text
489
- file file field string, responding to file methods
490
- hidden hidden field -
491
- integer number field integer
492
- float number field float
493
- decimal number field decimal
494
- range range field -
495
- datetime datetime select datetime/timestamp
496
- date date select date
497
- time time select time
498
- select collection select belongs_to/has_many/has_and_belongs_to_many associations
499
- radio_buttons collection radio buttons belongs_to
500
- check_boxes collection check boxes has_many/has_and_belongs_to_many associations
501
- country country select string with name matching "country"
502
- time_zone time zone select string with name matching "time_zone"
538
+ To add a CSS class to the label item, you can use the `item_label_class` option:
539
+
540
+ ```ruby
541
+ f.collection_check_boxes :role_ids, Role.all, :id, :name, item_label_class: 'my-custom-class'
503
542
  ```
504
543
 
544
+ ## Available input types and defaults for each column type
545
+
546
+ The following table shows the html element you will get for each attribute
547
+ according to its database definition. These defaults can be changed by
548
+ specifying the helper method in the column `Mapping` as the `as:` option.
549
+
550
+ Mapping | Generated HTML Element | Database Column Type
551
+ --------------- |--------------------------------------|---------------------
552
+ `boolean` | `input[type=checkbox]` | `boolean`
553
+ `string` | `input[type=text]` | `string`
554
+ `citext` | `input[type=text]` | `citext`
555
+ `email` | `input[type=email]` | `string` with `name =~ /email/`
556
+ `url` | `input[type=url]` | `string` with `name =~ /url/`
557
+ `tel` | `input[type=tel]` | `string` with `name =~ /phone/`
558
+ `password` | `input[type=password]` | `string` with `name =~ /password/`
559
+ `search` | `input[type=search]` | -
560
+ `uuid` | `input[type=text]` | `uuid`
561
+ `color` | `input[type=color]` | `string`
562
+ `text` | `textarea` | `text`
563
+ `hstore` | `textarea` | `hstore`
564
+ `json` | `textarea` | `json`
565
+ `jsonb` | `textarea` | `jsonb`
566
+ `file` | `input[type=file]` | `string` responding to file methods
567
+ `hidden` | `input[type=hidden]` | -
568
+ `integer` | `input[type=number]` | `integer`
569
+ `float` | `input[type=number]` | `float`
570
+ `decimal` | `input[type=number]` | `decimal`
571
+ `range` | `input[type=range]` | -
572
+ `datetime` | `datetime select` | `datetime/timestamp`
573
+ `date` | `date select` | `date`
574
+ `time` | `time select` | `time`
575
+ `select` | `select` | `belongs_to`/`has_many`/`has_and_belongs_to_many` associations
576
+ `radio_buttons` | collection of `input[type=radio]` | `belongs_to` associations
577
+ `check_boxes` | collection of `input[type=checkbox]` | `has_many`/`has_and_belongs_to_many` associations
578
+ `country` | `select` (countries as options) | `string` with `name =~ /country/`
579
+ `time_zone` | `select` (timezones as options) | `string` with `name =~ /time_zone/`
580
+
505
581
  ## Custom inputs
506
582
 
507
583
  It is very easy to add custom inputs to **Simple Form**. For instance, if you want to add a custom input
@@ -510,8 +586,10 @@ that extends the string one, you just need to add this file:
510
586
  ```ruby
511
587
  # app/inputs/currency_input.rb
512
588
  class CurrencyInput < SimpleForm::Inputs::Base
513
- def input
514
- "$ #{@builder.text_field(attribute_name, input_html_options)}".html_safe
589
+ def input(wrapper_options)
590
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
591
+
592
+ "$ #{@builder.text_field(attribute_name, merged_input_options)}".html_safe
515
593
  end
516
594
  end
517
595
  ```
@@ -521,6 +599,7 @@ And use it in your views:
521
599
  ```ruby
522
600
  f.input :money, as: :currency
523
601
  ```
602
+ Note, you may have to create the `app/inputs/` directory and restart your webserver.
524
603
 
525
604
  You can also redefine existing **Simple Form** inputs by creating a new class with the same name. For
526
605
  instance, if you want to wrap date/time/datetime in a div, you can do:
@@ -528,7 +607,7 @@ instance, if you want to wrap date/time/datetime in a div, you can do:
528
607
  ```ruby
529
608
  # app/inputs/date_time_input.rb
530
609
  class DateTimeInput < SimpleForm::Inputs::DateTimeInput
531
- def input
610
+ def input(wrapper_options)
532
611
  template.content_tag(:div, super)
533
612
  end
534
613
  end
@@ -545,6 +624,28 @@ class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
545
624
  end
546
625
  ```
547
626
 
627
+ If needed, you can namespace your custom inputs in a module and tell **Simple Form** to look for
628
+ their definitions in this module. This can avoid conflicts with other form libraries (like Formtastic) that look up
629
+ the global context to find inputs definition too.
630
+
631
+ ```ruby
632
+ # app/inputs/custom_inputs/numeric_input
633
+ module CustomInputs
634
+ class NumericInput < SimpleForm::Inputs::NumericInput
635
+ def input_html_classes
636
+ super.push('no-spinner')
637
+ end
638
+ end
639
+ end
640
+ ```
641
+
642
+ And in the **SimpleForm** initializer :
643
+
644
+ ```ruby
645
+ # config/simple_form.rb
646
+ config.custom_inputs_namespaces << "CustomInputs"
647
+ ```
648
+
548
649
  ## Custom form builder
549
650
 
550
651
  You can create a custom form builder that uses **Simple Form**.
@@ -563,15 +664,14 @@ Create a form builder class that inherits from `SimpleForm::FormBuilder`.
563
664
  ```ruby
564
665
  class CustomFormBuilder < SimpleForm::FormBuilder
565
666
  def input(attribute_name, options = {}, &block)
566
- options[:input_html].merge! class: 'custom'
567
- super
667
+ super(attribute_name, options.merge(label: false), &block)
568
668
  end
569
669
  end
570
670
  ```
571
671
 
572
672
  ## I18n
573
673
 
574
- **Simple Form** uses all power of I18n API to lookup labels, hints and placeholders. To customize your
674
+ **Simple Form** uses all power of I18n API to lookup labels, hints, prompts and placeholders. To customize your
575
675
  forms you can create a locale file like this:
576
676
 
577
677
  ```yaml
@@ -589,12 +689,18 @@ en:
589
689
  user:
590
690
  username: 'Your username'
591
691
  password: '****'
692
+ include_blanks:
693
+ user:
694
+ age: 'Rather not say'
695
+ prompts:
696
+ user:
697
+ role: 'Select your role'
592
698
  ```
593
699
 
594
700
  And your forms will use this information to render the components for you.
595
701
 
596
- **Simple Form** also lets you be more specific, separating lookups through actions for labels, hints and
597
- placeholders. Let's say you want a different label for new and edit actions, the locale file would
702
+ **Simple Form** also lets you be more specific, separating lookups through actions.
703
+ Let's say you want a different label for new and edit actions, the locale file would
598
704
  be something like:
599
705
 
600
706
  ```yaml
@@ -633,20 +739,26 @@ en:
633
739
  ```
634
740
 
635
741
  **Simple Form** will always look for a default attribute translation under the "defaults" key if no
636
- specific is found inside the model key. Note that this syntax is different from 1.x. To migrate to
637
- the new syntax, just move "labels.#{attribute}" to "labels.defaults.#{attribute}".
742
+ specific is found inside the model key.
638
743
 
639
- In addition, **Simple Form** will fallback to default human_attribute_name from Rails when no other
744
+ In addition, **Simple Form** will fallback to default `human_attribute_name` from Rails when no other
640
745
  translation is found for labels. Finally, you can also overwrite any label, hint or placeholder
641
746
  inside your view, just by passing the option manually. This way the I18n lookup will be skipped.
642
747
 
748
+ For `:prompt` and `:include_blank` the I18n lookup is optional and to enable it is necessary to pass
749
+ `:translate` as value.
750
+
751
+ ```ruby
752
+ f.input :role, prompt: :translate
753
+ ```
754
+
643
755
  **Simple Form** also has support for translating options in collection helpers. For instance, given a
644
- User with a `:gender` attribute, you might want to create a select box showing translated labels
645
- that would post either `male` or `female` as value. With **Simple Form** you could create an input
756
+ User with a `:role` attribute, you might want to create a select box showing translated labels
757
+ that would post either `:admin` or `:editor` as value. With **Simple Form** you could create an input
646
758
  like this:
647
759
 
648
760
  ```ruby
649
- f.input :gender, collection: [:male, :female]
761
+ f.input :role, collection: [:admin, :editor]
650
762
  ```
651
763
 
652
764
  And **Simple Form** will try a lookup like this in your locale file, to find the right labels to show:
@@ -656,9 +768,9 @@ en:
656
768
  simple_form:
657
769
  options:
658
770
  user:
659
- gender:
660
- male: 'Male'
661
- female: 'Female'
771
+ role:
772
+ admin: 'Administrator'
773
+ editor: 'Editor'
662
774
  ```
663
775
 
664
776
  You can also use the `defaults` key as you would do with labels, hints and placeholders. It is
@@ -711,6 +823,22 @@ object itself. Thus, similarly, if a form for an `Admin::User` object is defined
711
823
  `simple_form_for @admin_user, as: :some_user`, **Simple Form** will look for translations
712
824
  under `some_user` instead of `admin_user`.
713
825
 
826
+ 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`:
827
+
828
+ ```yaml
829
+ en:
830
+ simple_form:
831
+ labels:
832
+ posts:
833
+ title: 'Post title'
834
+ hints:
835
+ posts:
836
+ title: 'A good title'
837
+ placeholders:
838
+ posts:
839
+ title: 'Once upon a time...'
840
+ ```
841
+
714
842
  ## Configuration
715
843
 
716
844
  **Simple Form** has several configuration options. You can read and change them in the initializer
@@ -725,7 +853,8 @@ The syntax looks like this:
725
853
 
726
854
  ```ruby
727
855
  config.wrappers tag: :div, class: :input,
728
- error_class: :field_with_errors do |b|
856
+ error_class: :field_with_errors,
857
+ valid_class: :field_without_errors do |b|
729
858
 
730
859
  # Form extensions
731
860
  b.use :html5
@@ -770,13 +899,24 @@ end
770
899
 
771
900
  this will wrap the hint and error components within a `div` tag using the class `'separator'`.
772
901
 
902
+ You can customize _Form components_ passing options to them:
903
+
904
+ ```ruby
905
+ config.wrappers do |b|
906
+ b.use :label_input, class: 'label-input-class', error_class: 'is-invalid', valid_class: 'is-valid'
907
+ end
908
+ ```
909
+
910
+ This sets the input and label classes to `'label-input-class'` and will set the class `'is-invalid'`
911
+ if the input has errors and `'is-valid'` if the input is valid.
912
+
773
913
  If you want to customize the custom _Form components_ on demand you can give it a name like this:
774
914
 
775
915
  ```ruby
776
916
  config.wrappers do |b|
777
917
  b.use :placeholder
778
918
  b.use :label_input
779
- b.wrapper :my_wrapper, tag: :div, class: 'separator' do |component|
919
+ b.wrapper :my_wrapper, tag: :div, class: 'separator', html: { id: 'my_wrapper_id' } do |component|
780
920
  component.use :hint, wrap_with: { tag: :span, class: :hint }
781
921
  component.use :error, wrap_with: { tag: :span, class: :error }
782
922
  end
@@ -838,6 +978,101 @@ end
838
978
  By setting it as `optional`, a hint will only be generated when `hint: true` is explicitly used.
839
979
  The same for placeholder.
840
980
 
981
+ It is also possible to give the option `:unless_blank` to the wrapper if you want to render it only
982
+ when the content is present.
983
+
984
+ ```ruby
985
+ b.wrapper tag: :span, class: 'hint', unless_blank: true do |component|
986
+ component.optional :hint
987
+ end
988
+ ```
989
+
990
+ ## Custom Components
991
+
992
+ When you use custom wrappers, you might also be looking for a way to add custom components to your
993
+ wrapper. The default components are:
994
+
995
+ ```ruby
996
+ :label # The <label> tag alone
997
+ :input # The <input> tag alone
998
+ :label_input # The <label> and the <input> tags
999
+ :hint # The hint for the input
1000
+ :error # The error for the input
1001
+ ```
1002
+
1003
+ A custom component might be interesting for you if your views look something like this:
1004
+
1005
+ ```erb
1006
+ <%= simple_form_for @blog do |f| %>
1007
+ <div class="row">
1008
+ <div class="span1 number">
1009
+ 1
1010
+ </div>
1011
+ <div class="span8">
1012
+ <%= f.input :title %>
1013
+ </div>
1014
+ </div>
1015
+ <div class="row">
1016
+ <div class="span1 number">
1017
+ 2
1018
+ </div>
1019
+ <div class="span8">
1020
+ <%= f.input :body, as: :text %>
1021
+ </div>
1022
+ </div>
1023
+ <% end %>
1024
+ ```
1025
+
1026
+ A cleaner method to create your views would be:
1027
+
1028
+ ```erb
1029
+ <%= simple_form_for @blog, wrapper: :with_numbers do |f| %>
1030
+ <%= f.input :title, number: 1 %>
1031
+ <%= f.input :body, as: :text, number: 2 %>
1032
+ <% end %>
1033
+ ```
1034
+
1035
+ To use the number option on the input, first, tells to Simple Form the place where the components
1036
+ will be:
1037
+
1038
+ ``` ruby
1039
+ # config/initializers/simple_form.rb
1040
+ Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
1041
+ ```
1042
+
1043
+ Create a new component within the path specified above:
1044
+
1045
+ ```ruby
1046
+ # lib/components/numbers_component.rb
1047
+ module NumbersComponent
1048
+ # To avoid deprecation warning, you need to make the wrapper_options explicit
1049
+ # even when they won't be used.
1050
+ def number(wrapper_options = nil)
1051
+ @number ||= begin
1052
+ options[:number].to_s.html_safe if options[:number].present?
1053
+ end
1054
+ end
1055
+ end
1056
+
1057
+ SimpleForm.include_component(NumbersComponent)
1058
+ ```
1059
+
1060
+ Finally, add a new wrapper to the config/initializers/simple_form.rb file:
1061
+
1062
+ ```ruby
1063
+ config.wrappers :with_numbers, tag: 'div', class: 'row', error_class: 'error' do |b|
1064
+ b.use :html5
1065
+ b.use :number, wrap_with: { tag: 'div', class: 'span1 number'}
1066
+ b.wrapper tag: 'div', class: 'span8' do |ba|
1067
+ ba.use :placeholder
1068
+ ba.use :label
1069
+ ba.use :input
1070
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-inline' }
1071
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
1072
+ end
1073
+ end
1074
+ ```
1075
+
841
1076
  ## HTML 5 Notice
842
1077
 
843
1078
  By default, **Simple Form** will generate input field types and attributes that are supported in HTML5,
@@ -850,10 +1085,25 @@ required attribute to force a value into an input and will prevent form submissi
850
1085
  Depending on the design of the application this may or may not be desired. In many cases it can
851
1086
  break existing UI's.
852
1087
 
853
- It is possible to disable all HTML 5 extensions in **Simple Form** with the following configuration:
1088
+ It is possible to disable all HTML 5 extensions in **Simple Form** by removing the `html5`
1089
+ component from the wrapper used to render the inputs.
1090
+
1091
+ For example, change:
854
1092
 
855
1093
  ```ruby
856
- SimpleForm.html5 = false # default is true
1094
+ config.wrappers tag: :div do |b|
1095
+ b.use :html5
1096
+
1097
+ b.use :label_input
1098
+ end
1099
+ ```
1100
+
1101
+ To:
1102
+
1103
+ ```ruby
1104
+ config.wrappers tag: :div do |b|
1105
+ b.use :label_input
1106
+ end
857
1107
  ```
858
1108
 
859
1109
  If you want to have all other HTML 5 features, such as the new field types, you can disable only
@@ -870,51 +1120,126 @@ help you to use some generic javascript validation.
870
1120
  You can also add `novalidate` to a specific form by setting the option on the form itself:
871
1121
 
872
1122
  ```erb
873
- <%= simple_form_for(resource, html: {novalidate: true}) do |form| %>
1123
+ <%= simple_form_for(resource, html: { novalidate: true }) do |form| %>
874
1124
  ```
875
1125
 
876
- Please notice that any of the configurations above will not disable the `placeholder` component,
877
- which is an HTML 5 feature. We believe most of the newest browsers are handling this attribute fine,
878
- and if they aren't, any plugin you use would take of using the placeholder attribute to do it.
879
- However, you can disable it if you want, by removing the placeholder component from the components
880
- list in **Simple Form** configuration file.
1126
+ Please notice that none of the configurations above will disable the `placeholder` component,
1127
+ which is an HTML 5 feature. We believe most of the newest browsers are handling this attribute
1128
+ just fine, and if they aren't, any plugin you use would take care of applying the placeholder.
1129
+ In any case, you can disable it if you really want to, by removing the placeholder component
1130
+ from the components list in the **Simple Form** configuration file.
881
1131
 
882
- ## Information
1132
+ HTML 5 date / time inputs are not generated by **Simple Form** by default, so using `date`,
1133
+ `time` or `datetime` will all generate select boxes using normal Rails helpers. We believe
1134
+ browsers are not totally ready for these yet, but you can easily opt-in on a per-input basis
1135
+ by passing the html5 option:
1136
+
1137
+ ```erb
1138
+ <%= f.input :expires_at, as: :date, html5: true %>
1139
+ ```
1140
+
1141
+ ### Using non Active Record objects
1142
+
1143
+ There are few ways to build forms with objects that don't inherit from Active Record, as
1144
+ follows:
1145
+
1146
+ You can include the module `ActiveModel::Model`.
1147
+
1148
+ ```ruby
1149
+ class User
1150
+ include ActiveModel::Model
1151
+
1152
+ attr_accessor :id, :name
1153
+ end
1154
+ ```
1155
+
1156
+ If you are using Presenters or Decorators that inherit from `SimpleDelegator` you can delegate
1157
+ it to the model.
1158
+
1159
+ ```ruby
1160
+ class UserPresenter < SimpleDelegator
1161
+ # Without that, Simple Form will consider the user model as the object.
1162
+ def to_model
1163
+ self
1164
+ end
1165
+ end
1166
+ ```
1167
+
1168
+ You can define all methods required by the helpers.
1169
+
1170
+ ```ruby
1171
+ class User
1172
+ extend ActiveModel::Naming
1173
+
1174
+ attr_accessor :id, :name
1175
+
1176
+ def to_model
1177
+ self
1178
+ end
1179
+
1180
+ def to_key
1181
+ id
1182
+ end
1183
+
1184
+ def persisted?
1185
+ false
1186
+ end
1187
+ end
1188
+ ```
883
1189
 
884
- ### Google Group
1190
+ If your object doesn't implement those methods, you must make explicit it when you are
1191
+ building the form
885
1192
 
886
- If you have any questions, comments, or concerns please use the Google Group instead of the GitHub
887
- Issues tracker:
1193
+ ```ruby
1194
+ class User
1195
+ attr_accessor :id, :name
888
1196
 
889
- http://groups.google.com/group/plataformatec-simpleform
1197
+ # The only method required to use the f.submit helper.
1198
+ def persisted?
1199
+ false
1200
+ end
1201
+ end
1202
+ ```
1203
+
1204
+ ```erb
1205
+ <%= simple_form_for(@user, as: :user, method: :post, url: users_path) do |f| %>
1206
+ <%= f.input :name %>
1207
+ <%= f.submit 'New user' %>
1208
+ <% end %>
1209
+ ```
1210
+
1211
+ ## Information
890
1212
 
891
1213
  ### RDocs
892
1214
 
893
1215
  You can view the **Simple Form** documentation in RDoc format here:
894
1216
 
895
- http://rubydoc.info/github/plataformatec/simple_form/master/frames
896
-
897
- If you need to use **Simple Form** with Rails 2.3, you can always run `gem server` from the command line
898
- after you install the gem to access the old documentation.
1217
+ http://rubydoc.info/github/heartcombo/simple_form/master/frames
899
1218
 
900
1219
  ### Bug reports
901
1220
 
902
1221
  If you discover any bugs, feel free to create an issue on GitHub. Please add as much information as
903
- possible to help us fixing the possible bug. We also encourage you to help even more by forking and
1222
+ possible to help us in fixing the potential bug. We also encourage you to help even more by forking and
904
1223
  sending us a pull request.
905
1224
 
906
- https://github.com/plataformatec/simple_form/issues
1225
+ https://github.com/heartcombo/simple_form/issues
1226
+
1227
+ If you have discovered a security related bug, please do NOT use the GitHub issue tracker. Send an e-mail to heartcombo@googlegroups.com.
907
1228
 
908
1229
  ## Maintainers
909
1230
 
910
- * José Valim (https://github.com/josevalim)
911
1231
  * Carlos Antonio da Silva (https://github.com/carlosantoniodasilva)
912
1232
  * Rafael Mendonça França (https://github.com/rafaelfranca)
913
- * Vasiliy Ermolovich (https://github.com/nashby)
1233
+ * Felipe Renan (https://github.com/feliperenan)
1234
+
1235
+ [![Gem Version](https://fury-badge.herokuapp.com/rb/simple_form.png)](http://badge.fury.io/rb/simple_form)
1236
+ [![Build Status](https://api.travis-ci.org/heartcombo/simple_form.svg?branch=master)](http://travis-ci.org/heartcombo/simple_form)
1237
+ [![Code Climate](https://codeclimate.com/github/heartcombo/simple_form.png)](https://codeclimate.com/github/heartcombo/simple_form)
1238
+ [![Inline docs](http://inch-ci.org/github/heartcombo/simple_form.png)](http://inch-ci.org/github/heartcombo/simple_form)
914
1239
 
915
1240
  ## License
916
1241
 
917
- MIT License. Copyright 2009-2013 Plataformatec. http://plataformatec.com.br
1242
+ MIT License. Copyright 2020 Rafael França, Carlos Antônio da Silva. Copyright 2009-2019 Plataformatec.
1243
+
1244
+ The Simple Form logo is licensed under [Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License](https://creativecommons.org/licenses/by-nc-nd/4.0/).
918
1245
 
919
- You are not granted rights or licenses to the trademarks of the Plataformatec, including without
920
- limitation the Simple Form name or logo.