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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +48 -0
- data/.gitignore +28 -3
- data/.rubocop.yml +19 -15
- data/CHANGELOG.md +82 -1
- data/CONTRIBUTING.md +73 -12
- data/Dangerfile +5 -7
- data/Dockerfile +21 -0
- data/Gemfile +8 -11
- data/README.md +829 -82
- data/RELEASING.md +5 -10
- data/UPGRADE-4.0.md +1 -1
- data/UPGRADE-5.0.md +25 -0
- data/bootstrap_form.gemspec +8 -5
- data/demo/.ruby-version +1 -0
- data/demo/Gemfile +80 -0
- data/demo/Gemfile.lock +261 -0
- data/demo/Procfile.dev +2 -0
- data/demo/app/assets/builds/.keep +0 -0
- data/demo/app/assets/builds/application.js.LICENSE.txt +9 -0
- data/demo/app/assets/config/manifest.js +2 -2
- data/demo/app/assets/stylesheets/actiontext.css +31 -0
- data/demo/app/assets/stylesheets/application.scss +1 -1
- data/demo/app/controllers/bootstrap_controller.rb +17 -2
- data/demo/app/controllers/users_controller.rb +9 -0
- data/demo/app/helpers/bootstrap_helper.rb +5 -5
- data/demo/app/javascript/application.js +3 -0
- data/demo/app/models/skill.rb +15 -0
- data/demo/app/models/user.rb +14 -0
- data/demo/app/views/active_storage/blobs/_blob.html.erb +1 -1
- data/demo/app/views/bootstrap/form.html.erb +13 -0
- data/demo/app/views/layouts/action_text/contents/_content.html.erb +3 -0
- data/demo/app/views/layouts/application.html.erb +28 -20
- data/demo/bin/dev +9 -0
- data/demo/config/environments/development.rb +3 -3
- data/demo/config/puma.rb +2 -2
- data/demo/config/routes.rb +1 -0
- data/demo/db/schema.rb +31 -16
- data/demo/doc/screenshots/bootstrap/index/00_horizontal_form.png +0 -0
- data/demo/doc/screenshots/bootstrap/index/01_with_validation_error.png +0 -0
- data/demo/doc/screenshots/bootstrap/index/02_inline_form.png +0 -0
- data/demo/doc/screenshots/bootstrap/index/03_simple_action_text_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/index/04_floating_labels.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/00_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/01_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/02_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/03_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/04_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/05_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/06_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/07_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/08_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/09_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/10_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/11_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/12_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/13_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/14_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/15_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/16_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/17_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/18_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/19_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/20_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/21_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/22_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/23_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/24_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/25_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/26_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/27_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/28_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/29_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/30_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/31_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/32_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/33_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/34_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/35_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/36_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/37_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/38_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/39_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/40_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/41_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/42_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/43_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/44_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/45_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/46_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/47_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/48_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/49_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/50_example.png +0 -0
- data/demo/package.json +10 -6
- data/demo/test/application_system_test_case.rb +8 -0
- data/demo/test/controllers/bootstrap_controller_test.rb +8 -0
- data/demo/test/controllers/users_controller_test.rb +13 -0
- data/demo/test/fixtures/users.yml +2 -0
- data/demo/test/system/bootstrap_test.rb +84 -0
- data/demo/test/test_helper.rb +10 -0
- data/demo/webpack.config.js +20 -0
- data/demo/yarn.lock +4063 -3144
- data/docker-compose.yml +49 -0
- data/gemfiles/5.2.gemfile +2 -15
- data/gemfiles/6.0.gemfile +2 -17
- data/gemfiles/6.1.gemfile +4 -0
- data/gemfiles/7.0.gemfile +6 -0
- data/gemfiles/edge.gemfile +2 -17
- data/lib/bootstrap_form/action_view_extensions/form_helper.rb +1 -1
- data/lib/bootstrap_form/components/hints.rb +13 -4
- data/lib/bootstrap_form/components/labels.rb +2 -2
- data/lib/bootstrap_form/components/validation.rb +1 -1
- data/lib/bootstrap_form/configuration.rb +22 -0
- data/lib/bootstrap_form/form_builder.rb +10 -12
- data/lib/bootstrap_form/form_group.rb +26 -11
- data/lib/bootstrap_form/form_group_builder.rb +6 -8
- data/lib/bootstrap_form/helpers/bootstrap.rb +17 -12
- data/lib/bootstrap_form/inputs/base.rb +5 -5
- data/lib/bootstrap_form/inputs/check_box.rb +11 -23
- data/lib/bootstrap_form/inputs/collection_check_boxes.rb +5 -1
- data/lib/bootstrap_form/inputs/collection_select.rb +2 -1
- data/lib/bootstrap_form/inputs/file_field.rb +3 -15
- data/lib/bootstrap_form/inputs/grouped_collection_select.rb +2 -1
- data/lib/bootstrap_form/inputs/radio_button.rb +17 -30
- data/lib/bootstrap_form/inputs/select.rb +1 -0
- data/lib/bootstrap_form/inputs/time_zone_select.rb +1 -0
- data/lib/bootstrap_form/version.rb +1 -1
- data/lib/bootstrap_form.rb +17 -7
- metadata +94 -16
- data/.travis.yml +0 -42
- data/demo/config/initializers/assets.rb +0 -14
- data/gemfiles/5.0.gemfile +0 -18
- 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
|
-
[![
|
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
|
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.
|
35
|
-
* Rails 5.
|
36
|
-
* Bootstrap
|
28
|
+
* Ruby 2.5+
|
29
|
+
* Rails 5.2+
|
30
|
+
* Bootstrap 5.0+
|
37
31
|
|
38
32
|
## Installation
|
39
33
|
|
40
|
-
|
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 "
|
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="
|
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="
|
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
|
-
|
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
|
129
|
-
<
|
130
|
-
|
131
|
-
<
|
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="
|
135
|
-
<label for="user_password">Password</label>
|
136
|
-
<input class="form-control"
|
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
|
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
|
-
|
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
|
-
<
|
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.
|
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
|
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="
|
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
|
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
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
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 `
|
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,
|
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
|
-
<
|
424
|
-
<
|
425
|
-
|
426
|
-
<
|
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
|
-
</
|
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
|
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="
|
537
|
-
<label for="user_life_story">Life story</label>
|
538
|
-
<input
|
539
|
-
<trix-
|
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="
|
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
|
-
<%=
|
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
|
-
<
|
742
|
-
<
|
743
|
-
|
744
|
-
<
|
745
|
-
|
746
|
-
</
|
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
|
-
<%=
|
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
|
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
|
-
<
|
765
|
-
<
|
766
|
-
</
|
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
|
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
|
-
<
|
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
|
-
<%=
|
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
|
-
<
|
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-
|
1606
|
+
MIT License. Copyright 2012-2021 Stephen Potenza (https://github.com/potenza) and others
|