bootstrap_form 5.1.0 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +21 -8
- data/.gitignore +4 -2
- data/.rubocop.yml +2 -1
- data/.yarnrc +5 -0
- data/CHANGELOG.md +13 -3
- data/CONTRIBUTING.md +101 -14
- data/Dangerfile +4 -4
- data/Dockerfile +5 -5
- data/Gemfile +5 -21
- data/README.md +108 -42
- data/RELEASING.md +12 -1
- data/Rakefile +7 -6
- data/bootstrap_form.gemspec +6 -8
- data/docker-compose.yml +6 -24
- data/gemfiles/6.0.gemfile +1 -1
- data/gemfiles/6.1.gemfile +1 -1
- data/gemfiles/7.0.gemfile +2 -3
- data/gemfiles/common.gemfile +28 -0
- data/gemfiles/edge.gemfile +3 -2
- data/lib/bootstrap_form/components/labels.rb +3 -9
- data/lib/bootstrap_form/components/validation.rb +36 -19
- data/lib/bootstrap_form/form_builder.rb +4 -1
- data/lib/bootstrap_form/form_group.rb +9 -6
- data/lib/bootstrap_form/form_group_builder.rb +10 -7
- data/lib/bootstrap_form/helpers/bootstrap.rb +7 -8
- data/lib/bootstrap_form/helpers/field.rb +26 -0
- data/lib/bootstrap_form/helpers.rb +1 -0
- data/lib/bootstrap_form/inputs/base.rb +2 -2
- data/lib/bootstrap_form/inputs/check_box.rb +22 -6
- data/lib/bootstrap_form/inputs/radio_button.rb +3 -3
- data/lib/bootstrap_form/inputs/range_field.rb +1 -1
- data/lib/bootstrap_form/inputs.rb +1 -1
- data/lib/bootstrap_form/version.rb +2 -1
- data/lib/bootstrap_form.rb +1 -1
- metadata +14 -146
- data/demo/.postcssrc.yml +0 -3
- data/demo/.ruby-version +0 -1
- data/demo/Gemfile +0 -80
- data/demo/Gemfile.lock +0 -261
- data/demo/Procfile.dev +0 -2
- data/demo/README.md +0 -17
- data/demo/Rakefile +0 -6
- data/demo/app/assets/builds/.keep +0 -0
- data/demo/app/assets/builds/application.js.LICENSE.txt +0 -9
- data/demo/app/assets/config/manifest.js +0 -2
- data/demo/app/assets/stylesheets/actiontext.css +0 -31
- data/demo/app/assets/stylesheets/actiontext.scss +0 -38
- data/demo/app/assets/stylesheets/application.scss +0 -1
- data/demo/app/controllers/application_controller.rb +0 -2
- data/demo/app/controllers/bootstrap_controller.rb +0 -29
- data/demo/app/controllers/users_controller.rb +0 -9
- data/demo/app/helpers/bootstrap_helper.rb +0 -27
- data/demo/app/javascript/application.js +0 -3
- data/demo/app/javascript/channels/consumer.js +0 -6
- data/demo/app/javascript/channels/index.js +0 -5
- data/demo/app/javascript/packs/application.js +0 -11
- data/demo/app/models/address.rb +0 -3
- data/demo/app/models/application_record.rb +0 -3
- data/demo/app/models/faux_user.rb +0 -9
- data/demo/app/models/skill.rb +0 -15
- data/demo/app/models/super_user.rb +0 -2
- data/demo/app/models/user.rb +0 -25
- data/demo/app/views/active_storage/blobs/_blob.html.erb +0 -14
- data/demo/app/views/bootstrap/form.html.erb +0 -67
- data/demo/app/views/layouts/action_text/contents/_content.html.erb +0 -3
- data/demo/app/views/layouts/application.html.erb +0 -76
- data/demo/bin/bundle +0 -3
- data/demo/bin/dev +0 -9
- data/demo/bin/rails +0 -4
- data/demo/bin/rake +0 -4
- data/demo/bin/setup +0 -36
- data/demo/bin/update +0 -31
- data/demo/bin/webpack +0 -15
- data/demo/bin/webpack-dev-server +0 -15
- data/demo/bin/yarn +0 -11
- data/demo/config/application.rb +0 -21
- data/demo/config/boot.rb +0 -5
- data/demo/config/database.yml +0 -21
- data/demo/config/environment.rb +0 -5
- data/demo/config/environments/development.rb +0 -60
- data/demo/config/environments/production.rb +0 -48
- data/demo/config/environments/test.rb +0 -46
- data/demo/config/initializers/application_controller_renderer.rb +0 -8
- data/demo/config/initializers/backtrace_silencers.rb +0 -7
- data/demo/config/initializers/cookies_serializer.rb +0 -5
- data/demo/config/initializers/filter_parameter_logging.rb +0 -4
- data/demo/config/initializers/inflections.rb +0 -16
- data/demo/config/initializers/mime_types.rb +0 -4
- data/demo/config/initializers/wrap_parameters.rb +0 -14
- data/demo/config/locales/en.yml +0 -33
- data/demo/config/puma.rb +0 -56
- data/demo/config/routes.rb +0 -6
- data/demo/config/spring.rb +0 -6
- data/demo/config/storage.yml +0 -35
- data/demo/config/webpack/development.js +0 -5
- data/demo/config/webpack/environment.js +0 -3
- data/demo/config/webpack/production.js +0 -5
- data/demo/config/webpack/test.js +0 -5
- data/demo/config/webpacker.yml +0 -92
- data/demo/config.ru +0 -5
- data/demo/db/schema.rb +0 -84
- 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/log/.keep +0 -0
- data/demo/package.json +0 -21
- data/demo/public/favicon.ico +0 -0
- data/demo/test/application_system_test_case.rb +0 -8
- data/demo/test/controllers/bootstrap_controller_test.rb +0 -8
- data/demo/test/controllers/users_controller_test.rb +0 -13
- data/demo/test/fixtures/action_text/rich_texts.yml +0 -4
- data/demo/test/fixtures/users.yml +0 -2
- data/demo/test/system/bootstrap_test.rb +0 -84
- data/demo/test/test_helper.rb +0 -10
- data/demo/webpack.config.js +0 -20
- data/demo/yarn.lock +0 -7176
- data/gemfiles/5.2.gemfile +0 -4
data/README.md
CHANGED
|
@@ -25,8 +25,8 @@ Some other nice things that `bootstrap_form` does for you are:
|
|
|
25
25
|
|
|
26
26
|
`bootstrap_form` supports at a minimum the currently supported versions of Ruby and Rails:
|
|
27
27
|
|
|
28
|
-
* Ruby
|
|
29
|
-
* Rails
|
|
28
|
+
* Ruby 3.0+ (https://www.ruby-lang.org/en/downloads/branches/)
|
|
29
|
+
* Rails 6.0+ (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.
|
|
45
|
+
gem "bootstrap_form", "~> 5.2"
|
|
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 class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
|
|
87
|
+
<input aria-required="true" 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>
|
|
@@ -125,8 +125,6 @@ This generates:
|
|
|
125
125
|
|
|
126
126
|
### bootstrap_form_with
|
|
127
127
|
|
|
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.
|
|
129
|
-
|
|
130
128
|
To get started, just use the `bootstrap_form_with` helper in place of `form_with`. Here's an example:
|
|
131
129
|
|
|
132
130
|

|
|
@@ -145,7 +143,7 @@ This generates:
|
|
|
145
143
|
<form accept-charset="UTF-8" action="/users" method="post">
|
|
146
144
|
<div class="mb-3">
|
|
147
145
|
<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">
|
|
146
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
|
|
149
147
|
</div>
|
|
150
148
|
<div class="mb-3">
|
|
151
149
|
<label class="form-label" for="user_password">Password</label>
|
|
@@ -200,7 +198,7 @@ date_field password_field time_field
|
|
|
200
198
|
date_select phone_field time_select
|
|
201
199
|
datetime_field radio_button time_zone_select
|
|
202
200
|
datetime_local_field range_field url_field
|
|
203
|
-
datetime_select rich_text_area
|
|
201
|
+
datetime_select rich_text_area week_field
|
|
204
202
|
```
|
|
205
203
|
|
|
206
204
|
By default, the helpers generate a `label` tag, and an `input`, `select`, or `textarea` tag, by calling the Rails `label` helper, and then the Rails helper with the same name as the `bootstrap_form` helper.
|
|
@@ -278,7 +276,7 @@ This generates:
|
|
|
278
276
|
```html
|
|
279
277
|
<div class="mb-3">
|
|
280
278
|
<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">
|
|
279
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="text" value="steve@example.com">
|
|
282
280
|
</div>
|
|
283
281
|
```
|
|
284
282
|
|
|
@@ -294,7 +292,7 @@ This generates:
|
|
|
294
292
|
```html
|
|
295
293
|
<div class="mb-3">
|
|
296
294
|
<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">
|
|
295
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" placeholder="Email" required="required" type="text" value="steve@example.com">
|
|
298
296
|
</div>
|
|
299
297
|
```
|
|
300
298
|
|
|
@@ -312,7 +310,7 @@ This generates:
|
|
|
312
310
|
```html
|
|
313
311
|
<div class="mb-3">
|
|
314
312
|
<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">
|
|
313
|
+
<input aria-required="true" class="custom-class" id="user_email" name="user[email]" required="required" type="text" value="steve@example.com">
|
|
316
314
|
</div>
|
|
317
315
|
```
|
|
318
316
|
|
|
@@ -438,7 +436,7 @@ This generates:
|
|
|
438
436
|
<div class="mb-3">
|
|
439
437
|
<label class="form-label required" for="user_email">Email</label>
|
|
440
438
|
<div class="input-group input-group-lg">
|
|
441
|
-
<input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
|
|
439
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
|
|
442
440
|
<input class="btn btn-primary" data-disable-with="Subscribe" name="commit" type="submit" value="Subscribe">
|
|
443
441
|
</div>
|
|
444
442
|
</div>
|
|
@@ -503,7 +501,7 @@ Generated HTML:
|
|
|
503
501
|
|
|
504
502
|
```html
|
|
505
503
|
<div class="mb-3">
|
|
506
|
-
<input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
|
|
504
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
|
|
507
505
|
</div>
|
|
508
506
|
```
|
|
509
507
|
|
|
@@ -753,7 +751,7 @@ This generates:
|
|
|
753
751
|
```html
|
|
754
752
|
<div class="mb-3">
|
|
755
753
|
<label class="form-label" for="user_excellence">Excellence</label>
|
|
756
|
-
<input class="form-
|
|
754
|
+
<input class="form-range" id="user_excellence" name="user[excellence]" type="range">
|
|
757
755
|
</div>
|
|
758
756
|
```
|
|
759
757
|
|
|
@@ -771,7 +769,7 @@ This generates:
|
|
|
771
769
|
```html
|
|
772
770
|
<div class="mb-3">
|
|
773
771
|
<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">
|
|
772
|
+
<input aria-required="true" class="form-control-plaintext" id="user_email" name="user[email]" readonly required="required" type="text" value="steve@example.com">
|
|
775
773
|
</div>
|
|
776
774
|
```
|
|
777
775
|
|
|
@@ -791,7 +789,7 @@ This generates:
|
|
|
791
789
|
<div class="mb-3 row">
|
|
792
790
|
<label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
|
|
793
791
|
<div class="col-sm-10">
|
|
794
|
-
<input class="form-control-plaintext" id="user_email" name="user[email]" readonly type="text" value="steve@example.com">
|
|
792
|
+
<input aria-required="true" class="form-control-plaintext" id="user_email" name="user[email]" readonly required="required" type="text" value="steve@example.com">
|
|
795
793
|
</div>
|
|
796
794
|
</div>
|
|
797
795
|
</form>
|
|
@@ -946,8 +944,6 @@ will be rendered as
|
|
|
946
944
|
|
|
947
945
|
## Rich Text Areas AKA Trix Editor
|
|
948
946
|
|
|
949
|
-
If you're using Rails 6, `bootstrap_form` supports the `rich_text_area` helper.
|
|
950
|
-
|
|
951
947
|

|
|
952
948
|
```erb
|
|
953
949
|
<%= f.rich_text_area(:life_story) %>
|
|
@@ -1054,7 +1050,7 @@ This generates:
|
|
|
1054
1050
|
<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
1051
|
<div class="col">
|
|
1056
1052
|
<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">
|
|
1053
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
|
|
1058
1054
|
</div>
|
|
1059
1055
|
<div class="col">
|
|
1060
1056
|
<label class="form-label visually-hidden mr-sm-2" for="user_password">Password</label>
|
|
@@ -1116,7 +1112,7 @@ This generates:
|
|
|
1116
1112
|
<div class="mb-3 row">
|
|
1117
1113
|
<label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
|
|
1118
1114
|
<div class="col-sm-10">
|
|
1119
|
-
<input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
|
|
1115
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
|
|
1120
1116
|
</div>
|
|
1121
1117
|
</div>
|
|
1122
1118
|
<div class="mb-3 row">
|
|
@@ -1134,7 +1130,7 @@ This generates:
|
|
|
1134
1130
|
</div>
|
|
1135
1131
|
</div>
|
|
1136
1132
|
</div>
|
|
1137
|
-
|
|
1133
|
+
|
|
1138
1134
|
<div class="mb-3 row">
|
|
1139
1135
|
<div class="col-sm-10 offset-sm-2">
|
|
1140
1136
|
<input class="btn btn-secondary" data-disable-with="Create User" name="commit" type="submit" value="Create User">
|
|
@@ -1163,7 +1159,7 @@ This generates:
|
|
|
1163
1159
|
<div class="mb-3 row">
|
|
1164
1160
|
<label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
|
|
1165
1161
|
<div class="col-sm-10">
|
|
1166
|
-
<input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
|
|
1162
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
|
|
1167
1163
|
</div>
|
|
1168
1164
|
</div>
|
|
1169
1165
|
<div class="mb-3 row">
|
|
@@ -1220,7 +1216,7 @@ This generates:
|
|
|
1220
1216
|
<div class="mb-3 row">
|
|
1221
1217
|
<label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
|
|
1222
1218
|
<div class="col-sm-10">
|
|
1223
|
-
<input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
|
|
1219
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
|
|
1224
1220
|
</div>
|
|
1225
1221
|
</div>
|
|
1226
1222
|
<div class="mb-3 row">
|
|
@@ -1260,7 +1256,7 @@ This generates:
|
|
|
1260
1256
|
<div class="mb-3 row">
|
|
1261
1257
|
<label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
|
|
1262
1258
|
<div class="col-sm-10">
|
|
1263
|
-
<input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com">
|
|
1259
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
|
|
1264
1260
|
</div>
|
|
1265
1261
|
</div>
|
|
1266
1262
|
<div class="mb-3">
|
|
@@ -1301,7 +1297,7 @@ This generates:
|
|
|
1301
1297
|
<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
|
|
1302
1298
|
<div class="mb-3">
|
|
1303
1299
|
<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">
|
|
1300
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" required="required" type="email" value="steve@example.com">
|
|
1305
1301
|
</div>
|
|
1306
1302
|
<div class="mb-3">
|
|
1307
1303
|
<label class="form-label" for="user_password">Password</label>
|
|
@@ -1337,7 +1333,7 @@ This generates:
|
|
|
1337
1333
|
```html
|
|
1338
1334
|
<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
|
|
1339
1335
|
<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">
|
|
1336
|
+
<input aria-required="true" class="form-control" id="user_email" name="user[email]" placeholder="Email" required="required" type="email" value="steve@example.com">
|
|
1341
1337
|
<label class="form-label required" for="user_email">Email</label>
|
|
1342
1338
|
</div>
|
|
1343
1339
|
<div class="mb-3 form-floating">
|
|
@@ -1369,18 +1365,29 @@ Rails normally wraps fields with validation errors in a `div.field_with_errors`,
|
|
|
1369
1365
|
By default, fields that have validation errors will be outlined in red and the
|
|
1370
1366
|
error will be displayed below the field. Here's an example:
|
|
1371
1367
|
|
|
1368
|
+

|
|
1369
|
+
```erb
|
|
1370
|
+
<%= bootstrap_form_for(@user_with_error) do |f| %>
|
|
1371
|
+
<%= f.email_field :email %>
|
|
1372
|
+
<% end %>
|
|
1373
|
+
```
|
|
1374
|
+
|
|
1375
|
+
Generated HTML:
|
|
1376
|
+
|
|
1372
1377
|
```html
|
|
1373
|
-
<
|
|
1374
|
-
<
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
</div>
|
|
1378
|
+
<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
|
|
1379
|
+
<div class="mb-3">
|
|
1380
|
+
<label class="form-label required" for="user_email">Email</label>
|
|
1381
|
+
<input aria-required="true" class="form-control is-invalid" id="user_email" name="user[email]" required="required" type="email" value="steve.example.com">
|
|
1382
|
+
<div class="invalid-feedback">is invalid</div>
|
|
1383
|
+
</div>
|
|
1384
|
+
</form>
|
|
1378
1385
|
```
|
|
1379
1386
|
|
|
1380
1387
|
You can turn off inline errors for the entire form like this:
|
|
1381
1388
|
|
|
1382
1389
|
```erb
|
|
1383
|
-
<%= bootstrap_form_for(@
|
|
1390
|
+
<%= bootstrap_form_for(@user_with_error, inline_errors: false) do |f| %>
|
|
1384
1391
|
...
|
|
1385
1392
|
<% end %>
|
|
1386
1393
|
```
|
|
@@ -1390,12 +1397,24 @@ You can turn off inline errors for the entire form like this:
|
|
|
1390
1397
|
You can also display validation errors in the field's label; just turn
|
|
1391
1398
|
on the `:label_errors` option. Here's an example:
|
|
1392
1399
|
|
|
1400
|
+

|
|
1393
1401
|
```erb
|
|
1394
|
-
<%= bootstrap_form_for(@
|
|
1395
|
-
|
|
1402
|
+
<%= bootstrap_form_for(@user_with_error, label_errors: true) do |f| %>
|
|
1403
|
+
<%= f.email_field :email %>
|
|
1396
1404
|
<% end %>
|
|
1397
1405
|
```
|
|
1398
1406
|
|
|
1407
|
+
Generated HTML:
|
|
1408
|
+
|
|
1409
|
+
```html
|
|
1410
|
+
<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
|
|
1411
|
+
<div class="mb-3">
|
|
1412
|
+
<label class="form-label required text-danger" for="user_email">Email is invalid</label>
|
|
1413
|
+
<input aria-required="true" class="form-control is-invalid" id="user_email" name="user[email]" required="required" type="email" value="steve.example.com">
|
|
1414
|
+
</div>
|
|
1415
|
+
</form>
|
|
1416
|
+
```
|
|
1417
|
+
|
|
1399
1418
|
By default, turning on `:label_errors` will also turn off
|
|
1400
1419
|
`:inline_errors`. If you want both turned on, you can do that too:
|
|
1401
1420
|
|
|
@@ -1411,7 +1430,7 @@ To display an error message with an error summary, you can use the
|
|
|
1411
1430
|
`alert_message` helper. This won't output anything unless a model validation
|
|
1412
1431
|
has failed.
|
|
1413
1432
|
|
|
1414
|
-

|
|
1415
1434
|
```erb
|
|
1416
1435
|
<%= bootstrap_form_for @user_with_error do |f| %>
|
|
1417
1436
|
<%= f.alert_message "Please fix the errors below." %>
|
|
@@ -1434,7 +1453,7 @@ Which outputs:
|
|
|
1434
1453
|
|
|
1435
1454
|
You can turn off the error summary like this:
|
|
1436
1455
|
|
|
1437
|
-

|
|
1438
1457
|
```erb
|
|
1439
1458
|
<%= bootstrap_form_for @user_with_error do |f| %>
|
|
1440
1459
|
<%= f.alert_message "Please fix the errors below.", error_summary: false %>
|
|
@@ -1451,7 +1470,7 @@ This generates:
|
|
|
1451
1470
|
|
|
1452
1471
|
To output a simple unordered list of errors, use the `error_summary` helper.
|
|
1453
1472
|
|
|
1454
|
-

|
|
1455
1474
|
```erb
|
|
1456
1475
|
<%= bootstrap_form_for @user_with_error do |f| %>
|
|
1457
1476
|
<%= f.error_summary %>
|
|
@@ -1473,7 +1492,7 @@ Which outputs:
|
|
|
1473
1492
|
|
|
1474
1493
|
If you want to display a custom inline error for a specific attribute not represented by a form field, use the `errors_on` helper.
|
|
1475
1494
|
|
|
1476
|
-

|
|
1477
1496
|
```erb
|
|
1478
1497
|
<%= bootstrap_form_for @user_with_error do |f| %>
|
|
1479
1498
|
<%= f.errors_on :email %>
|
|
@@ -1490,7 +1509,7 @@ Which outputs:
|
|
|
1490
1509
|
|
|
1491
1510
|
You can hide the attribute name like this:
|
|
1492
1511
|
|
|
1493
|
-

|
|
1494
1513
|
```erb
|
|
1495
1514
|
<%= bootstrap_form_for @user_with_error do |f| %>
|
|
1496
1515
|
<%= f.errors_on :email, hide_attribute_name: true %>
|
|
@@ -1507,7 +1526,7 @@ Which outputs:
|
|
|
1507
1526
|
|
|
1508
1527
|
You can also use a custom class for the wrapping div, like this:
|
|
1509
1528
|
|
|
1510
|
-

|
|
1511
1530
|
```erb
|
|
1512
1531
|
<%= bootstrap_form_for @user_with_error do |f| %>
|
|
1513
1532
|
<%= f.errors_on :email, custom_class: 'custom-error' %>
|
|
@@ -1542,7 +1561,7 @@ ActiveModel::Validations::PresenceValidator.
|
|
|
1542
1561
|
|
|
1543
1562
|
In cases where this behaviour is undesirable, use the `required` option to force the class to be present or absent:
|
|
1544
1563
|
|
|
1545
|
-

|
|
1546
1565
|
```erb
|
|
1547
1566
|
<%= f.password_field :login, label: "New Username", required: true %>
|
|
1548
1567
|
<%= f.password_field :password, label: "New Password", required: false %>
|
|
@@ -1553,7 +1572,7 @@ This generates:
|
|
|
1553
1572
|
```html
|
|
1554
1573
|
<div class="mb-3">
|
|
1555
1574
|
<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">
|
|
1575
|
+
<input aria-required="true" class="form-control" id="user_login" name="user[login]" required="required" type="password">
|
|
1557
1576
|
</div>
|
|
1558
1577
|
<div class="mb-3">
|
|
1559
1578
|
<label class="form-label" for="user_password">New Password</label>
|
|
@@ -1561,6 +1580,53 @@ This generates:
|
|
|
1561
1580
|
</div>
|
|
1562
1581
|
```
|
|
1563
1582
|
|
|
1583
|
+
### Required belongs_to associations
|
|
1584
|
+
|
|
1585
|
+
Adding a form control for a `belongs_to` field will automatically pick up the associated presence validator.
|
|
1586
|
+
|
|
1587
|
+

|
|
1588
|
+
```erb
|
|
1589
|
+
<%= bootstrap_form_for(@address, url: '/address') do |f| %>
|
|
1590
|
+
<%= f.collection_select :user_id, @users, :id, :email, include_blank: "Select a value" %>
|
|
1591
|
+
<%= f.text_field :street %>
|
|
1592
|
+
<%= f.text_field :city %>
|
|
1593
|
+
<%= f.text_field :state %>
|
|
1594
|
+
<%= f.text_field :zip_code %>
|
|
1595
|
+
<%= f.submit "Save" %>
|
|
1596
|
+
<% end %>
|
|
1597
|
+
```
|
|
1598
|
+
|
|
1599
|
+
Generated HTML:
|
|
1600
|
+
|
|
1601
|
+
```html
|
|
1602
|
+
<form accept-charset="UTF-8" action="/address" class="new_address" id="new_address_1" method="post">
|
|
1603
|
+
<div class="mb-3">
|
|
1604
|
+
<label class="form-label required" for="address_user_id">User</label>
|
|
1605
|
+
<select class="form-select" id="address_user_id" name="address[user_id]">
|
|
1606
|
+
<option value="">Select a value</option>
|
|
1607
|
+
<option value="">steve@example.com</option>
|
|
1608
|
+
</select>
|
|
1609
|
+
</div>
|
|
1610
|
+
<div class="mb-3">
|
|
1611
|
+
<label class="form-label" for="address_street">Street</label>
|
|
1612
|
+
<input class="form-control" id="address_street" name="address[street]" type="text" value="Foo">
|
|
1613
|
+
</div>
|
|
1614
|
+
<div class="mb-3">
|
|
1615
|
+
<label class="form-label" for="address_city">City</label>
|
|
1616
|
+
<input class="form-control" id="address_city" name="address[city]" type="text">
|
|
1617
|
+
</div>
|
|
1618
|
+
<div class="mb-3">
|
|
1619
|
+
<label class="form-label" for="address_state">State</label>
|
|
1620
|
+
<input class="form-control" id="address_state" name="address[state]" type="text">
|
|
1621
|
+
</div>
|
|
1622
|
+
<div class="mb-3">
|
|
1623
|
+
<label class="form-label" for="address_zip_code">Zip code</label>
|
|
1624
|
+
<input class="form-control" id="address_zip_code" name="address[zip_code]" type="text">
|
|
1625
|
+
</div>
|
|
1626
|
+
<input class="btn btn-secondary" data-disable-with="Save" name="commit" type="submit" value="Save">
|
|
1627
|
+
</form>
|
|
1628
|
+
```
|
|
1629
|
+
|
|
1564
1630
|
## Internationalization
|
|
1565
1631
|
|
|
1566
1632
|
bootstrap_form follows standard rails conventions so it's i18n-ready. See more
|
data/RELEASING.md
CHANGED
|
@@ -11,7 +11,18 @@ Follow these steps to release a new version of bootstrap_form to rubygems.org.
|
|
|
11
11
|
## How to release
|
|
12
12
|
|
|
13
13
|
1. Run `BUNDLE_GEMFILE=gemfiles/7.0.gemfile bundle update` to make sure that you have all the gems necessary for testing and releasing.
|
|
14
|
-
2. **Ensure the tests are passing by running
|
|
14
|
+
2. **Ensure the tests are passing by running the tests**
|
|
15
|
+
|
|
16
|
+
(There should be no errors or warnings.)
|
|
17
|
+
|
|
18
|
+
BUNDLE_GEMFILE=gemfiles/7.0.gemfile bundle exec rake test
|
|
19
|
+
|
|
20
|
+
2. **Ensure the demo tests are passing by running**
|
|
21
|
+
|
|
22
|
+
cd demo
|
|
23
|
+
bundle update
|
|
24
|
+
bundle exec rake test:all
|
|
25
|
+
|
|
15
26
|
3. Determine which would be the correct next version number according to [semver](http://semver.org/).
|
|
16
27
|
4. Update the version in `./lib/bootstrap_form/version.rb`.
|
|
17
28
|
5. Update the GitHub diff links at the beginning of `CHANGELOG.md` (The pattern should be obvious when you look at them).
|
data/Rakefile
CHANGED
|
@@ -17,12 +17,13 @@ end
|
|
|
17
17
|
|
|
18
18
|
require 'bundler/gem_tasks'
|
|
19
19
|
|
|
20
|
-
require
|
|
20
|
+
require "minitest/test_task"
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
t.libs <<
|
|
24
|
-
t.
|
|
25
|
-
t.
|
|
22
|
+
Minitest::TestTask.create(:test) do |t|
|
|
23
|
+
t.libs << "test"
|
|
24
|
+
t.libs << "lib"
|
|
25
|
+
t.warning = false
|
|
26
|
+
t.test_globs = ["test/**/*_test.rb"]
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
# This automatically updates GitHub Releases whenever we `rake release` the gem
|
|
@@ -34,4 +35,4 @@ end
|
|
|
34
35
|
desc 'Run RuboCop checks'
|
|
35
36
|
RuboCop::RakeTask.new(:rubocop)
|
|
36
37
|
|
|
37
|
-
task default: %i[test rubocop]
|
|
38
|
+
task default: %i[test rubocop:autocorrect]
|
data/bootstrap_form.gemspec
CHANGED
|
@@ -3,30 +3,28 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
3
3
|
|
|
4
4
|
require "bootstrap_form/version"
|
|
5
5
|
|
|
6
|
-
REQUIRED_RAILS_VERSION = ">= 5.2".freeze
|
|
7
|
-
|
|
8
6
|
Gem::Specification.new do |s|
|
|
9
7
|
s.name = "bootstrap_form"
|
|
10
8
|
s.version = BootstrapForm::VERSION
|
|
11
9
|
s.authors = ["Stephen Potenza", "Carlos Lopes"]
|
|
12
10
|
s.email = ["potenza@gmail.com", "carlos.el.lopes@gmail.com"]
|
|
13
11
|
s.homepage = "https://github.com/bootstrap-ruby/bootstrap_form"
|
|
14
|
-
s.summary = "Rails form builder that makes it easy to style forms using "\
|
|
12
|
+
s.summary = "Rails form builder that makes it easy to style forms using " \
|
|
15
13
|
"Bootstrap 5"
|
|
16
|
-
s.description = "bootstrap_form is a rails form builder that makes it super "\
|
|
14
|
+
s.description = "bootstrap_form is a rails form builder that makes it super " \
|
|
17
15
|
"easy to create beautiful-looking forms using Bootstrap 5"
|
|
18
16
|
s.license = "MIT"
|
|
19
17
|
s.metadata = { "rubygems_mfa_required" => "true" }
|
|
20
18
|
|
|
21
19
|
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
22
|
-
f.match(%r{^(test)/})
|
|
20
|
+
f.match(%r{^(test)/|^(demo)/})
|
|
23
21
|
end
|
|
24
22
|
|
|
25
23
|
s.bindir = "exe"
|
|
26
24
|
s.require_paths = ["lib"]
|
|
27
25
|
|
|
28
|
-
s.required_ruby_version = ">=
|
|
26
|
+
s.required_ruby_version = ">= 3.0"
|
|
29
27
|
|
|
30
|
-
s.add_dependency("actionpack", REQUIRED_RAILS_VERSION)
|
|
31
|
-
s.add_dependency("activemodel", REQUIRED_RAILS_VERSION)
|
|
28
|
+
s.add_dependency("actionpack", BootstrapForm::REQUIRED_RAILS_VERSION)
|
|
29
|
+
s.add_dependency("activemodel", BootstrapForm::REQUIRED_RAILS_VERSION)
|
|
32
30
|
end
|
data/docker-compose.yml
CHANGED
|
@@ -5,9 +5,10 @@ services:
|
|
|
5
5
|
build:
|
|
6
6
|
context: .
|
|
7
7
|
args:
|
|
8
|
-
NODE_MAJOR:
|
|
9
|
-
YARN_VERSION:
|
|
10
|
-
|
|
8
|
+
NODE_MAJOR: "12"
|
|
9
|
+
YARN_VERSION: "1.22.4"
|
|
10
|
+
RUBY_VERSION: ${RUBY_VERSION}
|
|
11
|
+
image: bootstrap-form:latest-$RUBY_VERSION
|
|
11
12
|
tmpfs:
|
|
12
13
|
- /tmp
|
|
13
14
|
|
|
@@ -17,15 +18,6 @@ services:
|
|
|
17
18
|
tty: true
|
|
18
19
|
volumes:
|
|
19
20
|
- .:/app:cached
|
|
20
|
-
# - rails_cache:/app/tmp/cache
|
|
21
|
-
# - bundle:/app/vendor/bundle
|
|
22
|
-
# - node_modules:/app/node_modules
|
|
23
|
-
# - packs:/app/public/packs
|
|
24
|
-
- /etc/passwd:/etc/passwd:ro
|
|
25
|
-
# One or the other of the following lines might be redundant, or one might be
|
|
26
|
-
# better than the other.
|
|
27
|
-
- ~/.ssh:${HOME}/.ssh
|
|
28
|
-
- ${SSH_AUTH_SOCK}:/ssh-agent
|
|
29
21
|
environment:
|
|
30
22
|
- SSH_AUTH_SOCK=/ssh-agent
|
|
31
23
|
- NODE_ENV=development
|
|
@@ -34,16 +26,6 @@ services:
|
|
|
34
26
|
- WEBPACKER_DEV_SERVER_HOST=webpacker
|
|
35
27
|
- WEB_CONCURRENCY=1
|
|
36
28
|
- HISTFILE=/app/.bash_history
|
|
29
|
+
ports:
|
|
30
|
+
- "3000:3000"
|
|
37
31
|
command: /bin/bash
|
|
38
|
-
|
|
39
|
-
# server:
|
|
40
|
-
# <<: *shell
|
|
41
|
-
# command: sh -c "cd demo/app && bundle exec rails server -b 0.0.0.0"
|
|
42
|
-
# ports:
|
|
43
|
-
# - '3000:3000'
|
|
44
|
-
|
|
45
|
-
# volumes:
|
|
46
|
-
# bundle:
|
|
47
|
-
# node_modules:
|
|
48
|
-
# rails_cache:
|
|
49
|
-
# packs:
|
data/gemfiles/6.0.gemfile
CHANGED
data/gemfiles/6.1.gemfile
CHANGED
data/gemfiles/7.0.gemfile
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
gems = "#{
|
|
1
|
+
gems = "#{__dir__}/common.gemfile"
|
|
2
2
|
eval File.read(gems), binding, gems # rubocop: disable Security/Eval
|
|
3
3
|
|
|
4
|
-
# 7.0.0 has an issue with Ruby 3.1.
|
|
5
|
-
# And a test case has an issue with 7.0.1
|
|
6
4
|
gem "rails", "~> 7.0.2"
|
|
5
|
+
gem "sprockets-rails", require: "sprockets/railtie"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
source "http://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gemspec path: File.dirname(__dir__)
|
|
4
|
+
|
|
5
|
+
# To test with different Rails versions, use the files in `./gemfiles`
|
|
6
|
+
|
|
7
|
+
group :development do
|
|
8
|
+
gem "htmlbeautifier"
|
|
9
|
+
gem "puma"
|
|
10
|
+
gem "rubocop-performance", require: false
|
|
11
|
+
gem "rubocop-rails", require: false
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
group :test do
|
|
15
|
+
gem "diffy"
|
|
16
|
+
gem "equivalent-xml"
|
|
17
|
+
gem "mocha"
|
|
18
|
+
gem "sqlite3"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
group :development, :test do
|
|
22
|
+
gem "debug"
|
|
23
|
+
gem "pry-byebug"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
group :ci do
|
|
27
|
+
gem "danger"
|
|
28
|
+
end
|
data/gemfiles/edge.gemfile
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
gems = "#{
|
|
1
|
+
gems = "#{__dir__}/common.gemfile"
|
|
2
2
|
eval File.read(gems), binding, gems # rubocop: disable Security/Eval
|
|
3
3
|
|
|
4
|
-
gem "rails", git: "https://github.com/rails/rails.git"
|
|
4
|
+
gem "rails", git: "https://github.com/rails/rails.git", branch: "main"
|
|
5
|
+
gem "sprockets-rails", require: "sprockets/railtie"
|
|
@@ -24,14 +24,8 @@ module BootstrapForm
|
|
|
24
24
|
|
|
25
25
|
def label_classes(name, options, custom_label_col, group_layout)
|
|
26
26
|
classes = ["form-label", options[:class], label_layout_classes(custom_label_col, group_layout)]
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
when true
|
|
30
|
-
classes << "required"
|
|
31
|
-
when nil, :default
|
|
32
|
-
classes << "required" if required_attribute?(object, name)
|
|
33
|
-
end
|
|
34
|
-
|
|
27
|
+
classes << "required" if required_field_options(options, name)[:required]
|
|
28
|
+
options.delete(:required)
|
|
35
29
|
classes << "text-danger" if label_errors && error?(name)
|
|
36
30
|
classes.flatten.compact
|
|
37
31
|
end
|
|
@@ -46,7 +40,7 @@ module BootstrapForm
|
|
|
46
40
|
|
|
47
41
|
def label_text(name, options)
|
|
48
42
|
if label_errors && error?(name)
|
|
49
|
-
(options[:text] || object.class.human_attribute_name(name)).to_s
|
|
43
|
+
(options[:text] || object.class.human_attribute_name(name)).to_s + " #{get_error_messages(name)}"
|
|
50
44
|
else
|
|
51
45
|
options[:text] || object&.class.try(:human_attribute_name, name)
|
|
52
46
|
end
|