bootstrap_form 4.4.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +48 -0
  3. data/.gitignore +28 -3
  4. data/.rubocop.yml +19 -15
  5. data/CHANGELOG.md +82 -1
  6. data/CONTRIBUTING.md +73 -12
  7. data/Dangerfile +5 -7
  8. data/Dockerfile +21 -0
  9. data/Gemfile +8 -11
  10. data/README.md +829 -82
  11. data/RELEASING.md +5 -10
  12. data/UPGRADE-4.0.md +1 -1
  13. data/UPGRADE-5.0.md +25 -0
  14. data/bootstrap_form.gemspec +8 -5
  15. data/demo/.ruby-version +1 -0
  16. data/demo/Gemfile +80 -0
  17. data/demo/Gemfile.lock +261 -0
  18. data/demo/Procfile.dev +2 -0
  19. data/demo/app/assets/builds/.keep +0 -0
  20. data/demo/app/assets/builds/application.js.LICENSE.txt +9 -0
  21. data/demo/app/assets/config/manifest.js +2 -2
  22. data/demo/app/assets/stylesheets/actiontext.css +31 -0
  23. data/demo/app/assets/stylesheets/application.scss +1 -1
  24. data/demo/app/controllers/bootstrap_controller.rb +17 -2
  25. data/demo/app/controllers/users_controller.rb +9 -0
  26. data/demo/app/helpers/bootstrap_helper.rb +5 -5
  27. data/demo/app/javascript/application.js +3 -0
  28. data/demo/app/models/skill.rb +15 -0
  29. data/demo/app/models/user.rb +14 -0
  30. data/demo/app/views/active_storage/blobs/_blob.html.erb +1 -1
  31. data/demo/app/views/bootstrap/form.html.erb +13 -0
  32. data/demo/app/views/layouts/action_text/contents/_content.html.erb +3 -0
  33. data/demo/app/views/layouts/application.html.erb +28 -20
  34. data/demo/bin/dev +9 -0
  35. data/demo/config/environments/development.rb +3 -3
  36. data/demo/config/puma.rb +2 -2
  37. data/demo/config/routes.rb +1 -0
  38. data/demo/db/schema.rb +31 -16
  39. data/demo/doc/screenshots/bootstrap/index/00_horizontal_form.png +0 -0
  40. data/demo/doc/screenshots/bootstrap/index/01_with_validation_error.png +0 -0
  41. data/demo/doc/screenshots/bootstrap/index/02_inline_form.png +0 -0
  42. data/demo/doc/screenshots/bootstrap/index/03_simple_action_text_example.png +0 -0
  43. data/demo/doc/screenshots/bootstrap/index/04_floating_labels.png +0 -0
  44. data/demo/doc/screenshots/bootstrap/readme/00_example.png +0 -0
  45. data/demo/doc/screenshots/bootstrap/readme/01_example.png +0 -0
  46. data/demo/doc/screenshots/bootstrap/readme/02_example.png +0 -0
  47. data/demo/doc/screenshots/bootstrap/readme/03_example.png +0 -0
  48. data/demo/doc/screenshots/bootstrap/readme/04_example.png +0 -0
  49. data/demo/doc/screenshots/bootstrap/readme/05_example.png +0 -0
  50. data/demo/doc/screenshots/bootstrap/readme/06_example.png +0 -0
  51. data/demo/doc/screenshots/bootstrap/readme/07_example.png +0 -0
  52. data/demo/doc/screenshots/bootstrap/readme/08_example.png +0 -0
  53. data/demo/doc/screenshots/bootstrap/readme/09_example.png +0 -0
  54. data/demo/doc/screenshots/bootstrap/readme/10_example.png +0 -0
  55. data/demo/doc/screenshots/bootstrap/readme/11_example.png +0 -0
  56. data/demo/doc/screenshots/bootstrap/readme/12_example.png +0 -0
  57. data/demo/doc/screenshots/bootstrap/readme/13_example.png +0 -0
  58. data/demo/doc/screenshots/bootstrap/readme/14_example.png +0 -0
  59. data/demo/doc/screenshots/bootstrap/readme/15_example.png +0 -0
  60. data/demo/doc/screenshots/bootstrap/readme/16_example.png +0 -0
  61. data/demo/doc/screenshots/bootstrap/readme/17_example.png +0 -0
  62. data/demo/doc/screenshots/bootstrap/readme/18_example.png +0 -0
  63. data/demo/doc/screenshots/bootstrap/readme/19_example.png +0 -0
  64. data/demo/doc/screenshots/bootstrap/readme/20_example.png +0 -0
  65. data/demo/doc/screenshots/bootstrap/readme/21_example.png +0 -0
  66. data/demo/doc/screenshots/bootstrap/readme/22_example.png +0 -0
  67. data/demo/doc/screenshots/bootstrap/readme/23_example.png +0 -0
  68. data/demo/doc/screenshots/bootstrap/readme/24_example.png +0 -0
  69. data/demo/doc/screenshots/bootstrap/readme/25_example.png +0 -0
  70. data/demo/doc/screenshots/bootstrap/readme/26_example.png +0 -0
  71. data/demo/doc/screenshots/bootstrap/readme/27_example.png +0 -0
  72. data/demo/doc/screenshots/bootstrap/readme/28_example.png +0 -0
  73. data/demo/doc/screenshots/bootstrap/readme/29_example.png +0 -0
  74. data/demo/doc/screenshots/bootstrap/readme/30_example.png +0 -0
  75. data/demo/doc/screenshots/bootstrap/readme/31_example.png +0 -0
  76. data/demo/doc/screenshots/bootstrap/readme/32_example.png +0 -0
  77. data/demo/doc/screenshots/bootstrap/readme/33_example.png +0 -0
  78. data/demo/doc/screenshots/bootstrap/readme/34_example.png +0 -0
  79. data/demo/doc/screenshots/bootstrap/readme/35_example.png +0 -0
  80. data/demo/doc/screenshots/bootstrap/readme/36_example.png +0 -0
  81. data/demo/doc/screenshots/bootstrap/readme/37_example.png +0 -0
  82. data/demo/doc/screenshots/bootstrap/readme/38_example.png +0 -0
  83. data/demo/doc/screenshots/bootstrap/readme/39_example.png +0 -0
  84. data/demo/doc/screenshots/bootstrap/readme/40_example.png +0 -0
  85. data/demo/doc/screenshots/bootstrap/readme/41_example.png +0 -0
  86. data/demo/doc/screenshots/bootstrap/readme/42_example.png +0 -0
  87. data/demo/doc/screenshots/bootstrap/readme/43_example.png +0 -0
  88. data/demo/doc/screenshots/bootstrap/readme/44_example.png +0 -0
  89. data/demo/doc/screenshots/bootstrap/readme/45_example.png +0 -0
  90. data/demo/doc/screenshots/bootstrap/readme/46_example.png +0 -0
  91. data/demo/doc/screenshots/bootstrap/readme/47_example.png +0 -0
  92. data/demo/doc/screenshots/bootstrap/readme/48_example.png +0 -0
  93. data/demo/doc/screenshots/bootstrap/readme/49_example.png +0 -0
  94. data/demo/doc/screenshots/bootstrap/readme/50_example.png +0 -0
  95. data/demo/package.json +10 -6
  96. data/demo/test/application_system_test_case.rb +8 -0
  97. data/demo/test/controllers/bootstrap_controller_test.rb +8 -0
  98. data/demo/test/controllers/users_controller_test.rb +13 -0
  99. data/demo/test/fixtures/users.yml +2 -0
  100. data/demo/test/system/bootstrap_test.rb +84 -0
  101. data/demo/test/test_helper.rb +10 -0
  102. data/demo/webpack.config.js +20 -0
  103. data/demo/yarn.lock +4063 -3144
  104. data/docker-compose.yml +49 -0
  105. data/gemfiles/5.2.gemfile +2 -15
  106. data/gemfiles/6.0.gemfile +2 -17
  107. data/gemfiles/6.1.gemfile +4 -0
  108. data/gemfiles/7.0.gemfile +6 -0
  109. data/gemfiles/edge.gemfile +2 -17
  110. data/lib/bootstrap_form/action_view_extensions/form_helper.rb +1 -1
  111. data/lib/bootstrap_form/components/hints.rb +13 -4
  112. data/lib/bootstrap_form/components/labels.rb +2 -2
  113. data/lib/bootstrap_form/components/validation.rb +1 -1
  114. data/lib/bootstrap_form/configuration.rb +22 -0
  115. data/lib/bootstrap_form/form_builder.rb +10 -12
  116. data/lib/bootstrap_form/form_group.rb +26 -11
  117. data/lib/bootstrap_form/form_group_builder.rb +6 -8
  118. data/lib/bootstrap_form/helpers/bootstrap.rb +17 -12
  119. data/lib/bootstrap_form/inputs/base.rb +5 -5
  120. data/lib/bootstrap_form/inputs/check_box.rb +11 -23
  121. data/lib/bootstrap_form/inputs/collection_check_boxes.rb +5 -1
  122. data/lib/bootstrap_form/inputs/collection_select.rb +2 -1
  123. data/lib/bootstrap_form/inputs/file_field.rb +3 -15
  124. data/lib/bootstrap_form/inputs/grouped_collection_select.rb +2 -1
  125. data/lib/bootstrap_form/inputs/radio_button.rb +17 -30
  126. data/lib/bootstrap_form/inputs/select.rb +1 -0
  127. data/lib/bootstrap_form/inputs/time_zone_select.rb +1 -0
  128. data/lib/bootstrap_form/version.rb +1 -1
  129. data/lib/bootstrap_form.rb +17 -7
  130. metadata +94 -16
  131. data/.travis.yml +0 -42
  132. data/demo/config/initializers/assets.rb +0 -14
  133. data/gemfiles/5.0.gemfile +0 -18
  134. data/gemfiles/5.1.gemfile +0 -17
data/README.md CHANGED
@@ -1,17 +1,11 @@
1
- If you are using Bootstrap v3, refer to the legacy [legacy-2.7](https://github.com/bootstrap-ruby/bootstrap_form/tree/legacy-2.7) branch.
2
-
3
- This is a new take on the `bootstrap_form` README. Please leave comments at: #520. You can go back to the traditional [README](/OLD-README.md).
4
-
5
- ---
6
-
7
1
  # bootstrap_form
8
2
 
9
- [![Build Status](https://travis-ci.org/bootstrap-ruby/bootstrap_form.svg?branch=master)](https://travis-ci.org/bootstrap-ruby/bootstrap_form)
3
+ [![Ruby](https://github.com/bootstrap-ruby/bootstrap_form/actions/workflows/ruby.yml/badge.svg)](https://github.com/bootstrap-ruby/bootstrap_form/actions/workflows/ruby.yml)
10
4
  [![Gem Version](https://badge.fury.io/rb/bootstrap_form.svg)](https://rubygems.org/gems/bootstrap_form)
11
5
 
12
- `bootstrap_form` is a Rails form builder that makes it super easy to integrate Bootstrap v4-style forms into your Rails application. It provides form helpers that augment the Rails form helpers. `bootstrap_forms`'s form helpers generate the form field and its label and all the Bootstrap mark-up required for proper Bootstrap display. `bootstrap_form` also provides:
6
+ `bootstrap_form` is a Rails form builder that makes it super easy to integrate Bootstrap v5-style forms into your Rails application. It provides form helpers that augment the Rails form helpers. `bootstrap_forms`'s form helpers generate the form field and its label and all the Bootstrap mark-up required for proper Bootstrap display. `bootstrap_form` also provides:
13
7
 
14
- * [Validation error messages](#validation-and-errors) below the field they correspond to, by default. You can also put the error messages after the label, or turn off `bootstrap_form`'s validation error handling and do it yourself.
8
+ * [Validation error messages](#validation-and-errors) below the field they correspond to, by default. You can also put the error messages after the label, or turn off `bootstrap_form`'s validation error handling and do it yourself. _Note that this applies to Rails-generated validation messages._ HTML 5 client-side validation and Rails validation out of the box don't really work well together. One discussion of the challenges and some solutions is [here](https://www.jorgemanrubia.com/2019/02/16/form-validations-with-html5-and-modern-rails/)
15
9
  * Automatic [mark-up for the `required` attribute](#required-fields) on required fields.
16
10
  * An easy way to consistently show [help](#help-text) text on fields.
17
11
  * Mark-up for [Bootstrap horizontal forms](#horizontal-forms) (labels to the left of their fields, like a traditional desktop application), if that's what you want.
@@ -31,16 +25,24 @@ Some other nice things that `bootstrap_form` does for you are:
31
25
 
32
26
  `bootstrap_form` supports at a minimum the currently supported versions of Ruby and Rails:
33
27
 
34
- * Ruby 2.4+
35
- * Rails 5.0+ (Rails 5.1+ for `bootstrap_form_with`)
36
- * Bootstrap 4.0+
28
+ * Ruby 2.5+
29
+ * Rails 5.2+
30
+ * Bootstrap 5.0+
37
31
 
38
32
  ## Installation
39
33
 
40
- Add it to your Gemfile:
34
+ Install Bootstrap 5. There are many ways to do this, depending on the asset pipeline you're using in your Rails application. One way is to use the gem that works with Sprockets. To do so, in a brand new Rails 7.0 application created _without_ the `--webpacker` option, add the `bootstrap` gem to your `Gemfile`:
41
35
 
42
36
  ```ruby
43
- gem "bootstrap_form", "~> 4.0"
37
+ gem "bootstrap", "~> 5.0"
38
+ ```
39
+
40
+ And follow the remaining instructions in the [official bootstrap installation guide](https://github.com/twbs/bootstrap-rubygem#a-ruby-on-rails) for setting up `application.scss` and `application.js`.
41
+
42
+ Add the `bootstrap_form` gem to your `Gemfile`:
43
+
44
+ ```ruby
45
+ gem "bootstrap_form", "~> 5.1"
44
46
  ```
45
47
 
46
48
  Then:
@@ -66,6 +68,7 @@ If you followed the [official bootstrap installation guide](https://github.com/t
66
68
 
67
69
  To get started, use the `bootstrap_form_for` helper in place of the Rails `form_for` helper. Here's an example:
68
70
 
71
+ ![Example 0](demo/doc/screenshots/bootstrap/readme/00_example.png "Example 0")
69
72
  ```erb
70
73
  <%= bootstrap_form_for(@user) do |f| %>
71
74
  <%= f.email_field :email %>
@@ -79,20 +82,20 @@ This generates the following HTML:
79
82
 
80
83
  ```html
81
84
  <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
82
- <div class="form-group">
83
- <label for="user_email">Email</label>
84
- <input class="form-control" id="user_email" name="user[email]" type="email">
85
+ <div class="mb-3">
86
+ <label class="form-label required" for="user_email">Email</label>
87
+ <input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
85
88
  </div>
86
- <div class="form-group">
87
- <label for="user_password">Password</label>
89
+ <div class="mb-3">
90
+ <label class="form-label" for="user_password">Password</label>
88
91
  <input class="form-control" id="user_password" name="user[password]" type="password">
89
92
  </div>
90
- <div class="form-check">
91
- <input name="user[remember_me]" type="hidden" value="0">
93
+ <div class="form-check mb-3">
94
+ <input autocomplete="off" name="user[remember_me]" type="hidden" value="0">
92
95
  <input class="form-check-input" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1">
93
96
  <label class="form-check-label" for="user_remember_me">Remember me</label>
94
97
  </div>
95
- <input class="btn btn-secondary" name="commit" type="submit" value="Log In">
98
+ <input class="btn btn-secondary" data-disable-with="Log In" name="commit" type="submit" value="Log In">
96
99
  </form>
97
100
  ```
98
101
 
@@ -100,6 +103,7 @@ This generates the following HTML:
100
103
 
101
104
  If your form is not backed by a model, use the `bootstrap_form_tag`. Usage of this helper is the same as `bootstrap_form_for`, except no model object is passed in as the first argument. Here's an example:
102
105
 
106
+ ![Example 1](demo/doc/screenshots/bootstrap/readme/01_example.png "Example 1")
103
107
  ```erb
104
108
  <%= bootstrap_form_tag url: '/subscribe' do |f| %>
105
109
  <%= f.email_field :email, value: 'name@example.com' %>
@@ -107,16 +111,29 @@ If your form is not backed by a model, use the `bootstrap_form_tag`. Usage of th
107
111
  <% end %>
108
112
  ```
109
113
 
110
- ### bootstrap_form_with (Rails 5.1+)
114
+ This generates:
115
+
116
+ ```html
117
+ <form accept-charset="UTF-8" action="/subscribe" method="post">
118
+ <div class="mb-3">
119
+ <label class="form-label" for="email">Email</label>
120
+ <input class="form-control" id="email" name="email" type="email" value="name@example.com">
121
+ </div>
122
+ <input class="btn btn-secondary" data-disable-with="Save " name="commit" type="submit" value="Save ">
123
+ </form>
124
+ ```
125
+
126
+ ### bootstrap_form_with
111
127
 
112
128
  Note that `form_with` in Rails 5.1 does not add IDs to form elements and labels by default, which are both important to Bootstrap markup. This behaviour is corrected in Rails 5.2.
113
129
 
114
130
  To get started, just use the `bootstrap_form_with` helper in place of `form_with`. Here's an example:
115
131
 
132
+ ![Example 2](demo/doc/screenshots/bootstrap/readme/02_example.png "Example 2")
116
133
  ```erb
117
134
  <%= bootstrap_form_with(model: @user, local: true) do |f| %>
118
135
  <%= f.email_field :email %>
119
- <%= f.password_field :password %>
136
+ <%= f.password_field :password, help: 'A good password should be at least six characters long' %>
120
137
  <%= f.check_box :remember_me %>
121
138
  <%= f.submit "Log In" %>
122
139
  <% end %>
@@ -125,23 +142,22 @@ To get started, just use the `bootstrap_form_with` helper in place of `form_with
125
142
  This generates:
126
143
 
127
144
  ```html
128
- <form role="form" action="/users" accept-charset="UTF-8" method="post">
129
- <input name="utf8" type="hidden" value="&#x2713;" />
130
- <div class="form-group">
131
- <label class="required" for="user_email">Email</label>
132
- <input class="form-control" type="email" value="steve@example.com" name="user[email]" />
145
+ <form accept-charset="UTF-8" action="/users" method="post">
146
+ <div class="mb-3">
147
+ <label class="form-label required" for="user_email">Email</label>
148
+ <input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
133
149
  </div>
134
- <div class="form-group">
135
- <label for="user_password">Password</label>
136
- <input class="form-control" type="password" name="user[password]" />
150
+ <div class="mb-3">
151
+ <label class="form-label" for="user_password">Password</label>
152
+ <input class="form-control" id="user_password" name="user[password]" type="password">
137
153
  <small class="form-text text-muted">A good password should be at least six characters long</small>
138
154
  </div>
139
- <div class="form-check">
140
- <input name="user[remember_me]" type="hidden" value="0">
155
+ <div class="form-check mb-3">
156
+ <input autocomplete="off" name="user[remember_me]" type="hidden" value="0">
141
157
  <input class="form-check-input" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1">
142
158
  <label class="form-check-label" for="user_remember_me">Remember me</label>
143
159
  </div>
144
- <input type="submit" name="commit" value="Log In" class="btn btn-secondary" data-disable-with="Log In" />
160
+ <input class="btn btn-secondary" data-disable-with="Log In" name="commit" type="submit" value="Log In">
145
161
  </form>
146
162
  ```
147
163
 
@@ -150,6 +166,25 @@ in `form_with`.
150
166
 
151
167
  `form_with` has some important differences compared to `form_for` and `form_tag`, and these differences apply to `bootstrap_form_with`. A good summary of the differences can be found at: https://m.patrikonrails.com/rails-5-1s-form-with-vs-old-form-helpers-3a5f72a8c78a, or in the [Rails documentation](api.rubyonrails.org).
152
168
 
169
+ ## Configuration
170
+
171
+ `bootstrap_form` can be used out-of-the-box without any configuration. However, `bootstrap_form` does have an optional configuration file at `config/initializers/bootstrap_form.rb` for setting options that affect all generated forms in an application.
172
+
173
+ The current configuration options are:
174
+
175
+ | Option | Default value | Description |
176
+ |---------------------------|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
177
+ | `default_form_attributes` | | `bootstrap_form` versions 3 and 4 added a role="form" attribute to all forms. The W3C validator will raise a **warning** on forms with a role="form" attribute. `bootstrap_form` version 5 drops this attribute by default. Set this option to `{ role: "form" }` to make forms non-compliant with W3C, but generate the `role="form"` attribute like `bootstrap_form` versions 3 and 4. |
178
+
179
+ Example:
180
+
181
+ ```ruby
182
+ # config/initializers/bootstrap_form.rb
183
+ BootstrapForm.configure do |c|
184
+ c.default_form_attributes = { role: "form" } # to make forms non-compliant with W3C.
185
+ end
186
+ ```
187
+
153
188
  ## Form Helpers
154
189
 
155
190
  `bootstrap_form` provides its own version of the following Rails form helpers:
@@ -199,41 +234,93 @@ The options for the form helpers that aren't in the exceptions list are describe
199
234
 
200
235
  Use the `label` option if you want to specify the field's label text:
201
236
 
237
+ ![Example 3](demo/doc/screenshots/bootstrap/readme/03_example.png "Example 3")
202
238
  ```erb
203
239
  <%= f.password_field :password_confirmation, label: "Confirm Password" %>
204
240
  ```
205
241
 
206
- To hide a label, use the `hide_label: true` option. This adds the `sr-only`
242
+ This generates:
243
+
244
+ ```html
245
+ <div class="mb-3">
246
+ <label class="form-label" for="user_password_confirmation">Confirm Password</label>
247
+ <input class="form-control" id="user_password_confirmation" name="user[password_confirmation]" type="password">
248
+ </div>
249
+ ```
250
+
251
+ To hide a label, use the `hide_label: true` option. This adds the `visually-hidden`
207
252
  class, which keeps your labels accessible to those using screen readers.
208
253
 
254
+ ![Example 4](demo/doc/screenshots/bootstrap/readme/04_example.png "Example 4")
209
255
  ```erb
210
256
  <%= f.text_area :comment, hide_label: true, placeholder: "Leave a comment..." %>
211
257
  ```
212
258
 
259
+ This generates:
260
+
261
+ ```html
262
+ <div class="mb-3">
263
+ <label class="form-label visually-hidden" for="user_comment">Comment</label>
264
+ <textarea class="form-control" id="user_comment" name="user[comment]" placeholder="Leave a comment...">
265
+ </textarea>
266
+ </div>
267
+ ```
268
+
213
269
  To add custom classes to the field's label:
214
270
 
271
+ ![Example 5](demo/doc/screenshots/bootstrap/readme/05_example.png "Example 5")
215
272
  ```erb
216
273
  <%= f.text_field :email, label_class: "custom-class" %>
217
274
  ```
218
275
 
276
+ This generates:
277
+
278
+ ```html
279
+ <div class="mb-3">
280
+ <label class="form-label custom-class required" for="user_email">Email</label>
281
+ <input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com">
282
+ </div>
283
+ ```
284
+
219
285
  Or you can add the label as input placeholder instead (this automatically hides the label):
220
286
 
287
+ ![Example 6](demo/doc/screenshots/bootstrap/readme/06_example.png "Example 6")
221
288
  ```erb
222
289
  <%= f.text_field :email, label_as_placeholder: true %>
223
290
  ```
224
291
 
292
+ This generates:
293
+
294
+ ```html
295
+ <div class="mb-3">
296
+ <label class="form-label visually-hidden required" for="user_email">Email</label>
297
+ <input class="form-control" id="user_email" name="user[email]" placeholder="Email" type="text" value="steve@example.com">
298
+ </div>
299
+ ```
300
+
225
301
  ### Input Elements / Controls
226
302
 
227
303
  To specify the class of the generated input tag, use the `control_class` option:
228
304
 
305
+ ![Example 7](demo/doc/screenshots/bootstrap/readme/07_example.png "Example 7")
229
306
  ```erb
230
307
  <%= f.text_field :email, control_class: "custom-class" %>
231
308
  ```
232
309
 
310
+ This generates:
311
+
312
+ ```html
313
+ <div class="mb-3">
314
+ <label class="form-label required" for="user_email">Email</label>
315
+ <input class="custom-class" id="user_email" name="user[email]" type="text" value="steve@example.com">
316
+ </div>
317
+ ```
318
+
233
319
  ### Help Text
234
320
 
235
321
  To add help text, use the `help` option:
236
322
 
323
+ ![Example 8](demo/doc/screenshots/bootstrap/readme/08_example.png "Example 8")
237
324
  ```erb
238
325
  <%= f.password_field :password, help: "Must be at least 6 characters long" %>
239
326
  ```
@@ -241,7 +328,11 @@ To add help text, use the `help` option:
241
328
  This generates:
242
329
 
243
330
  ```html
244
- <small class="form-text text-muted">Must be at least 6 characters long</small>
331
+ <div class="mb-3">
332
+ <label class="form-label" for="user_password">Password</label>
333
+ <input class="form-control" id="user_password" name="user[password]" type="password">
334
+ <small class="form-text text-muted">Must be at least 6 characters long</small>
335
+ </div>
245
336
  ```
246
337
 
247
338
  This gem is also aware of help messages in locale translation files (i18n):
@@ -274,58 +365,146 @@ option or turn them off completely by passing `help: false`.
274
365
 
275
366
  You can pass `prepend` and/or `append` options to input fields:
276
367
 
368
+ ![Example 9](demo/doc/screenshots/bootstrap/readme/09_example.png "Example 9")
277
369
  ```erb
278
370
  <%= f.text_field :price, prepend: "$", append: ".00" %>
279
371
  ```
280
372
 
373
+ This generates:
374
+
375
+ ```html
376
+ <div class="mb-3">
377
+ <label class="form-label" for="user_price">Price</label>
378
+ <div class="input-group">
379
+ <span class="input-group-text">$</span>
380
+ <input class="form-control" id="user_price" name="user[price]" type="text">
381
+ <span class="input-group-text">.00</span>
382
+ </div>
383
+ </div>
384
+ ```
385
+
281
386
  If you want to attach multiple items to the input, pass them as an array:
282
387
 
388
+ ![Example 10](demo/doc/screenshots/bootstrap/readme/10_example.png "Example 10")
283
389
  ```erb
284
390
  <%= f.text_field :price, prepend: ['Net', '$'], append: ['.00', 'per day'] %>
285
391
  ```
286
392
 
393
+ This generates:
394
+
395
+ ```html
396
+ <div class="mb-3">
397
+ <label class="form-label" for="user_price">Price</label>
398
+ <div class="input-group">
399
+ <span class="input-group-text">Net</span>
400
+ <span class="input-group-text">$</span>
401
+ <input class="form-control" id="user_price" name="user[price]" type="text">
402
+ <span class="input-group-text">.00</span>
403
+ <span class="input-group-text">per day</span>
404
+ </div>
405
+ </div>
406
+ ```
407
+
287
408
  You can also prepend and append buttons. Note: The buttons must contain the
288
409
  `btn` class to generate the correct markup.
289
410
 
411
+ ![Example 11](demo/doc/screenshots/bootstrap/readme/11_example.png "Example 11")
290
412
  ```erb
291
413
  <%= f.text_field :search, append: link_to("Go", "#", class: "btn btn-secondary") %>
292
414
  ```
293
415
 
416
+ This generates:
417
+
418
+ ```html
419
+ <div class="mb-3">
420
+ <label class="form-label" for="user_search">Search</label>
421
+ <div class="input-group">
422
+ <input class="form-control" id="user_search" name="user[search]" type="text">
423
+ <a class="btn btn-secondary" href="#">Go</a>
424
+ </div>
425
+ </div>
426
+ ```
427
+
294
428
  To add a class to the input group wrapper, use the `:input_group_class` option.
295
429
 
430
+ ![Example 12](demo/doc/screenshots/bootstrap/readme/12_example.png "Example 12")
296
431
  ```erb
297
432
  <%= f.email_field :email, append: f.primary('Subscribe'), input_group_class: 'input-group-lg' %>
298
433
  ```
299
434
 
435
+ This generates:
436
+
437
+ ```html
438
+ <div class="mb-3">
439
+ <label class="form-label required" for="user_email">Email</label>
440
+ <div class="input-group input-group-lg">
441
+ <input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
442
+ <input class="btn btn-primary" data-disable-with="Subscribe" name="commit" type="submit" value="Subscribe">
443
+ </div>
444
+ </div>
445
+ ```
446
+
300
447
  ### Additional Form Group Attributes
301
448
 
302
- Bootstrap mark-up dictates that most input field types have the label and input wrapped in a `div.form-group`.
449
+ Bootstrap mark-up dictates that most input field types have the label and input wrapped in a `div.mb-3`.
303
450
 
304
- If you want to add an additional CSS class or any other attribute to the form group div, you can use the `wrapper: { class: 'additional-class', data: { foo: 'bar' } }` option.
451
+ If you want to change the CSS class or any other attribute to the form group div, you can use the `wrapper: { class: 'mb-3 additional-class', data: { foo: 'bar' } }` option.
305
452
 
453
+ ![Example 13](demo/doc/screenshots/bootstrap/readme/13_example.png "Example 13")
306
454
  ```erb
307
- <%= f.text_field :name, wrapper: { class: 'has-warning', data: { foo: 'bar' } } %>
455
+ <%= f.text_field :name, wrapper: { class: 'mb-3 has-warning', data: { foo: 'bar' } } %>
456
+ ```
457
+
458
+ This generates:
459
+
460
+ ```html
461
+ <div class="mb-3 has-warning" data-foo="bar">
462
+ <label class="form-label" for="user_name">Name</label>
463
+ <input class="form-control" id="user_name" name="user[name]" type="text">
464
+ </div>
308
465
  ```
309
466
 
310
467
  Which produces the following output:
311
468
 
469
+ ![Example 14](demo/doc/screenshots/bootstrap/readme/14_example.png "Example 14")
312
470
  ```erb
313
- <div class="form-group has-warning" data-foo="bar">
314
- <label class="form-control-label" for="user_name">Id</label>
471
+ <div class="mb-3 has-warning" data-foo="bar">
472
+ <label class="form-label form-control-label" for="user_name">Id</label>
473
+ <input class="form-control" id="user_name" name="user[name]" type="text">
474
+ </div>
475
+ ```
476
+
477
+ This generates:
478
+
479
+ ```html
480
+ <div class="mb-3 has-warning" data-foo="bar">
481
+ <label class="form-label form-control-label" for="user_name">Id</label>
315
482
  <input class="form-control" id="user_name" name="user[name]" type="text">
316
483
  </div>
317
484
  ```
318
485
 
319
- If you only want to set the class on the form group div, you can use the `wrapper_class` option. It's just a short form of `wrapper: { class: 'additional-class' }`.
486
+ If you only want to set the class on the form group div, you can use the `wrapper_class` option: `wrapper_class: 'mb-3 additional-class'`.
487
+ It's just a short form of `wrapper: { class: 'mb-3 additional-class' }`.
488
+
489
+ If you don't want any class on the form group div, you can set it to `false`: `wrapper_class: false`.
320
490
 
321
491
  ### Suppressing the Form Group Altogether
322
492
 
323
493
  You may want to define your own form group div around a field. To do so, add the option `wrapper: false` to the input field. For example:
324
494
 
325
- ```ruby
326
- f.form_group :user do
327
- f.email_field :email, wrapper: false
328
- end
495
+ ![Example 15](demo/doc/screenshots/bootstrap/readme/15_example.png "Example 15")
496
+ ```erb
497
+ <%= f.form_group :user do %>
498
+ <%= f.email_field :email, wrapper: false %>
499
+ <% end %>
500
+ ```
501
+
502
+ Generated HTML:
503
+
504
+ ```html
505
+ <div class="mb-3">
506
+ <input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
507
+ </div>
329
508
  ```
330
509
 
331
510
  Note that Bootstrap relies on the form group div to correctly format most fields, so if you use the `wrapper: false` option, you should provide your own form group div around the input field. You can write your own HTML, or use the `form_group` helper.
@@ -334,16 +513,30 @@ Note that Bootstrap relies on the form group div to correctly format most fields
334
513
 
335
514
  Our select helper accepts the same arguments as the [default Rails helper](http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-select). Here's an example of how you pass both options and html_options hashes:
336
515
 
516
+ ![Example 16](demo/doc/screenshots/bootstrap/readme/16_example.png "Example 16")
337
517
  ```erb
338
518
  <%= f.select :product, [["Apple", 1], ["Grape", 2]], { label: "Choose your favorite fruit:", wrapper: { class: 'has-warning', data: { foo: 'bar' } } }, { class: "selectpicker" } %>
339
519
  ```
340
520
 
521
+ This generates:
522
+
523
+ ```html
524
+ <div class="has-warning" data-foo="bar">
525
+ <label class="form-label" for="user_product">Choose your favorite fruit:</label>
526
+ <select class="form-select selectpicker" id="user_product" name="user[product]">
527
+ <option value="1">Apple</option>
528
+ <option value="2">Grape</option>
529
+ </select>
530
+ </div>
531
+ ```
532
+
341
533
  ## Checkboxes and Radios
342
534
 
343
535
  Checkboxes and radios should be placed inside of a `form_group` to render
344
536
  properly. The following example ensures that the entire form group will display
345
537
  an error if an associated validations fails:
346
538
 
539
+ ![Example 17](demo/doc/screenshots/bootstrap/readme/17_example.png "Example 17")
347
540
  ```erb
348
541
  <%= f.form_group :skill_level, label: { text: "Skill" }, help: "Optional Help Text" do %>
349
542
  <%= f.radio_button :skill_level, 0, label: "Novice", checked: true %>
@@ -356,8 +549,37 @@ an error if an associated validations fails:
356
549
  <% end %>
357
550
  ```
358
551
 
552
+ This generates:
553
+
554
+ ```html
555
+ <div class="mb-3">
556
+ <label class="form-label" for="user_skill_level">Skill</label>
557
+ <div class="form-check">
558
+ <input checked class="form-check-input" id="user_skill_level_0" name="user[skill_level]" type="radio" value="0">
559
+ <label class="form-check-label" for="user_skill_level_0">Novice</label>
560
+ </div>
561
+ <div class="form-check">
562
+ <input class="form-check-input" id="user_skill_level_1" name="user[skill_level]" type="radio" value="1">
563
+ <label class="form-check-label" for="user_skill_level_1">Intermediate</label>
564
+ </div>
565
+ <div class="form-check">
566
+ <input class="form-check-input" id="user_skill_level_2" name="user[skill_level]" type="radio" value="2">
567
+ <label class="form-check-label" for="user_skill_level_2">Advanced</label>
568
+ </div>
569
+ <small class="form-text text-muted">Optional Help Text</small>
570
+ </div>
571
+ <div class="mb-3">
572
+ <div class="form-check mb-3">
573
+ <input autocomplete="off" name="user[terms]" type="hidden" value="0">
574
+ <input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1">
575
+ <label class="form-check-label" for="user_terms">I agree to the Terms of Service</label>
576
+ </div>
577
+ </div>
578
+ ```
579
+
359
580
  You can also create a checkbox using a block:
360
581
 
582
+ ![Example 18](demo/doc/screenshots/bootstrap/readme/18_example.png "Example 18")
361
583
  ```erb
362
584
  <%= f.form_group :terms, label: { text: "Optional Label" } do %>
363
585
  <%= f.check_box :terms do %>
@@ -366,8 +588,24 @@ You can also create a checkbox using a block:
366
588
  <% end %>
367
589
  ```
368
590
 
591
+ This generates:
592
+
593
+ ```html
594
+ <div class="mb-3">
595
+ <label class="form-label" for="user_terms">Optional Label</label>
596
+ <div class="form-check mb-3">
597
+ <input autocomplete="off" name="user[terms]" type="hidden" value="0">
598
+ <input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1">
599
+ <label class="form-check-label" for="user_terms">
600
+ You need to check this box to accept our terms of service and privacy policy
601
+ </label>
602
+ </div>
603
+ </div>
604
+ ```
605
+
369
606
  To display checkboxes and radios inline, pass the `inline: true` option:
370
607
 
608
+ ![Example 19](demo/doc/screenshots/bootstrap/readme/19_example.png "Example 19")
371
609
  ```erb
372
610
  <%= f.form_group :skill_level, label: { text: "Skill" } do %>
373
611
  <%= f.radio_button :skill_level, 0, label: "Novice", inline: true %>
@@ -376,18 +614,81 @@ To display checkboxes and radios inline, pass the `inline: true` option:
376
614
  <% end %>
377
615
  ```
378
616
 
617
+ This generates:
618
+
619
+ ```html
620
+ <div class="mb-3">
621
+ <label class="form-label" for="user_skill_level">Skill</label>
622
+ <div class="form-check form-check-inline">
623
+ <input class="form-check-input" id="user_skill_level_0" name="user[skill_level]" type="radio" value="0">
624
+ <label class="form-check-label" for="user_skill_level_0">Novice</label>
625
+ </div>
626
+ <div class="form-check form-check-inline">
627
+ <input class="form-check-input" id="user_skill_level_1" name="user[skill_level]" type="radio" value="1">
628
+ <label class="form-check-label" for="user_skill_level_1">Intermediate</label>
629
+ </div>
630
+ <div class="form-check form-check-inline">
631
+ <input class="form-check-input" id="user_skill_level_2" name="user[skill_level]" type="radio" value="2">
632
+ <label class="form-check-label" for="user_skill_level_2">Advanced</label>
633
+ </div>
634
+ </div>
635
+ ```
636
+
379
637
  Check boxes and radio buttons are wrapped in a `div.form-check`. You can add classes to this `div` with the `:wrapper_class` option:
380
638
 
639
+ ![Example 20](demo/doc/screenshots/bootstrap/readme/20_example.png "Example 20")
381
640
  ```erb
382
641
  <%= f.radio_button :skill_level, 0, label: "Novice", inline: true, wrapper_class: "w-auto" %>
383
642
  ```
384
643
 
644
+ This generates:
645
+
646
+ ```html
647
+ <div class="form-check form-check-inline w-auto">
648
+ <input class="form-check-input" id="user_skill_level_0" name="user[skill_level]" type="radio" value="0">
649
+ <label class="form-check-label" for="user_skill_level_0">Novice</label>
650
+ </div>
651
+ ```
652
+
653
+ You can also add a style to the tag using the `wrapper` option:
654
+
655
+ ![Example 21](demo/doc/screenshots/bootstrap/readme/21_example.png "Example 21")
656
+ ```erb
657
+ <%= f.check_box :skilled, inline: true, wrapper: {style: "color: green"} %>
658
+ <%= f.radio_button :skill_level, 0, label: "Novice", inline: true, wrapper: {class: 'w-auto', style: "color: red"} %>
659
+ ```
660
+
661
+ This generates:
662
+
663
+ ```html
664
+ <div class="form-check form-check-inline mb-3" style="color: green">
665
+ <input autocomplete="off" name="user[skilled]" type="hidden" value="0">
666
+ <input class="form-check-input" id="user_skilled" name="user[skilled]" type="checkbox" value="1">
667
+ <label class="form-check-label" for="user_skilled">Skilled</label>
668
+ </div>
669
+ <div class="form-check form-check-inline w-auto" style="color: red">
670
+ <input class="form-check-input" id="user_skill_level_0" name="user[skill_level]" type="radio" value="0">
671
+ <label class="form-check-label" for="user_skill_level_0">Novice</label>
672
+ </div>
673
+ ```
674
+
385
675
  ### Switches
386
676
 
387
- To render checkboxes as switches with Bootstrap 4.2+, use `custom: :switch`:
677
+ To render checkboxes as switches with Bootstrap 4.2+, use `switch: true`:
388
678
 
679
+ ![Example 22](demo/doc/screenshots/bootstrap/readme/22_example.png "Example 22")
389
680
  ```erb
390
- <%= f.check_box :remember_me, custom: :switch %>
681
+ <%= f.check_box :remember_me, switch: true %>
682
+ ```
683
+
684
+ This generates:
685
+
686
+ ```html
687
+ <div class="form-check mb-3 form-switch">
688
+ <input autocomplete="off" name="user[remember_me]" type="hidden" value="0">
689
+ <input class="form-check-input" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1">
690
+ <label class="form-check-label" for="user_remember_me">Remember me</label>
691
+ </div>
391
692
  ```
392
693
 
393
694
  ### Collections
@@ -395,11 +696,40 @@ To render checkboxes as switches with Bootstrap 4.2+, use `custom: :switch`:
395
696
  `bootstrap_form` also provides helpers that automatically create the
396
697
  `form_group` and the `radio_button`s or `check_box`es for you:
397
698
 
699
+ ![Example 23](demo/doc/screenshots/bootstrap/readme/23_example.png "Example 23")
398
700
  ```erb
399
701
  <%= f.collection_radio_buttons :skill_level, Skill.all, :id, :name %>
400
702
  <%= f.collection_check_boxes :skills, Skill.all, :id, :name %>
401
703
  ```
402
704
 
705
+ This generates:
706
+
707
+ ```html
708
+ <div class="mb-3">
709
+ <label class="form-label" for="user_skill_level">Skill level</label>
710
+ <div class="form-check">
711
+ <input class="form-check-input" id="user_skill_level_1" name="user[skill_level]" type="radio" value="1">
712
+ <label class="form-check-label" for="user_skill_level_1">Mind reading</label>
713
+ </div>
714
+ <div class="form-check">
715
+ <input class="form-check-input" id="user_skill_level_2" name="user[skill_level]" type="radio" value="2">
716
+ <label class="form-check-label" for="user_skill_level_2">Farming</label>
717
+ </div>
718
+ </div>
719
+ <input autocomplete="off" id="user_skills" multiple name="user[skills][]" type="hidden" value="">
720
+ <div class="mb-3">
721
+ <label class="form-label" for="user_skills">Skills</label>
722
+ <div class="form-check">
723
+ <input class="form-check-input" id="user_skills_1" name="user[skills][]" type="checkbox" value="1">
724
+ <label class="form-check-label" for="user_skills_1">Mind reading</label>
725
+ </div>
726
+ <div class="form-check">
727
+ <input class="form-check-input" id="user_skills_2" name="user[skills][]" type="checkbox" value="2">
728
+ <label class="form-check-label" for="user_skills_2">Farming</label>
729
+ </div>
730
+ </div>
731
+ ```
732
+
403
733
  NOTE: These helpers do not currently support a block, unlike their equivalent Rails helpers. See issue [#477](https://github.com/bootstrap-ruby/bootstrap_form/issues/477). If you need to use the block syntax, use `collection_check_boxes_without_bootstrap` or `collection_radio_buttons_without_bootstrap` for now.
404
734
 
405
735
  Collection methods accept these options:
@@ -409,39 +739,98 @@ Collection methods accept these options:
409
739
  * `:help`: Add a help span to the `form_group`
410
740
  * Other options will be forwarded to the `radio_button`/`check_box` method
411
741
 
742
+ ## Range Controls
743
+
744
+ You can create a range control like this:
745
+
746
+ ![Example 24](demo/doc/screenshots/bootstrap/readme/24_example.png "Example 24")
747
+ ```erb
748
+ <%= f.range_field :excellence %>
749
+ ```
750
+
751
+ This generates:
752
+
753
+ ```html
754
+ <div class="mb-3">
755
+ <label class="form-label" for="user_excellence">Excellence</label>
756
+ <input class="form-control" id="user_excellence" name="user[excellence]" type="range">
757
+ </div>
758
+ ```
759
+
412
760
  ## Static Controls
413
761
 
414
762
  You can create a static control like this:
415
763
 
764
+ ![Example 25](demo/doc/screenshots/bootstrap/readme/25_example.png "Example 25")
416
765
  ```erb
417
766
  <%= f.static_control :email %>
418
767
  ```
419
768
 
769
+ This generates:
770
+
771
+ ```html
772
+ <div class="mb-3">
773
+ <label class="form-label required" for="user_email">Email</label>
774
+ <input class="form-control-plaintext" id="user_email" name="user[email]" readonly type="text" value="steve@example.com">
775
+ </div>
776
+ ```
777
+
420
778
  Here's the output for a horizontal layout:
421
779
 
780
+ ![Example 26](demo/doc/screenshots/bootstrap/readme/26_example.png "Example 26")
781
+ ```erb
782
+ <%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
783
+ <%= f.static_control :email %>
784
+ <% end %>
785
+ ```
786
+
787
+ This generates:
788
+
422
789
  ```html
423
- <div class="form-group">
424
- <label class="col-sm-2 form-control-label" for="user_email">Email</label>
425
- <div class="col-sm-10">
426
- <input class="form-control-plaintext" id="user_email" name="user[email]" readonly="readonly" type="text" value="test@email.com"/>
790
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
791
+ <div class="mb-3 row">
792
+ <label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
793
+ <div class="col-sm-10">
794
+ <input class="form-control-plaintext" id="user_email" name="user[email]" readonly type="text" value="steve@example.com">
795
+ </div>
427
796
  </div>
428
- </div>
797
+ </form>
429
798
  ```
430
799
 
431
800
  You can also create a static control that isn't based on a model attribute:
432
801
 
802
+ ![Example 27](demo/doc/screenshots/bootstrap/readme/27_example.png "Example 27")
433
803
  ```erb
434
804
  <%= f.static_control :field_name, label: "Custom Static Control", value: "Content Here" %>
435
805
  ```
436
806
 
807
+ This generates:
808
+
809
+ ```html
810
+ <div class="mb-3">
811
+ <label class="form-label" for="user_field_name">Custom Static Control</label>
812
+ <input class="form-control-plaintext" id="user_field_name" name="user[field_name]" readonly type="text" value="Content Here">
813
+ </div>
814
+ ```
815
+
437
816
  `field_name` may be any name that isn't already used in the form. Note that you may get "unpermitted parameter" messages in your log file with this approach.
438
817
 
439
818
  You can also create the static control the following way, if you don't need to get the value of the static control as a parameter when the form is submitted:
440
819
 
820
+ ![Example 28](demo/doc/screenshots/bootstrap/readme/28_example.png "Example 28")
441
821
  ```erb
442
822
  <%= f.static_control label: "Custom Static Control", value: "Content Here", name: nil %>
443
823
  ```
444
824
 
825
+ This generates:
826
+
827
+ ```html
828
+ <div class="mb-3">
829
+ <label class="form-label" for="user_">Custom Static Control</label>
830
+ <input class="form-control-plaintext" id="user_" readonly type="text" value="Content Here">
831
+ </div>
832
+ ```
833
+
445
834
  (If you neither provide a field name nor `name: nil`, the Rails code that submits the form will give a JavaScript error.)
446
835
 
447
836
  Prior to version 4 of `bootstrap_form`, you could pass a block to the `static_control` method.
@@ -462,28 +851,50 @@ this defining these selects as `inline-block` and a width of `auto`.
462
851
  The `btn btn-secondary` CSS classes are automatically added to your submit
463
852
  buttons.
464
853
 
854
+ ![Example 29](demo/doc/screenshots/bootstrap/readme/29_example.png "Example 29")
465
855
  ```erb
466
856
  <%= f.submit %>
467
857
  ```
468
858
 
859
+ This generates:
860
+
861
+ ```html
862
+ <input class="btn btn-secondary" data-disable-with="Create User" name="commit" type="submit" value="Create User">
863
+ ```
864
+
469
865
  You can also use the `primary` helper, which adds `btn btn-primary` to your
470
866
  submit button:
471
867
 
868
+ ![Example 30](demo/doc/screenshots/bootstrap/readme/30_example.png "Example 30")
472
869
  ```erb
473
870
  <%= f.primary "Optional Label" %>
474
871
  ```
475
872
 
873
+ This generates:
874
+
875
+ ```html
876
+ <input class="btn btn-primary" data-disable-with="Optional Label" name="commit" type="submit" value="Optional Label">
877
+ ```
878
+
476
879
  You can specify your own classes like this:
477
880
 
881
+ ![Example 31](demo/doc/screenshots/bootstrap/readme/31_example.png "Example 31")
478
882
  ```erb
479
883
  <%= f.submit "Log In", class: "btn btn-success" %>
480
884
  ```
481
885
 
886
+ This generates:
887
+
888
+ ```html
889
+ <input class="btn btn-success" data-disable-with="Log In" name="commit" type="submit" value="Log In">
890
+ ```
891
+
482
892
  If the `primary` helper receives a `render_as_button: true` option or a block,
483
893
  it will be rendered as an HTML button, instead of an input tag. This allows you
484
894
  to specify HTML content and styling for your buttons (such as adding
485
895
  illustrative icons to them). For example, the following statements
486
896
 
897
+ ![Example 32](demo/doc/screenshots/bootstrap/readme/32_example.png "Example 32")
487
898
  ```erb
488
899
  <%= f.primary "Save changes <span class='fa fa-save'></span>".html_safe, render_as_button: true %>
489
900
 
@@ -493,6 +904,17 @@ illustrative icons to them). For example, the following statements
493
904
  end %>
494
905
  ```
495
906
 
907
+ This generates:
908
+
909
+ ```html
910
+ <button class="btn btn-primary" name="button" type="submit">Save changes <span class="fa fa-save">
911
+ </span>
912
+ </button>
913
+ <button class="btn btn-primary" name="button" type="submit">Save changes <span class="fa fa-save">
914
+ </span>
915
+ </button>
916
+ ```
917
+
496
918
  are equivalent, and each of them both be rendered as:
497
919
 
498
920
  ```html
@@ -506,6 +928,7 @@ Bootstrap classes), or for element targeting via CSS classes.
506
928
  Be aware, however, that using the `class` option will discard any extra classes
507
929
  you add. As an example, the following button declarations
508
930
 
931
+ ![Example 33](demo/doc/screenshots/bootstrap/readme/33_example.png "Example 33")
509
932
  ```erb
510
933
  <%= f.primary "My Nice Button", extra_class: 'my-button' %>
511
934
 
@@ -515,9 +938,8 @@ you add. As an example, the following button declarations
515
938
  will be rendered as
516
939
 
517
940
  ```html
518
- <input type="submit" value="My Nice Button" class="btn btn-primary my-button" />
519
-
520
- <input type="submit" value="My Button" class="my-button" />
941
+ <input class="btn btn-primary my-button" data-disable-with="My Nice Button" name="commit" type="submit" value="My Nice Button">
942
+ <input class="my-button" data-disable-with="My Button" name="commit" type="submit" value="My Button">
521
943
  ```
522
944
 
523
945
  (some unimportant HTML attributes have been removed for simplicity)
@@ -526,6 +948,7 @@ will be rendered as
526
948
 
527
949
  If you're using Rails 6, `bootstrap_form` supports the `rich_text_area` helper.
528
950
 
951
+ ![Example 34](demo/doc/screenshots/bootstrap/readme/34_example.png "Example 34")
529
952
  ```erb
530
953
  <%= f.rich_text_area(:life_story) %>
531
954
  ```
@@ -533,10 +956,49 @@ If you're using Rails 6, `bootstrap_form` supports the `rich_text_area` helper.
533
956
  will be rendered as:
534
957
 
535
958
  ```html
536
- <div class="form-group">
537
- <label for="user_life_story">Life story</label>
538
- <input type="hidden" name="user[life_story]" id="user_life_story_trix_input_user"/>
539
- <trix-editor id="user_life_story" data-blob-url-template="http://test.host/rails/active_storage/blobs/:signed_id/:filename" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" input="user_life_story_trix_input_user" class="trix-content form-control"/>
959
+ <div class="mb-3">
960
+ <label class="form-label" for="user_life_story">Life story</label>
961
+ <input autocomplete="off" id="user_life_story_trix_input_user" name="user[life_story]" type="hidden">
962
+ <trix-toolbar id="trix-toolbar-1">
963
+ <div class="trix-button-row">
964
+ <span class="trix-button-group trix-button-group--text-tools" data-trix-button-group="text-tools">
965
+ <button class="trix-button trix-button--icon trix-button--icon-bold" data-trix-attribute="bold" data-trix-key="b" tabindex="-1" title="Bold" type="button">Bold</button>
966
+ <button class="trix-button trix-button--icon trix-button--icon-italic" data-trix-attribute="italic" data-trix-key="i" tabindex="-1" title="Italic" type="button">Italic</button>
967
+ <button class="trix-button trix-button--icon trix-button--icon-strike" data-trix-attribute="strike" tabindex="-1" title="Strikethrough" type="button">Strikethrough</button>
968
+ <button class="trix-button trix-button--icon trix-button--icon-link" data-trix-action="link" data-trix-attribute="href" data-trix-key="k" tabindex="-1" title="Link" type="button">Link</button>
969
+ </span>
970
+ <span class="trix-button-group trix-button-group--block-tools" data-trix-button-group="block-tools">
971
+ <button class="trix-button trix-button--icon trix-button--icon-heading-1" data-trix-attribute="heading1" tabindex="-1" title="Heading" type="button">Heading</button>
972
+ <button class="trix-button trix-button--icon trix-button--icon-quote" data-trix-attribute="quote" tabindex="-1" title="Quote" type="button">Quote</button>
973
+ <button class="trix-button trix-button--icon trix-button--icon-code" data-trix-attribute="code" tabindex="-1" title="Code" type="button">Code</button>
974
+ <button class="trix-button trix-button--icon trix-button--icon-bullet-list" data-trix-attribute="bullet" tabindex="-1" title="Bullets" type="button">Bullets</button>
975
+ <button class="trix-button trix-button--icon trix-button--icon-number-list" data-trix-attribute="number" tabindex="-1" title="Numbers" type="button">Numbers</button>
976
+ <button class="trix-button trix-button--icon trix-button--icon-decrease-nesting-level" data-trix-action="decreaseNestingLevel" tabindex="-1" title="Decrease Level" type="button">Decrease Level</button>
977
+ <button class="trix-button trix-button--icon trix-button--icon-increase-nesting-level" data-trix-action="increaseNestingLevel" tabindex="-1" title="Increase Level" type="button">Increase Level</button>
978
+ </span>
979
+ <span class="trix-button-group trix-button-group--file-tools" data-trix-button-group="file-tools">
980
+ <button class="trix-button trix-button--icon trix-button--icon-attach" data-trix-action="attachFiles" tabindex="-1" title="Attach Files" type="button">Attach Files</button>
981
+ </span>
982
+ <span class="trix-button-group-spacer">
983
+ </span>
984
+ <span class="trix-button-group trix-button-group--history-tools" data-trix-button-group="history-tools">
985
+ <button class="trix-button trix-button--icon trix-button--icon-undo" data-trix-action="undo" data-trix-key="z" tabindex="-1" title="Undo" type="button">Undo</button>
986
+ <button class="trix-button trix-button--icon trix-button--icon-redo" data-trix-action="redo" data-trix-key="shift+z" tabindex="-1" title="Redo" type="button">Redo</button>
987
+ </span>
988
+ </div>
989
+ <div class="trix-dialogs" data-trix-dialogs="">
990
+ <div class="trix-dialog trix-dialog--link" data-trix-dialog="href" data-trix-dialog-attribute="href">
991
+ <div class="trix-dialog__link-fields">
992
+ <input aria-label="URL" class="trix-input trix-input--dialog" data-trix-input="" disabled name="href" placeholder="Enter a URL…" required="" type="url">
993
+ <div class="trix-button-group">
994
+ <input class="trix-button trix-button--dialog" data-trix-method="setAttribute" type="button" value="Link">
995
+ <input class="trix-button trix-button--dialog" data-trix-method="removeAttribute" type="button" value="Unlink">
996
+ </div>
997
+ </div>
998
+ </div>
999
+ </div>
1000
+ </trix-toolbar>
1001
+ <trix-editor aria-label="Life story" class="trix-content form-control" contenteditable="" data-blob-url-template="http://test.host/rails/active_storage/blobs/redirect/:signed_id/:filename" data-direct-upload-url="http://test.host/rails/active_storage/direct_uploads" id="user_life_story" input="user_life_story_trix_input_user" role="textbox" toolbar="trix-toolbar-1" trix-id="1">
540
1002
  </trix-editor>
541
1003
  </div>
542
1004
  ```
@@ -554,10 +1016,17 @@ The `hidden_field` helper in `bootstrap_form` calls the Rails helper directly, a
554
1016
  If you want to use the original Rails form helpers for a particular field,
555
1017
  append `_without_bootstrap` to the helper:
556
1018
 
1019
+ ![Example 35](demo/doc/screenshots/bootstrap/readme/35_example.png "Example 35")
557
1020
  ```erb
558
1021
  <%= f.text_field_without_bootstrap :email %>
559
1022
  ```
560
1023
 
1024
+ This generates:
1025
+
1026
+ ```html
1027
+ <input id="user_email" name="user[email]" type="text" value="steve@example.com">
1028
+ ```
1029
+
561
1030
  ## Form Styles
562
1031
 
563
1032
  By default, your forms will stack labels on top of controls and your controls
@@ -569,6 +1038,7 @@ To use an inline-layout form, use the `layout: :inline` option. To hide labels,
569
1038
  use the `hide_label: true` option, which keeps your labels accessible to those
570
1039
  using screen readers.
571
1040
 
1041
+ ![Example 36](demo/doc/screenshots/bootstrap/readme/36_example.png "Example 36")
572
1042
  ```erb
573
1043
  <%= bootstrap_form_for(@user, layout: :inline) do |f| %>
574
1044
  <%= f.email_field :email, hide_label: true %>
@@ -578,12 +1048,44 @@ using screen readers.
578
1048
  <% end %>
579
1049
  ```
580
1050
 
1051
+ This generates:
1052
+
1053
+ ```html
1054
+ <form accept-charset="UTF-8" action="/users" class="new_user row row-cols-auto g-3 align-items-center" id="new_user" method="post">
1055
+ <div class="col">
1056
+ <label class="form-label visually-hidden mr-sm-2 required" for="user_email">Email</label>
1057
+ <input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
1058
+ </div>
1059
+ <div class="col">
1060
+ <label class="form-label visually-hidden mr-sm-2" for="user_password">Password</label>
1061
+ <input class="form-control" id="user_password" name="user[password]" type="password">
1062
+ </div>
1063
+ <div class="form-check form-check-inline mb-3">
1064
+ <input autocomplete="off" name="user[remember_me]" type="hidden" value="0">
1065
+ <input class="form-check-input" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1">
1066
+ <label class="form-check-label" for="user_remember_me">Remember me</label>
1067
+ </div>
1068
+ <div class="col">
1069
+ <input class="btn btn-secondary" data-disable-with="Create User" name="commit" type="submit" value="Create User">
1070
+ </div>
1071
+ </form>
1072
+ ```
1073
+
581
1074
  To skip label rendering at all, use `skip_label: true` option.
582
1075
 
1076
+ ![Example 37](demo/doc/screenshots/bootstrap/readme/37_example.png "Example 37")
583
1077
  ```erb
584
1078
  <%= f.password_field :password, skip_label: true %>
585
1079
  ```
586
1080
 
1081
+ This generates:
1082
+
1083
+ ```html
1084
+ <div class="mb-3">
1085
+ <input class="form-control" id="user_password" name="user[password]" type="password">
1086
+ </div>
1087
+ ```
1088
+
587
1089
  ### Horizontal Forms
588
1090
 
589
1091
  To use a horizontal-layout form with labels to the left of the control, use the
@@ -593,6 +1095,7 @@ To use a horizontal-layout form with labels to the left of the control, use the
593
1095
  In the example below, the checkbox and submit button have been wrapped in a
594
1096
  `form_group` to keep them properly aligned.
595
1097
 
1098
+ ![Example 38](demo/doc/screenshots/bootstrap/readme/38_example.png "Example 38")
596
1099
  ```erb
597
1100
  <%= bootstrap_form_for(@user, layout: :horizontal, label_col: "col-sm-2", control_col: "col-sm-10") do |f| %>
598
1101
  <%= f.email_field :email %>
@@ -606,8 +1109,43 @@ In the example below, the checkbox and submit button have been wrapped in a
606
1109
  <% end %>
607
1110
  ```
608
1111
 
1112
+ This generates:
1113
+
1114
+ ```html
1115
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1116
+ <div class="mb-3 row">
1117
+ <label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
1118
+ <div class="col-sm-10">
1119
+ <input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
1120
+ </div>
1121
+ </div>
1122
+ <div class="mb-3 row">
1123
+ <label class="form-label col-form-label col-sm-2" for="user_password">Password</label>
1124
+ <div class="col-sm-10">
1125
+ <input class="form-control" id="user_password" name="user[password]" type="password">
1126
+ </div>
1127
+ </div>
1128
+ <div class="mb-3 row">
1129
+ <div class="col-sm-10 offset-sm-2">
1130
+ <div class="form-check">
1131
+ <input autocomplete="off" name="user[remember_me]" type="hidden" value="0">
1132
+ <input class="form-check-input" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1">
1133
+ <label class="form-check-label" for="user_remember_me">Remember me</label>
1134
+ </div>
1135
+ </div>
1136
+ </div>
1137
+
1138
+ <div class="mb-3 row">
1139
+ <div class="col-sm-10 offset-sm-2">
1140
+ <input class="btn btn-secondary" data-disable-with="Create User" name="commit" type="submit" value="Create User">
1141
+ </div>
1142
+ </div>
1143
+ </form>
1144
+ ```
1145
+
609
1146
  The `label_col` and `control_col` css classes can also be changed per control:
610
1147
 
1148
+ ![Example 39](demo/doc/screenshots/bootstrap/readme/39_example.png "Example 39")
611
1149
  ```erb
612
1150
  <%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
613
1151
  <%= f.email_field :email %>
@@ -618,6 +1156,30 @@ The `label_col` and `control_col` css classes can also be changed per control:
618
1156
  <% end %>
619
1157
  ```
620
1158
 
1159
+ This generates:
1160
+
1161
+ ```html
1162
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1163
+ <div class="mb-3 row">
1164
+ <label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
1165
+ <div class="col-sm-10">
1166
+ <input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
1167
+ </div>
1168
+ </div>
1169
+ <div class="mb-3 row">
1170
+ <label class="form-label col-form-label col-sm-2" for="user_age">Age</label>
1171
+ <div class="col-sm-3">
1172
+ <input class="form-control" id="user_age" name="user[age]" type="text" value="42">
1173
+ </div>
1174
+ </div>
1175
+ <div class="mb-3 row">
1176
+ <div class="col-sm-10 offset-sm-2">
1177
+ <input class="btn btn-secondary" data-disable-with="Create User" name="commit" type="submit" value="Create User">
1178
+ </div>
1179
+ </div>
1180
+ </form>
1181
+ ```
1182
+
621
1183
  or default value can be changed in initializer:
622
1184
 
623
1185
  ```ruby
@@ -640,6 +1202,7 @@ end
640
1202
 
641
1203
  Control col wrapper class can be modified with `add_control_col_class`. This option will preserve column definition:
642
1204
 
1205
+ ![Example 40](demo/doc/screenshots/bootstrap/readme/40_example.png "Example 40")
643
1206
  ```erb
644
1207
  <%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
645
1208
  <%= f.email_field :email %>
@@ -650,10 +1213,35 @@ Control col wrapper class can be modified with `add_control_col_class`. This opt
650
1213
  <% end %>
651
1214
  ```
652
1215
 
1216
+ This generates:
1217
+
1218
+ ```html
1219
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1220
+ <div class="mb-3 row">
1221
+ <label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
1222
+ <div class="col-sm-10">
1223
+ <input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
1224
+ </div>
1225
+ </div>
1226
+ <div class="mb-3 row">
1227
+ <label class="form-label col-form-label col-sm-2" for="user_age">Age</label>
1228
+ <div class="col-sm-10 additional-control-col-class">
1229
+ <input class="form-control" id="user_age" name="user[age]" type="text" value="42">
1230
+ </div>
1231
+ </div>
1232
+ <div class="mb-3 row">
1233
+ <div class="col-sm-10 offset-sm-2">
1234
+ <input class="btn btn-secondary" data-disable-with="Create User" name="commit" type="submit" value="Create User">
1235
+ </div>
1236
+ </div>
1237
+ </form>
1238
+ ```
1239
+
653
1240
  ### Custom Field Layout
654
1241
 
655
1242
  The form-level `layout` can be overridden per field, unless the form-level layout was `inline`:
656
1243
 
1244
+ ![Example 41](demo/doc/screenshots/bootstrap/readme/41_example.png "Example 41")
657
1245
  ```erb
658
1246
  <%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
659
1247
  <%= f.email_field :email %>
@@ -665,12 +1253,39 @@ The form-level `layout` can be overridden per field, unless the form-level layou
665
1253
  <% end %>
666
1254
  ```
667
1255
 
1256
+ This generates:
1257
+
1258
+ ```html
1259
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1260
+ <div class="mb-3 row">
1261
+ <label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
1262
+ <div class="col-sm-10">
1263
+ <input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
1264
+ </div>
1265
+ </div>
1266
+ <div class="mb-3">
1267
+ <label class="form-label" for="user_feet">Feet</label>
1268
+ <input class="form-control" id="user_feet" name="user[feet]" type="text" value="5">
1269
+ </div>
1270
+ <div class="mb-3">
1271
+ <label class="form-label" for="user_inches">Inches</label>
1272
+ <input class="form-control" id="user_inches" name="user[inches]" type="text" value="7">
1273
+ </div>
1274
+ <div class="mb-3 row">
1275
+ <div class="col-sm-10 offset-sm-2">
1276
+ <input class="btn btn-secondary" data-disable-with="Create User" name="commit" type="submit" value="Create User">
1277
+ </div>
1278
+ </div>
1279
+ </form>
1280
+ ```
1281
+
668
1282
  A form-level `layout: :inline` can't be overridden because of the way Bootstrap 4 implements in-line layouts. One possible work-around is to leave the form-level layout as default, and specify the individual fields as `layout: :inline`, except for the fields(s) that should be other than in-line.
669
1283
 
670
1284
  ### Custom Form Element Styles
671
1285
 
672
1286
  The `custom` option can be used to replace the browser default styles for check boxes and radio buttons with dedicated Bootstrap styled form elements. Here's an example:
673
1287
 
1288
+ ![Example 42](demo/doc/screenshots/bootstrap/readme/42_example.png "Example 42")
674
1289
  ```erb
675
1290
  <%= bootstrap_form_for(@user) do |f| %>
676
1291
  <%= f.email_field :email %>
@@ -680,6 +1295,71 @@ The `custom` option can be used to replace the browser default styles for check
680
1295
  <% end %>
681
1296
  ```
682
1297
 
1298
+ This generates:
1299
+
1300
+ ```html
1301
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1302
+ <div class="mb-3">
1303
+ <label class="form-label required" for="user_email">Email</label>
1304
+ <input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
1305
+ </div>
1306
+ <div class="mb-3">
1307
+ <label class="form-label" for="user_password">Password</label>
1308
+ <input class="form-control" id="user_password" name="user[password]" type="password">
1309
+ </div>
1310
+ <div class="form-check mb-3">
1311
+ <input autocomplete="off" name="user[remember_me]" type="hidden" value="0">
1312
+ <input class="form-check-input" custom="true" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1">
1313
+ <label class="form-check-label" for="user_remember_me">Remember me</label>
1314
+ </div>
1315
+ <input class="btn btn-secondary" data-disable-with="Log In" name="commit" type="submit" value="Log In">
1316
+ </form>
1317
+ ```
1318
+
1319
+ ### Floating Labels
1320
+
1321
+ The `floating` option can be used to enable Bootstrap 5's floating labels. This option is supported on text fields
1322
+ and dropdowns. Here's an example:
1323
+
1324
+ ![Example 43](demo/doc/screenshots/bootstrap/readme/43_example.png "Example 43")
1325
+ ```erb
1326
+ <%= bootstrap_form_for(@user) do |f| %>
1327
+ <%= f.email_field :email, floating: true %>
1328
+ <%= f.password_field :password, floating: true %>
1329
+ <%= f.password_field :password, floating: true %>
1330
+ <%= f.select :status, [["Active", 1], ["Inactive", 2]], include_blank: "Select a value", floating: true %>
1331
+ <%= f.submit "Log In" %>
1332
+ <% end %>
1333
+ ```
1334
+
1335
+ This generates:
1336
+
1337
+ ```html
1338
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1339
+ <div class="mb-3 form-floating">
1340
+ <input class="form-control" id="user_email" name="user[email]" placeholder="Email" type="email" value="steve@example.com">
1341
+ <label class="form-label required" for="user_email">Email</label>
1342
+ </div>
1343
+ <div class="mb-3 form-floating">
1344
+ <input class="form-control" id="user_password" name="user[password]" placeholder="Password" type="password">
1345
+ <label class="form-label" for="user_password">Password</label>
1346
+ </div>
1347
+ <div class="mb-3 form-floating">
1348
+ <input class="form-control" id="user_password" name="user[password]" placeholder="Password" type="password">
1349
+ <label class="form-label" for="user_password">Password</label>
1350
+ </div>
1351
+ <div class="mb-3 form-floating">
1352
+ <select class="form-select" id="user_status" name="user[status]">
1353
+ <option value="">Select a value</option>
1354
+ <option value="1">Active</option>
1355
+ <option value="2">Inactive</option>
1356
+ </select>
1357
+ <label class="form-label" for="user_status">Status</label>
1358
+ </div>
1359
+ <input class="btn btn-secondary" data-disable-with="Log In" name="commit" type="submit" value="Log In">
1360
+ </form>
1361
+ ```
1362
+
683
1363
  ## Validation and Errors
684
1364
 
685
1365
  Rails normally wraps fields with validation errors in a `div.field_with_errors`, but this behaviour isn't consistent with Bootstrap 4 styling. By default, `bootstrap_form` generations in-line errors which appear below the field. But it can also generate errors on the label, or not display any errors, leaving it up to you.
@@ -690,8 +1370,8 @@ By default, fields that have validation errors will be outlined in red and the
690
1370
  error will be displayed below the field. Here's an example:
691
1371
 
692
1372
  ```html
693
- <div class="form-group">
694
- <label class="form-control-label" for="user_email">Email</label>
1373
+ <div class="mb-3">
1374
+ <label class="form-label form-control-label" for="user_email">Email</label>
695
1375
  <input class="form-control is-invalid" id="user_email" name="user[email]" type="email" value="">
696
1376
  <small class="invalid-feedback">can't be blank</small>
697
1377
  </div>
@@ -731,66 +1411,115 @@ To display an error message with an error summary, you can use the
731
1411
  `alert_message` helper. This won't output anything unless a model validation
732
1412
  has failed.
733
1413
 
1414
+ ![Example 44](demo/doc/screenshots/bootstrap/readme/44_example.png "Example 44")
734
1415
  ```erb
735
- <%= f.alert_message "Please fix the errors below." %>
1416
+ <%= bootstrap_form_for @user_with_error do |f| %>
1417
+ <%= f.alert_message "Please fix the errors below." %>
1418
+ <% end %>
736
1419
  ```
737
1420
 
738
1421
  Which outputs:
739
1422
 
740
1423
  ```html
741
- <div class="alert alert-danger">
742
- <p>Please fix the errors below.</p>
743
- <ul class="rails-bootstrap-forms-error-summary">
744
- <li>Email can't be blank</li>
745
- </ul>
746
- </div>
1424
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1425
+ <div class="alert alert-danger">
1426
+ <p>Please fix the errors below.</p>
1427
+ <ul class="rails-bootstrap-forms-error-summary">
1428
+ <li>Email is invalid</li>
1429
+ <li>Misc is invalid</li>
1430
+ </ul>
1431
+ </div>
1432
+ </form>
747
1433
  ```
748
1434
 
749
1435
  You can turn off the error summary like this:
750
1436
 
1437
+ ![Example 45](demo/doc/screenshots/bootstrap/readme/45_example.png "Example 45")
751
1438
  ```erb
752
- <%= f.alert_message "Please fix the errors below.", error_summary: false %>
1439
+ <%= bootstrap_form_for @user_with_error do |f| %>
1440
+ <%= f.alert_message "Please fix the errors below.", error_summary: false %>
1441
+ <% end %>
1442
+ ```
1443
+
1444
+ This generates:
1445
+
1446
+ ```html
1447
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1448
+ <div class="alert alert-danger">Please fix the errors below.</div>
1449
+ </form>
753
1450
  ```
754
1451
 
755
1452
  To output a simple unordered list of errors, use the `error_summary` helper.
756
1453
 
1454
+ ![Example 46](demo/doc/screenshots/bootstrap/readme/46_example.png "Example 46")
757
1455
  ```erb
758
- <%= f.error_summary %>
1456
+ <%= bootstrap_form_for @user_with_error do |f| %>
1457
+ <%= f.error_summary %>
1458
+ <% end %>
759
1459
  ```
760
1460
 
761
1461
  Which outputs:
762
1462
 
763
1463
  ```html
764
- <ul class="rails-bootstrap-forms-error-summary">
765
- <li>Email can't be blank</li>
766
- </ul>
1464
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1465
+ <ul class="rails-bootstrap-forms-error-summary">
1466
+ <li>Email is invalid</li>
1467
+ <li>Misc is invalid</li>
1468
+ </ul>
1469
+ </form>
767
1470
  ```
768
1471
 
769
1472
  ### Errors On
770
1473
 
771
- If you want to display a custom inline error for a specific attribute not
772
- represented by a form field, use the `errors_on` helper.
1474
+ If you want to display a custom inline error for a specific attribute not represented by a form field, use the `errors_on` helper.
773
1475
 
1476
+ ![Example 47](demo/doc/screenshots/bootstrap/readme/47_example.png "Example 47")
774
1477
  ```erb
775
- <%= f.errors_on :tasks %>
1478
+ <%= bootstrap_form_for @user_with_error do |f| %>
1479
+ <%= f.errors_on :email %>
1480
+ <% end %>
776
1481
  ```
777
1482
 
778
1483
  Which outputs:
779
1484
 
780
1485
  ```html
781
- <div class="alert alert-danger">Tasks can't be blank.</div>
1486
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1487
+ <div class="invalid-feedback">Email is invalid</div>
1488
+ </form>
782
1489
  ```
783
1490
 
784
1491
  You can hide the attribute name like this:
785
1492
 
1493
+ ![Example 48](demo/doc/screenshots/bootstrap/readme/48_example.png "Example 48")
786
1494
  ```erb
787
- <%= f.errors_on :tasks, hide_attribute_name: true %>
1495
+ <%= bootstrap_form_for @user_with_error do |f| %>
1496
+ <%= f.errors_on :email, hide_attribute_name: true %>
1497
+ <% end %>
1498
+ ```
1499
+
1500
+ Which outputs:
1501
+
1502
+ ```html
1503
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1504
+ <div class="invalid-feedback">is invalid</div>
1505
+ </form>
1506
+ ```
1507
+
1508
+ You can also use a custom class for the wrapping div, like this:
1509
+
1510
+ ![Example 49](demo/doc/screenshots/bootstrap/readme/49_example.png "Example 49")
1511
+ ```erb
1512
+ <%= bootstrap_form_for @user_with_error do |f| %>
1513
+ <%= f.errors_on :email, custom_class: 'custom-error' %>
1514
+ <% end %>
788
1515
  ```
789
1516
 
790
1517
  Which outputs:
791
1518
 
792
1519
  ```html
793
- <div class="alert alert-danger">can't be blank.</div>
1520
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1521
+ <div class="custom-error">Email is invalid</div>
1522
+ </form>
794
1523
  ```
795
1524
 
796
1525
  ## Required Fields
@@ -813,11 +1542,25 @@ ActiveModel::Validations::PresenceValidator.
813
1542
 
814
1543
  In cases where this behaviour is undesirable, use the `required` option to force the class to be present or absent:
815
1544
 
1545
+ ![Example 50](demo/doc/screenshots/bootstrap/readme/50_example.png "Example 50")
816
1546
  ```erb
817
1547
  <%= f.password_field :login, label: "New Username", required: true %>
818
1548
  <%= f.password_field :password, label: "New Password", required: false %>
819
1549
  ```
820
1550
 
1551
+ This generates:
1552
+
1553
+ ```html
1554
+ <div class="mb-3">
1555
+ <label class="form-label required" for="user_login">New Username</label>
1556
+ <input class="form-control" id="user_login" name="user[login]" required="required" type="password">
1557
+ </div>
1558
+ <div class="mb-3">
1559
+ <label class="form-label" for="user_password">New Password</label>
1560
+ <input class="form-control" id="user_password" name="user[password]" type="password">
1561
+ </div>
1562
+ ```
1563
+
821
1564
  ## Internationalization
822
1565
 
823
1566
  bootstrap_form follows standard rails conventions so it's i18n-ready. See more
@@ -854,6 +1597,10 @@ If you're considering contributing to bootstrap_form,
854
1597
  please review the [Contributing](/CONTRIBUTING.md)
855
1598
  document first.
856
1599
 
1600
+ ## Previous Version
1601
+
1602
+ If you're looking for `bootstrap_form` for Bootstrap 4, go [here](https://github.com/bootstrap-ruby/bootstrap_form/tree/bootstrap-4).
1603
+
857
1604
  ## License
858
1605
 
859
- MIT License. Copyright 2012-2020 Stephen Potenza (https://github.com/potenza) and others
1606
+ MIT License. Copyright 2012-2021 Stephen Potenza (https://github.com/potenza) and others