bootstrap_form 5.2.3 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -19,14 +19,14 @@ Some other nice things that `bootstrap_form` does for you are:
19
19
  * Reduces errors, because you're doing less typing.
20
20
  * Makes it easier to see the logic of the form, because it's not mixed in with the Bootstrap mark-up.
21
21
 
22
- `bootstrap_form` works like the standard Rails form helpers, and this README assumes you know how they work. You start a form with one of [`bootstrap_form_with`](#bootstrap-form-with), [`bootstrap_form_for`](#bootstrap-form-for), or [`bootstrap_form_tag`](#bootstrap-form-tag) in a view file. You get a form builder that calls the [`bootstrap_form` helpers](#form-helpers) instead of the standard Rails helpers. You use that form builder in the view file to render one or more form fields.
22
+ `bootstrap_form` works like the standard Rails form helpers, and this README assumes you know how they work. You start a form with one of [`bootstrap_form_with`](#bootstrap_form_with), [`bootstrap_form_for`](#bootstrap_form_for), or [`bootstrap_form_tag`](#bootstrap_form_tag) in a view file. You get a form builder that calls the [`bootstrap_form` helpers](#form-helpers) instead of the standard Rails helpers. You use that form builder in the view file to render one or more form fields.
23
23
 
24
24
  ## Requirements
25
25
 
26
26
  `bootstrap_form` supports at a minimum the currently supported versions of Ruby and Rails:
27
27
 
28
28
  * Ruby 3.0+ (https://www.ruby-lang.org/en/downloads/branches/)
29
- * Rails 6.0+ (https://guides.rubyonrails.org/maintenance_policy.html)
29
+ * Rails 6.1+ (https://guides.rubyonrails.org/maintenance_policy.html)
30
30
  * Bootstrap 5.0+
31
31
 
32
32
  ## Installation
@@ -42,7 +42,7 @@ And follow the remaining instructions in the [official bootstrap installation gu
42
42
  Add the `bootstrap_form` gem to your `Gemfile`:
43
43
 
44
44
  ```ruby
45
- gem "bootstrap_form", "~> 5.2"
45
+ gem "bootstrap_form", "~> 5.3"
46
46
  ```
47
47
 
48
48
  Then:
@@ -84,7 +84,7 @@ This generates the following HTML:
84
84
  <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
85
85
  <div class="mb-3">
86
86
  <label class="form-label required" for="user_email">Email</label>
87
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
87
+ <input class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
88
88
  </div>
89
89
  <div class="mb-3">
90
90
  <label class="form-label" for="user_password">Password</label>
@@ -143,7 +143,7 @@ This generates:
143
143
  <form accept-charset="UTF-8" action="/users" method="post">
144
144
  <div class="mb-3">
145
145
  <label class="form-label required" for="user_email">Email</label>
146
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
146
+ <input class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
147
147
  </div>
148
148
  <div class="mb-3">
149
149
  <label class="form-label" for="user_password">Password</label>
@@ -164,6 +164,45 @@ in `form_with`.
164
164
 
165
165
  `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).
166
166
 
167
+ ### bootstrap_fields_for and bootstrap_fields
168
+
169
+ Adding fields for a different object without nesting can be achieved using the `bootstrap_fields_for` and
170
+ `bootstrap_fields` helpers in the same way it is done in Rails.
171
+
172
+ ![Example 3](demo/doc/screenshots/bootstrap/readme/03_example.png "Example 3")
173
+ ```erb
174
+ <%= bootstrap_form_with model: @user do |f| %>
175
+ <%= f.email_field :email %>
176
+ <%= bootstrap_fields_for :parent do |pf| %>
177
+ <%= pf.email_field :email, label: 'Parent email' %>
178
+ <% end %>
179
+ <%= bootstrap_fields @user.address do |af| %>
180
+ <%= af.text_field :street_name %>
181
+ <% end %>
182
+ <%= f.primary "Save" %>
183
+ <% end %>
184
+ ```
185
+
186
+ Generated HTML:
187
+
188
+ ```html
189
+ <form accept-charset="UTF-8" action="/users" method="post">
190
+ <div class="mb-3">
191
+ <label class="form-label required" for="user_email">Email</label>
192
+ <input class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
193
+ </div>
194
+ <div class="mb-3">
195
+ <label class="form-label" for="parent_email">Parent email</label>
196
+ <input class="form-control" id="parent_email" name="parent[email]" type="email">
197
+ </div>
198
+ <div class="mb-3">
199
+ <label class="form-label" for="street_name">Street name</label>
200
+ <input class="form-control" id="street_name" name="street_name" type="text">
201
+ </div>
202
+ <input class="btn btn-primary" data-disable-with="Save" name="commit" type="submit" value="Save">
203
+ </form>
204
+ ```
205
+
167
206
  ## Configuration
168
207
 
169
208
  `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.
@@ -232,7 +271,7 @@ The options for the form helpers that aren't in the exceptions list are describe
232
271
 
233
272
  Use the `label` option if you want to specify the field's label text:
234
273
 
235
- ![Example 3](demo/doc/screenshots/bootstrap/readme/03_example.png "Example 3")
274
+ ![Example 4](demo/doc/screenshots/bootstrap/readme/04_example.png "Example 4")
236
275
  ```erb
237
276
  <%= f.password_field :password_confirmation, label: "Confirm Password" %>
238
277
  ```
@@ -249,7 +288,7 @@ This generates:
249
288
  To hide a label, use the `hide_label: true` option. This adds the `visually-hidden`
250
289
  class, which keeps your labels accessible to those using screen readers.
251
290
 
252
- ![Example 4](demo/doc/screenshots/bootstrap/readme/04_example.png "Example 4")
291
+ ![Example 5](demo/doc/screenshots/bootstrap/readme/05_example.png "Example 5")
253
292
  ```erb
254
293
  <%= f.text_area :comment, hide_label: true, placeholder: "Leave a comment..." %>
255
294
  ```
@@ -258,7 +297,7 @@ This generates:
258
297
 
259
298
  ```html
260
299
  <div class="mb-3">
261
- <label class="form-label visually-hidden" for="user_comment">Comment</label>
300
+ <label class="visually-hidden" for="user_comment">Comment</label>
262
301
  <textarea class="form-control" id="user_comment" name="user[comment]" placeholder="Leave a comment...">
263
302
  </textarea>
264
303
  </div>
@@ -266,33 +305,33 @@ This generates:
266
305
 
267
306
  To add custom classes to the field's label:
268
307
 
269
- ![Example 5](demo/doc/screenshots/bootstrap/readme/05_example.png "Example 5")
308
+ ![Example 6](demo/doc/screenshots/bootstrap/readme/06_example.png "Example 6")
270
309
  ```erb
271
- <%= f.text_field :email, label_class: "custom-class" %>
310
+ <%= f.email_field :email, label_class: "custom-class" %>
272
311
  ```
273
312
 
274
313
  This generates:
275
314
 
276
315
  ```html
277
316
  <div class="mb-3">
278
- <label class="form-label custom-class required" for="user_email">Email</label>
279
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="text" value="steve@example.com">
317
+ <label class="custom-class required" for="user_email">Email</label>
318
+ <input class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
280
319
  </div>
281
320
  ```
282
321
 
283
322
  Or you can add the label as input placeholder instead (this automatically hides the label):
284
323
 
285
- ![Example 6](demo/doc/screenshots/bootstrap/readme/06_example.png "Example 6")
324
+ ![Example 7](demo/doc/screenshots/bootstrap/readme/07_example.png "Example 7")
286
325
  ```erb
287
- <%= f.text_field :email, value: '', label_as_placeholder: true %>
326
+ <%= f.email_field :email, value: '', label_as_placeholder: true %>
288
327
  ```
289
328
 
290
329
  This generates:
291
330
 
292
331
  ```html
293
332
  <div class="mb-3">
294
- <label class="form-label visually-hidden required" for="user_email">Email</label>
295
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" placeholder="Email" required="required" type="text" value="">
333
+ <label class="visually-hidden required" for="user_email">Email</label>
334
+ <input class="form-control" id="user_email" name="user[email]" placeholder="Email" required="required" type="email" value="">
296
335
  </div>
297
336
  ```
298
337
 
@@ -300,7 +339,7 @@ This generates:
300
339
 
301
340
  To specify the class of the generated input tag, use the `control_class` option:
302
341
 
303
- ![Example 7](demo/doc/screenshots/bootstrap/readme/07_example.png "Example 7")
342
+ ![Example 8](demo/doc/screenshots/bootstrap/readme/08_example.png "Example 8")
304
343
  ```erb
305
344
  <%= f.text_field :email, control_class: "custom-class" %>
306
345
  ```
@@ -310,7 +349,7 @@ This generates:
310
349
  ```html
311
350
  <div class="mb-3">
312
351
  <label class="form-label required" for="user_email">Email</label>
313
- <input aria-required="true" class="custom-class" id="user_email" name="user[email]" required="required" type="text" value="steve@example.com">
352
+ <input class="custom-class" id="user_email" name="user[email]" required="required" type="text" value="steve@example.com">
314
353
  </div>
315
354
  ```
316
355
 
@@ -318,7 +357,7 @@ This generates:
318
357
 
319
358
  To add help text, use the `help` option:
320
359
 
321
- ![Example 8](demo/doc/screenshots/bootstrap/readme/08_example.png "Example 8")
360
+ ![Example 9](demo/doc/screenshots/bootstrap/readme/09_example.png "Example 9")
322
361
  ```erb
323
362
  <%= f.password_field :password, help: "Must be at least 6 characters long" %>
324
363
  ```
@@ -363,7 +402,7 @@ option or turn them off completely by passing `help: false`.
363
402
 
364
403
  You can pass `prepend` and/or `append` options to input fields:
365
404
 
366
- ![Example 9](demo/doc/screenshots/bootstrap/readme/09_example.png "Example 9")
405
+ ![Example 10](demo/doc/screenshots/bootstrap/readme/10_example.png "Example 10")
367
406
  ```erb
368
407
  <%= f.text_field :price, prepend: "$", append: ".00" %>
369
408
  ```
@@ -383,9 +422,10 @@ This generates:
383
422
 
384
423
  If you want to attach multiple items to the input, pass them as an array:
385
424
 
386
- ![Example 10](demo/doc/screenshots/bootstrap/readme/10_example.png "Example 10")
425
+ ![Example 11](demo/doc/screenshots/bootstrap/readme/11_example.png "Example 11")
387
426
  ```erb
388
- <%= f.text_field :price, prepend: ['Net', '$'], append: ['.00', 'per day'] %>
427
+ <% icon = capture do %><i class="bi bi-currency-dollar"></i><% end %>
428
+ <%= f.text_field :price, prepend: ['Net', icon], append: ['.00', 'per day'] %>
389
429
  ```
390
430
 
391
431
  This generates:
@@ -395,7 +435,10 @@ This generates:
395
435
  <label class="form-label" for="user_price">Price</label>
396
436
  <div class="input-group">
397
437
  <span class="input-group-text">Net</span>
398
- <span class="input-group-text">$</span>
438
+ <span class="input-group-text">
439
+ <i class="bi bi-currency-dollar">
440
+ </i>
441
+ </span>
399
442
  <input class="form-control" id="user_price" name="user[price]" type="text">
400
443
  <span class="input-group-text">.00</span>
401
444
  <span class="input-group-text">per day</span>
@@ -406,7 +449,7 @@ This generates:
406
449
  You can also prepend and append buttons. Note: The buttons must contain the
407
450
  `btn` class to generate the correct markup.
408
451
 
409
- ![Example 11](demo/doc/screenshots/bootstrap/readme/11_example.png "Example 11")
452
+ ![Example 12](demo/doc/screenshots/bootstrap/readme/12_example.png "Example 12")
410
453
  ```erb
411
454
  <%= f.text_field :search, append: link_to("Go", "#", class: "btn btn-secondary") %>
412
455
  ```
@@ -425,7 +468,7 @@ This generates:
425
468
 
426
469
  To add a class to the input group wrapper, use the `:input_group_class` option.
427
470
 
428
- ![Example 12](demo/doc/screenshots/bootstrap/readme/12_example.png "Example 12")
471
+ ![Example 13](demo/doc/screenshots/bootstrap/readme/13_example.png "Example 13")
429
472
  ```erb
430
473
  <%= f.email_field :email, append: f.primary('Subscribe'), input_group_class: 'input-group-lg' %>
431
474
  ```
@@ -436,7 +479,7 @@ This generates:
436
479
  <div class="mb-3">
437
480
  <label class="form-label required" for="user_email">Email</label>
438
481
  <div class="input-group input-group-lg">
439
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
482
+ <input class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
440
483
  <input class="btn btn-primary" data-disable-with="Subscribe" name="commit" type="submit" value="Subscribe">
441
484
  </div>
442
485
  </div>
@@ -448,7 +491,7 @@ Bootstrap mark-up dictates that most input field types have the label and input
448
491
 
449
492
  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.
450
493
 
451
- ![Example 13](demo/doc/screenshots/bootstrap/readme/13_example.png "Example 13")
494
+ ![Example 14](demo/doc/screenshots/bootstrap/readme/14_example.png "Example 14")
452
495
  ```erb
453
496
  <%= f.text_field :name, wrapper: { class: 'mb-3 has-warning', data: { foo: 'bar' } } %>
454
497
  ```
@@ -464,7 +507,7 @@ This generates:
464
507
 
465
508
  Which produces the following output:
466
509
 
467
- ![Example 14](demo/doc/screenshots/bootstrap/readme/14_example.png "Example 14")
510
+ ![Example 15](demo/doc/screenshots/bootstrap/readme/15_example.png "Example 15")
468
511
  ```erb
469
512
  <div class="mb-3 has-warning" data-foo="bar">
470
513
  <label class="form-label form-control-label" for="user_name">Id</label>
@@ -490,7 +533,7 @@ If you don't want any class on the form group div, you can set it to `false`: `w
490
533
 
491
534
  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:
492
535
 
493
- ![Example 15](demo/doc/screenshots/bootstrap/readme/15_example.png "Example 15")
536
+ ![Example 16](demo/doc/screenshots/bootstrap/readme/16_example.png "Example 16")
494
537
  ```erb
495
538
  <%= f.form_group :user do %>
496
539
  <%= f.email_field :email, wrapper: false %>
@@ -501,7 +544,7 @@ Generated HTML:
501
544
 
502
545
  ```html
503
546
  <div class="mb-3">
504
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
547
+ <input class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
505
548
  </div>
506
549
  ```
507
550
 
@@ -511,7 +554,7 @@ Note that Bootstrap relies on the form group div to correctly format most fields
511
554
 
512
555
  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:
513
556
 
514
- ![Example 16](demo/doc/screenshots/bootstrap/readme/16_example.png "Example 16")
557
+ ![Example 17](demo/doc/screenshots/bootstrap/readme/17_example.png "Example 17")
515
558
  ```erb
516
559
  <%= f.select :product, [["Apple", 1], ["Grape", 2]], { label: "Choose your favorite fruit:", wrapper: { class: 'has-warning', data: { foo: 'bar' } } }, { class: "selectpicker" } %>
517
560
  ```
@@ -534,7 +577,7 @@ Checkboxes and radios should be placed inside of a `form_group` to render
534
577
  properly. The following example ensures that the entire form group will display
535
578
  an error if an associated validations fails:
536
579
 
537
- ![Example 17](demo/doc/screenshots/bootstrap/readme/17_example.png "Example 17")
580
+ ![Example 18](demo/doc/screenshots/bootstrap/readme/18_example.png "Example 18")
538
581
  ```erb
539
582
  <%= f.form_group :skill_level, label: { text: "Skill" }, help: "Optional Help Text" do %>
540
583
  <%= f.radio_button :skill_level, 0, label: "Novice", checked: true %>
@@ -577,7 +620,7 @@ This generates:
577
620
 
578
621
  You can also create a checkbox using a block:
579
622
 
580
- ![Example 18](demo/doc/screenshots/bootstrap/readme/18_example.png "Example 18")
623
+ ![Example 19](demo/doc/screenshots/bootstrap/readme/19_example.png "Example 19")
581
624
  ```erb
582
625
  <%= f.form_group :terms, label: { text: "Optional Label" } do %>
583
626
  <%= f.check_box :terms do %>
@@ -603,7 +646,7 @@ This generates:
603
646
 
604
647
  To display checkboxes and radios inline, pass the `inline: true` option:
605
648
 
606
- ![Example 19](demo/doc/screenshots/bootstrap/readme/19_example.png "Example 19")
649
+ ![Example 20](demo/doc/screenshots/bootstrap/readme/20_example.png "Example 20")
607
650
  ```erb
608
651
  <%= f.form_group :skill_level, label: { text: "Skill" } do %>
609
652
  <%= f.radio_button :skill_level, 0, label: "Novice", inline: true %>
@@ -634,7 +677,7 @@ This generates:
634
677
 
635
678
  Check boxes and radio buttons are wrapped in a `div.form-check`. You can add classes to this `div` with the `:wrapper_class` option:
636
679
 
637
- ![Example 20](demo/doc/screenshots/bootstrap/readme/20_example.png "Example 20")
680
+ ![Example 21](demo/doc/screenshots/bootstrap/readme/21_example.png "Example 21")
638
681
  ```erb
639
682
  <%= f.radio_button :skill_level, 0, label: "Novice", inline: true, wrapper_class: "w-auto" %>
640
683
  ```
@@ -650,7 +693,7 @@ This generates:
650
693
 
651
694
  You can also add a style to the tag using the `wrapper` option:
652
695
 
653
- ![Example 21](demo/doc/screenshots/bootstrap/readme/21_example.png "Example 21")
696
+ ![Example 22](demo/doc/screenshots/bootstrap/readme/22_example.png "Example 22")
654
697
  ```erb
655
698
  <%= f.check_box :skilled, inline: true, wrapper: {style: "color: green"} %>
656
699
  <%= f.radio_button :skill_level, 0, label: "Novice", inline: true, wrapper: {class: 'w-auto', style: "color: red"} %>
@@ -674,7 +717,7 @@ This generates:
674
717
 
675
718
  To render checkboxes as switches with Bootstrap 4.2+, use `switch: true`:
676
719
 
677
- ![Example 22](demo/doc/screenshots/bootstrap/readme/22_example.png "Example 22")
720
+ ![Example 23](demo/doc/screenshots/bootstrap/readme/23_example.png "Example 23")
678
721
  ```erb
679
722
  <%= f.check_box :remember_me, switch: true %>
680
723
  ```
@@ -694,7 +737,7 @@ This generates:
694
737
  `bootstrap_form` also provides helpers that automatically create the
695
738
  `form_group` and the `radio_button`s or `check_box`es for you:
696
739
 
697
- ![Example 23](demo/doc/screenshots/bootstrap/readme/23_example.png "Example 23")
740
+ ![Example 24](demo/doc/screenshots/bootstrap/readme/24_example.png "Example 24")
698
741
  ```erb
699
742
  <%= f.collection_radio_buttons :skill_level, Skill.all, :id, :name %>
700
743
  <%= f.collection_check_boxes :skills, Skill.all, :id, :name %>
@@ -714,7 +757,7 @@ This generates:
714
757
  <label class="form-check-label" for="user_skill_level_2">Farming</label>
715
758
  </div>
716
759
  </div>
717
- <input autocomplete="off" id="user_skills" multiple name="user[skills][]" type="hidden" value="">
760
+ <input autocomplete="off" id="user_skills" name="user[skills][]" type="hidden" value="">
718
761
  <div class="mb-3">
719
762
  <label class="form-label" for="user_skills">Skills</label>
720
763
  <div class="form-check">
@@ -737,11 +780,38 @@ Collection methods accept these options:
737
780
  * `:help`: Add a help span to the `form_group`
738
781
  * Other options will be forwarded to the `radio_button`/`check_box` method
739
782
 
783
+
784
+ To add `data-` attributes to a collection of radio buttons, map your models to an array and add a hash:
785
+
786
+ ![Example 25](demo/doc/screenshots/bootstrap/readme/25_example.png "Example 25")
787
+ ```erb
788
+ <%# Use the :first and :second elements of the array to be the value and label respectively %>
789
+ <%- choices = @collection.map { |addr| [ addr.id, addr.street, { 'data-zip-code': addr.zip_code } ] } -%>
790
+
791
+ <%= f.collection_radio_buttons :misc, choices, :first, :second %>
792
+ ```
793
+
794
+ This generates:
795
+
796
+ ```html
797
+ <div class="mb-3">
798
+ <label class="form-label" for="user_misc">Misc</label>
799
+ <div class="form-check">
800
+ <input class="form-check-input" id="user_misc_1" name="user[misc]" type="radio" value="1">
801
+ <label class="form-check-label" for="user_misc_1">Foo</label>
802
+ </div>
803
+ <div class="form-check">
804
+ <input class="form-check-input" id="user_misc_2" name="user[misc]" type="radio" value="2">
805
+ <label class="form-check-label" for="user_misc_2">Bar</label>
806
+ </div>
807
+ </div>
808
+ ```
809
+
740
810
  ## Range Controls
741
811
 
742
812
  You can create a range control like this:
743
813
 
744
- ![Example 24](demo/doc/screenshots/bootstrap/readme/24_example.png "Example 24")
814
+ ![Example 26](demo/doc/screenshots/bootstrap/readme/26_example.png "Example 26")
745
815
  ```erb
746
816
  <%= f.range_field :excellence %>
747
817
  ```
@@ -759,7 +829,7 @@ This generates:
759
829
 
760
830
  You can create a static control like this:
761
831
 
762
- ![Example 25](demo/doc/screenshots/bootstrap/readme/25_example.png "Example 25")
832
+ ![Example 27](demo/doc/screenshots/bootstrap/readme/27_example.png "Example 27")
763
833
  ```erb
764
834
  <%= f.static_control :email %>
765
835
  ```
@@ -769,13 +839,13 @@ This generates:
769
839
  ```html
770
840
  <div class="mb-3">
771
841
  <label class="form-label required" for="user_email">Email</label>
772
- <input aria-required="true" class="form-control-plaintext" id="user_email" name="user[email]" readonly required="required" type="text" value="steve@example.com">
842
+ <input class="form-control-plaintext" id="user_email" name="user[email]" readonly required="required" type="text" value="steve@example.com">
773
843
  </div>
774
844
  ```
775
845
 
776
846
  Here's the output for a horizontal layout:
777
847
 
778
- ![Example 26](demo/doc/screenshots/bootstrap/readme/26_example.png "Example 26")
848
+ ![Example 28](demo/doc/screenshots/bootstrap/readme/28_example.png "Example 28")
779
849
  ```erb
780
850
  <%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
781
851
  <%= f.static_control :email %>
@@ -787,9 +857,9 @@ This generates:
787
857
  ```html
788
858
  <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
789
859
  <div class="mb-3 row">
790
- <label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
860
+ <label class="col-form-label col-sm-2 required" for="user_email">Email</label>
791
861
  <div class="col-sm-10">
792
- <input aria-required="true" class="form-control-plaintext" id="user_email" name="user[email]" readonly required="required" type="text" value="steve@example.com">
862
+ <input class="form-control-plaintext" id="user_email" name="user[email]" readonly required="required" type="text" value="steve@example.com">
793
863
  </div>
794
864
  </div>
795
865
  </form>
@@ -797,7 +867,7 @@ This generates:
797
867
 
798
868
  You can also create a static control that isn't based on a model attribute:
799
869
 
800
- ![Example 27](demo/doc/screenshots/bootstrap/readme/27_example.png "Example 27")
870
+ ![Example 29](demo/doc/screenshots/bootstrap/readme/29_example.png "Example 29")
801
871
  ```erb
802
872
  <%= f.static_control :field_name, label: "Custom Static Control", value: "Content Here" %>
803
873
  ```
@@ -815,7 +885,7 @@ This generates:
815
885
 
816
886
  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:
817
887
 
818
- ![Example 28](demo/doc/screenshots/bootstrap/readme/28_example.png "Example 28")
888
+ ![Example 30](demo/doc/screenshots/bootstrap/readme/30_example.png "Example 30")
819
889
  ```erb
820
890
  <%= f.static_control label: "Custom Static Control", value: "Content Here", name: nil %>
821
891
  ```
@@ -842,14 +912,14 @@ The multiple selects that the date and time helpers (`date_select`,
842
912
  `time_select`, `datetime_select`) generate are wrapped inside a
843
913
  `div.rails-bootstrap-forms-[date|time|datetime]-select` tag. This is because
844
914
  Bootstrap automatically styles our controls as `block`s. This wrapper fixes
845
- this defining these selects as `inline-block` and a width of `auto`.
915
+ this by defining these selects as `inline-block` and a width of `auto`.
846
916
 
847
917
  ## Submit Buttons
848
918
 
849
919
  The `btn btn-secondary` CSS classes are automatically added to your submit
850
920
  buttons.
851
921
 
852
- ![Example 29](demo/doc/screenshots/bootstrap/readme/29_example.png "Example 29")
922
+ ![Example 31](demo/doc/screenshots/bootstrap/readme/31_example.png "Example 31")
853
923
  ```erb
854
924
  <%= f.submit %>
855
925
  ```
@@ -863,7 +933,7 @@ This generates:
863
933
  You can also use the `primary` helper, which adds `btn btn-primary` to your
864
934
  submit button:
865
935
 
866
- ![Example 30](demo/doc/screenshots/bootstrap/readme/30_example.png "Example 30")
936
+ ![Example 32](demo/doc/screenshots/bootstrap/readme/32_example.png "Example 32")
867
937
  ```erb
868
938
  <%= f.primary "Optional Label" %>
869
939
  ```
@@ -876,7 +946,7 @@ This generates:
876
946
 
877
947
  You can specify your own classes like this:
878
948
 
879
- ![Example 31](demo/doc/screenshots/bootstrap/readme/31_example.png "Example 31")
949
+ ![Example 33](demo/doc/screenshots/bootstrap/readme/33_example.png "Example 33")
880
950
  ```erb
881
951
  <%= f.submit "Log In", class: "btn btn-success" %>
882
952
  ```
@@ -892,23 +962,23 @@ it will be rendered as an HTML button, instead of an input tag. This allows you
892
962
  to specify HTML content and styling for your buttons (such as adding
893
963
  illustrative icons to them). For example, the following statements
894
964
 
895
- ![Example 32](demo/doc/screenshots/bootstrap/readme/32_example.png "Example 32")
965
+ ![Example 34](demo/doc/screenshots/bootstrap/readme/34_example.png "Example 34")
896
966
  ```erb
897
- <%= f.primary "Save changes <span class='fa fa-save'></span>".html_safe, render_as_button: true %>
967
+ <%= f.primary "Save changes <span class='bi bi-save'></span>".html_safe, render_as_button: true %>
898
968
 
899
969
  <%= f.primary do
900
970
  concat 'Save changes '
901
- concat content_tag(:span, nil, class: 'fa fa-save')
971
+ concat content_tag(:span, nil, class: 'bi bi-save')
902
972
  end %>
903
973
  ```
904
974
 
905
975
  This generates:
906
976
 
907
977
  ```html
908
- <button class="btn btn-primary" name="button" type="submit">Save changes <span class="fa fa-save">
978
+ <button class="btn btn-primary" name="button" type="submit">Save changes <span class="bi bi-save">
909
979
  </span>
910
980
  </button>
911
- <button class="btn btn-primary" name="button" type="submit">Save changes <span class="fa fa-save">
981
+ <button class="btn btn-primary" name="button" type="submit">Save changes <span class="bi bi-save">
912
982
  </span>
913
983
  </button>
914
984
  ```
@@ -916,7 +986,7 @@ This generates:
916
986
  are equivalent, and each of them both be rendered as:
917
987
 
918
988
  ```html
919
- <button name="button" type="submit" class="btn btn-primary">Save changes <span class="fa fa-save"></span></button>
989
+ <button name="button" type="submit" class="btn btn-primary">Save changes <span class="bi bi-save"></span></button>
920
990
  ```
921
991
 
922
992
  If you wish to add additional CSS classes to your button, while keeping the
@@ -926,7 +996,7 @@ Bootstrap classes), or for element targeting via CSS classes.
926
996
  Be aware, however, that using the `class` option will discard any extra classes
927
997
  you add. As an example, the following button declarations
928
998
 
929
- ![Example 33](demo/doc/screenshots/bootstrap/readme/33_example.png "Example 33")
999
+ ![Example 35](demo/doc/screenshots/bootstrap/readme/35_example.png "Example 35")
930
1000
  ```erb
931
1001
  <%= f.primary "My Nice Button", extra_class: 'my-button' %>
932
1002
 
@@ -944,7 +1014,7 @@ will be rendered as
944
1014
 
945
1015
  ## Rich Text Areas AKA Trix Editor
946
1016
 
947
- ![Example 34](demo/doc/screenshots/bootstrap/readme/34_example.png "Example 34")
1017
+ ![Example 36](demo/doc/screenshots/bootstrap/readme/36_example.png "Example 36")
948
1018
  ```erb
949
1019
  <%= f.rich_text_area(:life_story) %>
950
1020
  ```
@@ -1012,7 +1082,7 @@ The `hidden_field` helper in `bootstrap_form` calls the Rails helper directly, a
1012
1082
  If you want to use the original Rails form helpers for a particular field,
1013
1083
  append `_without_bootstrap` to the helper:
1014
1084
 
1015
- ![Example 35](demo/doc/screenshots/bootstrap/readme/35_example.png "Example 35")
1085
+ ![Example 37](demo/doc/screenshots/bootstrap/readme/37_example.png "Example 37")
1016
1086
  ```erb
1017
1087
  <%= f.text_field_without_bootstrap :email %>
1018
1088
  ```
@@ -1034,7 +1104,7 @@ To use an inline-layout form, use the `layout: :inline` option. To hide labels,
1034
1104
  use the `hide_label: true` option, which keeps your labels accessible to those
1035
1105
  using screen readers.
1036
1106
 
1037
- ![Example 36](demo/doc/screenshots/bootstrap/readme/36_example.png "Example 36")
1107
+ ![Example 38](demo/doc/screenshots/bootstrap/readme/38_example.png "Example 38")
1038
1108
  ```erb
1039
1109
  <%= bootstrap_form_for(@user, layout: :inline) do |f| %>
1040
1110
  <%= f.email_field :email, hide_label: true %>
@@ -1049,17 +1119,19 @@ This generates:
1049
1119
  ```html
1050
1120
  <form accept-charset="UTF-8" action="/users" class="new_user row row-cols-auto g-3 align-items-center" id="new_user" method="post">
1051
1121
  <div class="col">
1052
- <label class="form-label visually-hidden me-sm-2 required" for="user_email">Email</label>
1053
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1122
+ <label class="visually-hidden required" for="user_email">Email</label>
1123
+ <input class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1054
1124
  </div>
1055
1125
  <div class="col">
1056
- <label class="form-label visually-hidden me-sm-2" for="user_password">Password</label>
1126
+ <label class="visually-hidden" for="user_password">Password</label>
1057
1127
  <input class="form-control" id="user_password" name="user[password]" type="password">
1058
1128
  </div>
1059
- <div class="form-check form-check-inline mb-3">
1060
- <input autocomplete="off" name="user[remember_me]" type="hidden" value="0">
1061
- <input class="form-check-input" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1">
1062
- <label class="form-check-label" for="user_remember_me">Remember me</label>
1129
+ <div class="col">
1130
+ <div class="form-check form-check-inline">
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>
1063
1135
  </div>
1064
1136
  <div class="col">
1065
1137
  <input class="btn btn-secondary" data-disable-with="Create User" name="commit" type="submit" value="Create User">
@@ -1069,7 +1141,7 @@ This generates:
1069
1141
 
1070
1142
  To skip label rendering at all, use `skip_label: true` option.
1071
1143
 
1072
- ![Example 37](demo/doc/screenshots/bootstrap/readme/37_example.png "Example 37")
1144
+ ![Example 39](demo/doc/screenshots/bootstrap/readme/39_example.png "Example 39")
1073
1145
  ```erb
1074
1146
  <%= f.password_field :password, skip_label: true %>
1075
1147
  ```
@@ -1088,17 +1160,15 @@ To use a horizontal-layout form with labels to the left of the control, use the
1088
1160
  `layout: :horizontal` option. You should specify both `label_col` and
1089
1161
  `control_col` css classes as well (they default to `col-sm-2` and `col-sm-10`).
1090
1162
 
1091
- In the example below, the checkbox and submit button have been wrapped in a
1092
- `form_group` to keep them properly aligned.
1163
+ In the example below, the submit button has been wrapped in a `form_group` to
1164
+ keep it properly aligned.
1093
1165
 
1094
- ![Example 38](demo/doc/screenshots/bootstrap/readme/38_example.png "Example 38")
1166
+ ![Example 40](demo/doc/screenshots/bootstrap/readme/40_example.png "Example 40")
1095
1167
  ```erb
1096
1168
  <%= bootstrap_form_for(@user, layout: :horizontal, label_col: "col-sm-2", control_col: "col-sm-10") do |f| %>
1097
1169
  <%= f.email_field :email %>
1098
1170
  <%= f.password_field :password %>
1099
- <%= f.form_group do %>
1100
- <%= f.check_box :remember_me %>
1101
- <% end %>
1171
+ <%= f.check_box :remember_me %>
1102
1172
  <%= f.form_group do %>
1103
1173
  <%= f.submit %>
1104
1174
  <% end %>
@@ -1110,13 +1180,13 @@ This generates:
1110
1180
  ```html
1111
1181
  <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1112
1182
  <div class="mb-3 row">
1113
- <label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
1183
+ <label class="col-form-label col-sm-2 required" for="user_email">Email</label>
1114
1184
  <div class="col-sm-10">
1115
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1185
+ <input class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1116
1186
  </div>
1117
1187
  </div>
1118
1188
  <div class="mb-3 row">
1119
- <label class="form-label col-form-label col-sm-2" for="user_password">Password</label>
1189
+ <label class="col-form-label col-sm-2" for="user_password">Password</label>
1120
1190
  <div class="col-sm-10">
1121
1191
  <input class="form-control" id="user_password" name="user[password]" type="password">
1122
1192
  </div>
@@ -1140,11 +1210,12 @@ This generates:
1140
1210
 
1141
1211
  The `label_col` and `control_col` css classes can also be changed per control:
1142
1212
 
1143
- ![Example 39](demo/doc/screenshots/bootstrap/readme/39_example.png "Example 39")
1213
+ ![Example 41](demo/doc/screenshots/bootstrap/readme/41_example.png "Example 41")
1144
1214
  ```erb
1145
1215
  <%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
1146
1216
  <%= f.email_field :email %>
1147
- <%= f.text_field :age, control_col: "col-sm-3" %>
1217
+ <%= f.text_field :age, label_col: "col-sm-3", control_col: "col-sm-3" %>
1218
+ <%= f.check_box :terms, label_col: "", control_col: "col-sm-11" %>
1148
1219
  <%= f.form_group do %>
1149
1220
  <%= f.submit %>
1150
1221
  <% end %>
@@ -1156,17 +1227,26 @@ This generates:
1156
1227
  ```html
1157
1228
  <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1158
1229
  <div class="mb-3 row">
1159
- <label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
1230
+ <label class="col-form-label col-sm-2 required" for="user_email">Email</label>
1160
1231
  <div class="col-sm-10">
1161
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1232
+ <input class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1162
1233
  </div>
1163
1234
  </div>
1164
1235
  <div class="mb-3 row">
1165
- <label class="form-label col-form-label col-sm-2" for="user_age">Age</label>
1236
+ <label class="col-form-label col-sm-3" for="user_age">Age</label>
1166
1237
  <div class="col-sm-3">
1167
1238
  <input class="form-control" id="user_age" name="user[age]" type="text" value="42">
1168
1239
  </div>
1169
1240
  </div>
1241
+ <div class="mb-3 row">
1242
+ <div class="col-sm-10">
1243
+ <div class="form-check">
1244
+ <input autocomplete="off" name="user[terms]" type="hidden" value="0">
1245
+ <input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1">
1246
+ <label class="form-check-label" for="user_terms">Terms</label>
1247
+ </div>
1248
+ </div>
1249
+ </div>
1170
1250
  <div class="mb-3 row">
1171
1251
  <div class="col-sm-10 offset-sm-2">
1172
1252
  <input class="btn btn-secondary" data-disable-with="Create User" name="commit" type="submit" value="Create User">
@@ -1188,7 +1268,7 @@ module BootstrapForm
1188
1268
  'col-sm-8'
1189
1269
  end
1190
1270
  def default_layout
1191
- # :default, :horizontal or :inline
1271
+ # :vertical, :horizontal or :inline
1192
1272
  :horizontal
1193
1273
  end
1194
1274
  end
@@ -1197,7 +1277,7 @@ end
1197
1277
 
1198
1278
  Control col wrapper class can be modified with `add_control_col_class`. This option will preserve column definition:
1199
1279
 
1200
- ![Example 40](demo/doc/screenshots/bootstrap/readme/40_example.png "Example 40")
1280
+ ![Example 42](demo/doc/screenshots/bootstrap/readme/42_example.png "Example 42")
1201
1281
  ```erb
1202
1282
  <%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
1203
1283
  <%= f.email_field :email %>
@@ -1213,13 +1293,13 @@ This generates:
1213
1293
  ```html
1214
1294
  <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1215
1295
  <div class="mb-3 row">
1216
- <label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
1296
+ <label class="col-form-label col-sm-2 required" for="user_email">Email</label>
1217
1297
  <div class="col-sm-10">
1218
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1298
+ <input class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1219
1299
  </div>
1220
1300
  </div>
1221
1301
  <div class="mb-3 row">
1222
- <label class="form-label col-form-label col-sm-2" for="user_age">Age</label>
1302
+ <label class="col-form-label col-sm-2" for="user_age">Age</label>
1223
1303
  <div class="col-sm-10 additional-control-col-class">
1224
1304
  <input class="form-control" id="user_age" name="user[age]" type="text" value="42">
1225
1305
  </div>
@@ -1236,15 +1316,16 @@ This generates:
1236
1316
 
1237
1317
  The form-level `layout` can be overridden per field, unless the form-level layout was `inline`:
1238
1318
 
1239
- ![Example 41](demo/doc/screenshots/bootstrap/readme/41_example.png "Example 41")
1319
+ ![Example 43](demo/doc/screenshots/bootstrap/readme/43_example.png "Example 43")
1240
1320
  ```erb
1241
1321
  <%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
1242
1322
  <%= f.email_field :email %>
1243
- <%= f.text_field :feet, layout: :default %>
1244
- <%= f.text_field :inches, layout: :default %>
1245
- <%= f.form_group do %>
1246
- <%= f.submit %>
1247
- <% end %>
1323
+ <div class="row">
1324
+ <div class="col"><%= f.text_field :feet, layout: :vertical %></div>
1325
+ <div class="col"><%= f.text_field :inches, layout: :vertical %></div>
1326
+ </div>
1327
+ <%= f.check_box :terms, layout: :vertical %>
1328
+ <%= f.submit %>
1248
1329
  <% end %>
1249
1330
  ```
1250
1331
 
@@ -1253,70 +1334,44 @@ This generates:
1253
1334
  ```html
1254
1335
  <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1255
1336
  <div class="mb-3 row">
1256
- <label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
1337
+ <label class="col-form-label col-sm-2 required" for="user_email">Email</label>
1257
1338
  <div class="col-sm-10">
1258
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1339
+ <input class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1259
1340
  </div>
1260
1341
  </div>
1261
- <div class="mb-3">
1262
- <label class="form-label" for="user_feet">Feet</label>
1263
- <input class="form-control" id="user_feet" name="user[feet]" type="text" value="5">
1342
+ <div class="row">
1343
+ <div class="col">
1344
+ <div class="mb-3">
1345
+ <label class="form-label" for="user_feet">Feet</label>
1346
+ <input class="form-control" id="user_feet" name="user[feet]" type="text" value="5">
1347
+ </div>
1348
+ </div>
1349
+ <div class="col">
1350
+ <div class="mb-3">
1351
+ <label class="form-label" for="user_inches">Inches</label>
1352
+ <input class="form-control" id="user_inches" name="user[inches]" type="text" value="7">
1353
+ </div>
1354
+ </div>
1264
1355
  </div>
1265
1356
  <div class="mb-3">
1266
- <label class="form-label" for="user_inches">Inches</label>
1267
- <input class="form-control" id="user_inches" name="user[inches]" type="text" value="7">
1268
- </div>
1269
- <div class="mb-3 row">
1270
- <div class="col-sm-10 offset-sm-2">
1271
- <input class="btn btn-secondary" data-disable-with="Create User" name="commit" type="submit" value="Create User">
1357
+ <div class="form-check">
1358
+ <input autocomplete="off" name="user[terms]" type="hidden" value="0">
1359
+ <input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1">
1360
+ <label class="form-check-label" for="user_terms">Terms</label>
1272
1361
  </div>
1273
1362
  </div>
1363
+ <input class="btn btn-secondary" data-disable-with="Create User" name="commit" type="submit" value="Create User">
1274
1364
  </form>
1275
1365
  ```
1276
1366
 
1277
1367
  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.
1278
1368
 
1279
- ### Custom Form Element Styles
1280
-
1281
- 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:
1282
-
1283
- ![Example 42](demo/doc/screenshots/bootstrap/readme/42_example.png "Example 42")
1284
- ```erb
1285
- <%= bootstrap_form_for(@user) do |f| %>
1286
- <%= f.email_field :email %>
1287
- <%= f.password_field :password %>
1288
- <%= f.check_box :remember_me, custom: true %>
1289
- <%= f.submit "Log In" %>
1290
- <% end %>
1291
- ```
1292
-
1293
- This generates:
1294
-
1295
- ```html
1296
- <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1297
- <div class="mb-3">
1298
- <label class="form-label required" for="user_email">Email</label>
1299
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1300
- </div>
1301
- <div class="mb-3">
1302
- <label class="form-label" for="user_password">Password</label>
1303
- <input class="form-control" id="user_password" name="user[password]" type="password">
1304
- </div>
1305
- <div class="form-check mb-3">
1306
- <input autocomplete="off" name="user[remember_me]" type="hidden" value="0">
1307
- <input class="form-check-input" custom="true" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1">
1308
- <label class="form-check-label" for="user_remember_me">Remember me</label>
1309
- </div>
1310
- <input class="btn btn-secondary" data-disable-with="Log In" name="commit" type="submit" value="Log In">
1311
- </form>
1312
- ```
1313
-
1314
1369
  ### Floating Labels
1315
1370
 
1316
1371
  The `floating` option can be used to enable Bootstrap 5's floating labels. This option is supported on text fields
1317
1372
  and dropdowns. Here's an example:
1318
1373
 
1319
- ![Example 43](demo/doc/screenshots/bootstrap/readme/43_example.png "Example 43")
1374
+ ![Example 44](demo/doc/screenshots/bootstrap/readme/44_example.png "Example 44")
1320
1375
  ```erb
1321
1376
  <%= bootstrap_form_for(@user) do |f| %>
1322
1377
  <%= f.email_field :email, floating: true %>
@@ -1332,7 +1387,7 @@ This generates:
1332
1387
  ```html
1333
1388
  <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1334
1389
  <div class="mb-3 form-floating">
1335
- <input aria-required="true" class="form-control" id="user_email" name="user[email]" placeholder="Email" required="required" type="email" value="steve@example.com">
1390
+ <input class="form-control" id="user_email" name="user[email]" placeholder="Email" required="required" type="email" value="steve@example.com">
1336
1391
  <label class="form-label required" for="user_email">Email</label>
1337
1392
  </div>
1338
1393
  <div class="mb-3 form-floating">
@@ -1364,10 +1419,15 @@ Rails normally wraps fields with validation errors in a `div.field_with_errors`,
1364
1419
  By default, fields that have validation errors will be outlined in red and the
1365
1420
  error will be displayed below the field. Here's an example:
1366
1421
 
1367
- ![Example 44](demo/doc/screenshots/bootstrap/readme/44_example.png "Example 44")
1422
+ ![Example 45](demo/doc/screenshots/bootstrap/readme/45_example.png "Example 45")
1368
1423
  ```erb
1369
1424
  <%= bootstrap_form_for(@user_with_error) do |f| %>
1370
1425
  <%= f.email_field :email %>
1426
+ <%= f.collection_radio_buttons :misc, Skill.all, :id, :name %>
1427
+ <%= f.collection_check_boxes :preferences, [[1, 'Good'], [2, 'Bad']], :first, :second %>
1428
+ <%= f.fields_for :address do |af| %>
1429
+ <%= af.text_field :street %>
1430
+ <% end %>
1371
1431
  <% end %>
1372
1432
  ```
1373
1433
 
@@ -1377,7 +1437,37 @@ Generated HTML:
1377
1437
  <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1378
1438
  <div class="mb-3">
1379
1439
  <label class="form-label required" for="user_email">Email</label>
1380
- <input aria-required="true" class="form-control is-invalid" id="user_email" name="user[email]" required="required" type="email" value="steve.example.com">
1440
+ <input class="form-control is-invalid" id="user_email" name="user[email]" required="required" type="email" value="steve.example.com">
1441
+ <div class="invalid-feedback">is invalid</div>
1442
+ </div>
1443
+ <div class="mb-3">
1444
+ <label class="form-label" for="user_misc">Misc</label>
1445
+ <div class="form-check">
1446
+ <input checked class="form-check-input is-invalid" id="user_misc_1" name="user[misc]" type="radio" value="1">
1447
+ <label class="form-check-label" for="user_misc_1">Mind reading</label>
1448
+ </div>
1449
+ <div class="form-check">
1450
+ <input class="form-check-input is-invalid" id="user_misc_2" name="user[misc]" type="radio" value="2">
1451
+ <label class="form-check-label" for="user_misc_2">Farming</label>
1452
+ <div class="invalid-feedback">is invalid</div>
1453
+ </div>
1454
+ </div>
1455
+ <input autocomplete="off" id="user_preferences" name="user[preferences][]" type="hidden" value="">
1456
+ <div class="mb-3">
1457
+ <label class="form-label" for="user_preferences">Preferences</label>
1458
+ <div class="form-check">
1459
+ <input checked class="form-check-input is-invalid" id="user_preferences_1" name="user[preferences][]" type="checkbox" value="1">
1460
+ <label class="form-check-label" for="user_preferences_1">Good</label>
1461
+ </div>
1462
+ <div class="form-check">
1463
+ <input class="form-check-input is-invalid" id="user_preferences_2" name="user[preferences][]" type="checkbox" value="2">
1464
+ <label class="form-check-label" for="user_preferences_2">Bad</label>
1465
+ <div class="invalid-feedback">is invalid</div>
1466
+ </div>
1467
+ </div>
1468
+ <div class="mb-3">
1469
+ <label class="form-label" for="user_address_attributes_street">Street</label>
1470
+ <input class="form-control is-invalid" id="user_address_attributes_street" name="user[address_attributes][street]" type="text" value="Bar">
1381
1471
  <div class="invalid-feedback">is invalid</div>
1382
1472
  </div>
1383
1473
  </form>
@@ -1396,7 +1486,7 @@ You can turn off inline errors for the entire form like this:
1396
1486
  You can also display validation errors in the field's label; just turn
1397
1487
  on the `:label_errors` option. Here's an example:
1398
1488
 
1399
- ![Example 45](demo/doc/screenshots/bootstrap/readme/45_example.png "Example 45")
1489
+ ![Example 46](demo/doc/screenshots/bootstrap/readme/46_example.png "Example 46")
1400
1490
  ```erb
1401
1491
  <%= bootstrap_form_for(@user_with_error, label_errors: true) do |f| %>
1402
1492
  <%= f.email_field :email %>
@@ -1409,7 +1499,7 @@ Generated HTML:
1409
1499
  <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1410
1500
  <div class="mb-3">
1411
1501
  <label class="form-label required text-danger" for="user_email">Email is invalid</label>
1412
- <input aria-required="true" class="form-control is-invalid" id="user_email" name="user[email]" required="required" type="email" value="steve.example.com">
1502
+ <input class="form-control is-invalid" id="user_email" name="user[email]" required="required" type="email" value="steve.example.com">
1413
1503
  </div>
1414
1504
  </form>
1415
1505
  ```
@@ -1429,7 +1519,7 @@ To display an error message with an error summary, you can use the
1429
1519
  `alert_message` helper. This won't output anything unless a model validation
1430
1520
  has failed.
1431
1521
 
1432
- ![Example 46](demo/doc/screenshots/bootstrap/readme/46_example.png "Example 46")
1522
+ ![Example 47](demo/doc/screenshots/bootstrap/readme/47_example.png "Example 47")
1433
1523
  ```erb
1434
1524
  <%= bootstrap_form_for @user_with_error do |f| %>
1435
1525
  <%= f.alert_message "Please fix the errors below." %>
@@ -1445,6 +1535,7 @@ Which outputs:
1445
1535
  <ul class="rails-bootstrap-forms-error-summary">
1446
1536
  <li>Email is invalid</li>
1447
1537
  <li>Misc is invalid</li>
1538
+ <li>Preferences is invalid</li>
1448
1539
  </ul>
1449
1540
  </div>
1450
1541
  </form>
@@ -1452,7 +1543,7 @@ Which outputs:
1452
1543
 
1453
1544
  You can turn off the error summary like this:
1454
1545
 
1455
- ![Example 47](demo/doc/screenshots/bootstrap/readme/47_example.png "Example 47")
1546
+ ![Example 48](demo/doc/screenshots/bootstrap/readme/48_example.png "Example 48")
1456
1547
  ```erb
1457
1548
  <%= bootstrap_form_for @user_with_error do |f| %>
1458
1549
  <%= f.alert_message "Please fix the errors below.", error_summary: false %>
@@ -1469,7 +1560,7 @@ This generates:
1469
1560
 
1470
1561
  To output a simple unordered list of errors, use the `error_summary` helper.
1471
1562
 
1472
- ![Example 48](demo/doc/screenshots/bootstrap/readme/48_example.png "Example 48")
1563
+ ![Example 49](demo/doc/screenshots/bootstrap/readme/49_example.png "Example 49")
1473
1564
  ```erb
1474
1565
  <%= bootstrap_form_for @user_with_error do |f| %>
1475
1566
  <%= f.error_summary %>
@@ -1483,6 +1574,7 @@ Which outputs:
1483
1574
  <ul class="rails-bootstrap-forms-error-summary">
1484
1575
  <li>Email is invalid</li>
1485
1576
  <li>Misc is invalid</li>
1577
+ <li>Preferences is invalid</li>
1486
1578
  </ul>
1487
1579
  </form>
1488
1580
  ```
@@ -1491,7 +1583,7 @@ Which outputs:
1491
1583
 
1492
1584
  If you want to display a custom inline error for a specific attribute not represented by a form field, use the `errors_on` helper.
1493
1585
 
1494
- ![Example 49](demo/doc/screenshots/bootstrap/readme/49_example.png "Example 49")
1586
+ ![Example 50](demo/doc/screenshots/bootstrap/readme/50_example.png "Example 50")
1495
1587
  ```erb
1496
1588
  <%= bootstrap_form_for @user_with_error do |f| %>
1497
1589
  <%= f.errors_on :email %>
@@ -1508,7 +1600,7 @@ Which outputs:
1508
1600
 
1509
1601
  You can hide the attribute name like this:
1510
1602
 
1511
- ![Example 50](demo/doc/screenshots/bootstrap/readme/50_example.png "Example 50")
1603
+ ![Example 51](demo/doc/screenshots/bootstrap/readme/51_example.png "Example 51")
1512
1604
  ```erb
1513
1605
  <%= bootstrap_form_for @user_with_error do |f| %>
1514
1606
  <%= f.errors_on :email, hide_attribute_name: true %>
@@ -1525,7 +1617,7 @@ Which outputs:
1525
1617
 
1526
1618
  You can also use a custom class for the wrapping div, like this:
1527
1619
 
1528
- ![Example 51](demo/doc/screenshots/bootstrap/readme/51_example.png "Example 51")
1620
+ ![Example 52](demo/doc/screenshots/bootstrap/readme/52_example.png "Example 52")
1529
1621
  ```erb
1530
1622
  <%= bootstrap_form_for @user_with_error do |f| %>
1531
1623
  <%= f.errors_on :email, custom_class: 'custom-error' %>
@@ -1560,7 +1652,7 @@ ActiveModel::Validations::PresenceValidator.
1560
1652
 
1561
1653
  In cases where this behaviour is undesirable, use the `required` option to force the class to be present or absent:
1562
1654
 
1563
- ![Example 52](demo/doc/screenshots/bootstrap/readme/52_example.png "Example 52")
1655
+ ![Example 53](demo/doc/screenshots/bootstrap/readme/53_example.png "Example 53")
1564
1656
  ```erb
1565
1657
  <%= f.password_field :login, label: "New Username", required: true %>
1566
1658
  <%= f.password_field :password, label: "New Password", required: false %>
@@ -1571,7 +1663,7 @@ This generates:
1571
1663
  ```html
1572
1664
  <div class="mb-3">
1573
1665
  <label class="form-label required" for="user_login">New Username</label>
1574
- <input aria-required="true" class="form-control" id="user_login" name="user[login]" required="required" type="password">
1666
+ <input class="form-control" id="user_login" name="user[login]" required="required" type="password">
1575
1667
  </div>
1576
1668
  <div class="mb-3">
1577
1669
  <label class="form-label" for="user_password">New Password</label>
@@ -1583,7 +1675,7 @@ This generates:
1583
1675
 
1584
1676
  Adding a form control for a `belongs_to` field will automatically pick up the associated presence validator.
1585
1677
 
1586
- ![Example 53](demo/doc/screenshots/bootstrap/readme/53_example.png "Example 53")
1678
+ ![Example 54](demo/doc/screenshots/bootstrap/readme/54_example.png "Example 54")
1587
1679
  ```erb
1588
1680
  <%= bootstrap_form_for(@address, url: '/address') do |f| %>
1589
1681
  <%= f.collection_select :user_id, @users, :id, :email, include_blank: "Select a value" %>
@@ -1626,6 +1718,98 @@ Generated HTML:
1626
1718
  </form>
1627
1719
  ```
1628
1720
 
1721
+ ## Disabled fields
1722
+
1723
+ Fields can be disabled using the standard Rails form helper option.
1724
+
1725
+ ![Example 55](demo/doc/screenshots/bootstrap/readme/55_example.png "Example 55")
1726
+ ```erb
1727
+ <%= bootstrap_form_for @user do |f| %>
1728
+ <div class="row g-3">
1729
+ <div class="col-auto"><%= f.email_field :email, disabled: true %></div>
1730
+ <div class="col-auto"><%= f.password_field :password, disabled: true %></div>
1731
+ <div class="col-auto"><%= f.text_area :comments, disabled: true %></div>
1732
+ <div class="col-auto"><%= f.text_field :status, disabled: true %></div>
1733
+ <div class="col-auto"><%= f.number_field :misc, label: "Number", disabled: true %></div>
1734
+ <div class="col-auto"><%= f.radio_button :preferences, 1, disabled: true %></div>
1735
+ <div class="col-auto"><%= f.check_box :terms, disabled: true %></div>
1736
+ <div class="col-auto"><%= f.select :type, [1,2,3], {}, disabled: true %></div>
1737
+ <div class="col-auto"><%= f.datetime_field :created_at, disabled: true %></div>
1738
+ </div>
1739
+ <%= f.primary disabled: true %>
1740
+ <% end %>
1741
+ ```
1742
+
1743
+ Generated HTML:
1744
+
1745
+ ```html
1746
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
1747
+ <div class="row g-3">
1748
+ <div class="col-auto">
1749
+ <div class="mb-3">
1750
+ <label class="form-label required" for="user_email">Email</label>
1751
+ <input class="form-control" disabled id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
1752
+ </div>
1753
+ </div>
1754
+ <div class="col-auto">
1755
+ <div class="mb-3">
1756
+ <label class="form-label" for="user_password">Password</label>
1757
+ <input class="form-control" disabled id="user_password" name="user[password]" type="password">
1758
+ </div>
1759
+ </div>
1760
+ <div class="col-auto">
1761
+ <div class="mb-3">
1762
+ <label class="form-label" for="user_comments">Comments</label>
1763
+ <textarea class="form-control" disabled id="user_comments" name="user[comments]">
1764
+ </textarea>
1765
+ </div>
1766
+ </div>
1767
+ <div class="col-auto">
1768
+ <div class="mb-3">
1769
+ <label class="form-label" for="user_status">Status</label>
1770
+ <input class="form-control" disabled id="user_status" name="user[status]" type="text">
1771
+ </div>
1772
+ </div>
1773
+ <div class="col-auto">
1774
+ <div class="mb-3">
1775
+ <label class="form-label" for="user_misc">Number</label>
1776
+ <input class="form-control" disabled id="user_misc" name="user[misc]" type="number">
1777
+ </div>
1778
+ </div>
1779
+ <div class="col-auto">
1780
+ <div class="form-check disabled">
1781
+ <input class="form-check-input" disabled id="user_preferences_1" name="user[preferences]" type="radio" value="1">
1782
+ <label class="form-check-label" for="user_preferences_1">1</label>
1783
+ </div>
1784
+ </div>
1785
+ <div class="col-auto">
1786
+ <div class="form-check mb-3">
1787
+ <input autocomplete="off" disabled name="user[terms]" type="hidden" value="0">
1788
+ <input class="form-check-input" disabled id="user_terms" name="user[terms]" type="checkbox" value="1">
1789
+ <label class="form-check-label" for="user_terms">Terms</label>
1790
+ </div>
1791
+ </div>
1792
+ <div class="col-auto">
1793
+ <div class="mb-3">
1794
+ <label class="form-label" for="user_type">Type</label>
1795
+ <select class="form-select" disabled id="user_type" name="user[type]">
1796
+ <option value="1">1</option>
1797
+ <option value="2">2</option>
1798
+ <option value="3">3</option>
1799
+ </select>
1800
+ </div>
1801
+ </div>
1802
+ <div class="col-auto">
1803
+ <div class="mb-3">
1804
+ <label class="form-label" for="user_created_at">Created at</label>
1805
+ <input class="form-control" disabled id="user_created_at" name="user[created_at]" type="datetime-local">
1806
+ </div>
1807
+ </div>
1808
+ </div>
1809
+ <input class="btn btn-primary" data-disable-with="Create User" disabled name="commit" type="submit" value="Create User">
1810
+ </form>
1811
+ ```
1812
+
1629
1813
  ## Internationalization
1630
1814
 
1631
1815
  bootstrap_form follows standard rails conventions so it's i18n-ready. See more