diff --git a/.rubocop.yml b/.rubocop.yml
index 15e25d3f..af7b7d59 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -39,9 +39,7 @@ Layout/SpaceAroundEqualsInParameterDefault:
Metrics/AbcSize:
Max: 18
- Exclude:
- - "demo/test/**/*"
- - "test/**/*"
+ Enabled: false
Metrics/BlockLength:
Exclude:
diff --git a/README.md b/README.md
index 28eb4a7a..1eb5f668 100644
--- a/README.md
+++ b/README.md
@@ -548,11 +548,25 @@ It's just a short form of `wrapper: { class: 'mb-3 additional-class' }`.
If you don't want any class on the form group div, you can set it to `false`: `wrapper_class: false`.
+
+```erb
+<%= f.text_field :name, wrapper: { class: false } %>
+```
+
+This generates:
+
+```html
+
+
+
+
+```
+
### Suppressing the Form Group Altogether
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:
-
+
```erb
<%= f.form_group :user do %>
<%= f.email_field :email, wrapper: false %>
@@ -573,7 +587,7 @@ Note that Bootstrap relies on the form group div to correctly format most fields
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:
-
+
```erb
<%= f.select :product, [["Apple", 1], ["Grape", 2]], { label: "Choose your favorite fruit:", wrapper: { class: 'has-warning', data: { foo: 'bar' } } }, { class: "selectpicker" } %>
```
@@ -596,7 +610,7 @@ Checkboxes and radios should be placed inside of a `form_group` to render
properly. The following example ensures that the entire form group will display
an error if an associated validations fails:
-
+
```erb
<%= f.form_group :skill_level, label: { text: "Skill" }, help: "Optional Help Text" do %>
<%= f.radio_button :skill_level, 0, label: "Novice", checked: true %>
@@ -639,7 +653,7 @@ This generates:
You can also create a checkbox using a block:
-
+
```erb
<%= f.form_group :terms, label: { text: "Optional Label" } do %>
<%= f.check_box :terms do %>
@@ -665,7 +679,7 @@ This generates:
To display checkboxes and radios inline, pass the `inline: true` option:
-
+
```erb
<%= f.form_group :skill_level, label: { text: "Skill" } do %>
<%= f.radio_button :skill_level, 0, label: "Novice", inline: true %>
@@ -696,7 +710,7 @@ This generates:
Check boxes and radio buttons are wrapped in a `div.form-check`. You can add classes to this `div` with the `:wrapper_class` option:
-
+
```erb
<%= f.radio_button :skill_level, 0, label: "Novice", inline: true, wrapper_class: "w-auto" %>
```
@@ -712,7 +726,7 @@ This generates:
You can also add a style to the tag using the `wrapper` option:
-
+
```erb
<%= f.check_box :skilled, inline: true, wrapper: {style: "color: green"} %>
<%= f.radio_button :skill_level, 0, label: "Novice", inline: true, wrapper: {class: 'w-auto', style: "color: red"} %>
@@ -736,7 +750,7 @@ This generates:
To render checkboxes as switches with Bootstrap 4.2+, use `switch: true`:
-
+
```erb
<%= f.check_box :remember_me, switch: true %>
```
@@ -756,7 +770,7 @@ This generates:
`bootstrap_form` also provides helpers that automatically create the
`form_group` and the `radio_button`s or `check_box`es for you:
-
+
```erb
<%= f.collection_radio_buttons :skill_level, Skill.all, :id, :name %>
<%= f.collection_check_boxes :skills, Skill.all, :id, :name %>
@@ -802,7 +816,7 @@ Collection methods accept these options:
To add `data-` attributes to a collection of radio buttons, map your models to an array and add a hash:
-
+
```erb
<%# Use the :first and :second elements of the array to be the value and label respectively %>
<%- choices = @collection.map { |addr| [ addr.id, addr.street, { 'data-zip-code': addr.zip_code } ] } -%>
@@ -830,7 +844,7 @@ This generates:
You can create a range control like this:
-
+
```erb
<%= f.range_field :excellence %>
```
@@ -848,7 +862,7 @@ This generates:
You can create a static control like this:
-
+
```erb
<%= f.static_control :email %>
```
@@ -864,7 +878,7 @@ This generates:
Here's the output for a horizontal layout:
-
+
```erb
<%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
<%= f.static_control :email %>
@@ -886,7 +900,7 @@ This generates:
You can also create a static control that isn't based on a model attribute:
-
+
```erb
<%= f.static_control :field_name, label: "Custom Static Control", value: "Content Here" %>
```
@@ -904,7 +918,7 @@ This generates:
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:
-
+
```erb
<%= f.static_control label: "Custom Static Control", value: "Content Here", name: nil %>
```
@@ -938,7 +952,7 @@ this by defining these selects as `inline-block` and a width of `auto`.
The `btn btn-secondary` CSS classes are automatically added to your submit
buttons.
-
+
```erb
<%= f.submit %>
```
@@ -952,7 +966,7 @@ This generates:
You can also use the `primary` helper, which adds `btn btn-primary` to your
submit button:
-
+
```erb
<%= f.primary "Optional Label" %>
```
@@ -965,7 +979,7 @@ This generates:
You can specify your own classes like this:
-
+
```erb
<%= f.submit "Log In", class: "btn btn-success" %>
```
@@ -981,7 +995,7 @@ it will be rendered as an HTML button, instead of an input tag. This allows you
to specify HTML content and styling for your buttons (such as adding
illustrative icons to them). For example, the following statements
-
+
```erb
<%= f.primary "Save changes ".html_safe, render_as_button: true %>
@@ -1015,7 +1029,7 @@ Bootstrap classes), or for element targeting via CSS classes.
Be aware, however, that using the `class` option will discard any extra classes
you add. As an example, the following button declarations
-
+
```erb
<%= f.primary "My Nice Button", extra_class: 'my-button' %>
@@ -1033,7 +1047,7 @@ will be rendered as
## Rich Text Areas AKA Trix Editor
-
+
```erb
<%= f.rich_text_area(:life_story) %>
```
@@ -1101,7 +1115,7 @@ The `hidden_field` helper in `bootstrap_form` calls the Rails helper directly, a
If you want to use the original Rails form helpers for a particular field,
append `_without_bootstrap` to the helper:
-
+
```erb
<%= f.text_field_without_bootstrap :email %>
```
@@ -1123,7 +1137,7 @@ To use an inline-layout form, use the `layout: :inline` option. To hide labels,
use the `hide_label: true` option, which keeps your labels accessible to those
using screen readers.
-
+
```erb
<%= bootstrap_form_for(@user, layout: :inline) do |f| %>
<%= f.email_field :email, hide_label: true %>
@@ -1160,7 +1174,7 @@ This generates:
To skip label rendering at all, use `skip_label: true` option.
-
+
```erb
<%= f.password_field :password, skip_label: true %>
```
@@ -1182,7 +1196,7 @@ To use a horizontal-layout form with labels to the left of the control, use the
In the example below, the submit button has been wrapped in a `form_group` to
keep it properly aligned.
-
+
```erb
<%= bootstrap_form_for(@user, layout: :horizontal, label_col: "col-sm-2", control_col: "col-sm-10") do |f| %>
<%= f.email_field :email %>
@@ -1229,7 +1243,7 @@ This generates:
The `label_col` and `control_col` css classes can also be changed per control:
-
+
```erb
<%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
<%= f.email_field :email %>
@@ -1296,7 +1310,7 @@ end
Control col wrapper class can be modified with `add_control_col_class`. This option will preserve column definition:
-
+
```erb
<%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
<%= f.email_field :email %>
@@ -1335,7 +1349,7 @@ This generates:
The form-level `layout` can be overridden per field, unless the form-level layout was `inline`:
-
+
```erb
<%= bootstrap_form_for(@user, layout: :horizontal) do |f| %>
<%= f.email_field :email %>
@@ -1390,7 +1404,7 @@ A form-level `layout: :inline` can't be overridden because of the way Bootstrap
The `floating` option can be used to enable Bootstrap 5's floating labels. This option is supported on text fields
and dropdowns. Here's an example:
-
+
```erb
<%= bootstrap_form_for(@user) do |f| %>
<%= f.email_field :email, floating: true %>
@@ -1438,7 +1452,7 @@ Rails normally wraps fields with validation errors in a `div.field_with_errors`,
By default, fields that have validation errors will be outlined in red and the
error will be displayed below the field. Here's an example:
-
+
```erb
<%= bootstrap_form_for(@user_with_error) do |f| %>
<%= f.email_field :email %>
@@ -1505,7 +1519,7 @@ You can turn off inline errors for the entire form like this:
You can also display validation errors in the field's label; just turn
on the `:label_errors` option. Here's an example:
-
+
```erb
<%= bootstrap_form_for(@user_with_error, label_errors: true) do |f| %>
<%= f.email_field :email %>
@@ -1538,7 +1552,7 @@ To display an error message with an error summary, you can use the
`alert_message` helper. This won't output anything unless a model validation
has failed.
-
+
```erb
<%= bootstrap_form_for @user_with_error do |f| %>
<%= f.alert_message "Please fix the errors below." %>
@@ -1562,7 +1576,7 @@ Which outputs:
You can turn off the error summary like this:
-
+
```erb
<%= bootstrap_form_for @user_with_error do |f| %>
<%= f.alert_message "Please fix the errors below.", error_summary: false %>
@@ -1579,7 +1593,7 @@ This generates:
To output a simple unordered list of errors, use the `error_summary` helper.
-
+
```erb
<%= bootstrap_form_for @user_with_error do |f| %>
<%= f.error_summary %>
@@ -1602,7 +1616,7 @@ Which outputs:
If you want to display a custom inline error for a specific attribute not represented by a form field, use the `errors_on` helper.
-
+
```erb
<%= bootstrap_form_for @user_with_error do |f| %>
@@ -1623,7 +1637,7 @@ Note that the `invalid-feedback` `div` is hidden unless there is a preceding ele
You can hide the attribute name like this:
-
+
```erb
<%= bootstrap_form_for @user_with_error do |f| %>
@@ -1642,7 +1656,7 @@ Which outputs:
You can also use a custom class for the wrapping div, like this:
-
+
```erb
<%= bootstrap_form_for @user_with_error do |f| %>
@@ -1681,7 +1695,7 @@ ActiveModel::Validations::PresenceValidator.
In cases where this behaviour is undesirable, use the `required` option to force the class to be present or absent:
-
+
```erb
<%= f.password_field :login, label: "New Username", required: true %>
<%= f.password_field :password, label: "New Password", required: false %>
@@ -1704,7 +1718,7 @@ This generates:
Adding a form control for a `belongs_to` field will automatically pick up the associated presence validator.
-
+
```erb
<%= bootstrap_form_for(@address, url: '/address') do |f| %>
<%= f.collection_select :user_id, @users, :id, :email, include_blank: "Select a value" %>
@@ -1751,7 +1765,7 @@ Generated HTML:
Fields can be disabled using the standard Rails form helper option.
-
+
```erb
<%= bootstrap_form_for @user do |f| %>
diff --git a/demo/app/models/user.rb b/demo/app/models/user.rb
index 34293855..52ea3a4a 100644
--- a/demo/app/models/user.rb
+++ b/demo/app/models/user.rb
@@ -3,7 +3,7 @@ class User < ApplicationRecord
serialize :preferences, coder: JSON
- validates :email, presence: true, length: { minimum: 5 }, if: :always
+ validates :email, presence: true, length: { minimum: 5 }, if: :always?
validates :terms, acceptance: { accept: true }
# Conditional (always disabled) validators used in tests
@@ -15,7 +15,7 @@ class User < ApplicationRecord
has_rich_text(:life_story)
- def always # rubocop:disable Naming/PredicateMethod
+ def always?
true
end
diff --git a/demo/doc/screenshots/bootstrap/readme/16_example.png b/demo/doc/screenshots/bootstrap/readme/16_example.png
index 379bc3f4..ecea0144 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/16_example.png and b/demo/doc/screenshots/bootstrap/readme/16_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/17_example.png b/demo/doc/screenshots/bootstrap/readme/17_example.png
index 586e26a1..379bc3f4 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/17_example.png and b/demo/doc/screenshots/bootstrap/readme/17_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/18_example.png b/demo/doc/screenshots/bootstrap/readme/18_example.png
index 45426a41..586e26a1 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/18_example.png and b/demo/doc/screenshots/bootstrap/readme/18_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/19_example.png b/demo/doc/screenshots/bootstrap/readme/19_example.png
index 8cf822aa..45426a41 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/19_example.png and b/demo/doc/screenshots/bootstrap/readme/19_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/20_example.png b/demo/doc/screenshots/bootstrap/readme/20_example.png
index d38bbf0e..8cf822aa 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/20_example.png and b/demo/doc/screenshots/bootstrap/readme/20_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/21_example.png b/demo/doc/screenshots/bootstrap/readme/21_example.png
index 5e20c632..d38bbf0e 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/21_example.png and b/demo/doc/screenshots/bootstrap/readme/21_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/22_example.png b/demo/doc/screenshots/bootstrap/readme/22_example.png
index 54c7d85b..5e20c632 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/22_example.png and b/demo/doc/screenshots/bootstrap/readme/22_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/23_example.png b/demo/doc/screenshots/bootstrap/readme/23_example.png
index 61ef9c01..54c7d85b 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/23_example.png and b/demo/doc/screenshots/bootstrap/readme/23_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/24_example.png b/demo/doc/screenshots/bootstrap/readme/24_example.png
index da055a51..61ef9c01 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/24_example.png and b/demo/doc/screenshots/bootstrap/readme/24_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/25_example.png b/demo/doc/screenshots/bootstrap/readme/25_example.png
index 5408da93..da055a51 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/25_example.png and b/demo/doc/screenshots/bootstrap/readme/25_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/26_example.png b/demo/doc/screenshots/bootstrap/readme/26_example.png
index a864ec64..5408da93 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/26_example.png and b/demo/doc/screenshots/bootstrap/readme/26_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/27_example.png b/demo/doc/screenshots/bootstrap/readme/27_example.png
index 1df0a867..a864ec64 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/27_example.png and b/demo/doc/screenshots/bootstrap/readme/27_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/28_example.png b/demo/doc/screenshots/bootstrap/readme/28_example.png
index 68a8a708..1df0a867 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/28_example.png and b/demo/doc/screenshots/bootstrap/readme/28_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/29_example.png b/demo/doc/screenshots/bootstrap/readme/29_example.png
index eda66777..68a8a708 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/29_example.png and b/demo/doc/screenshots/bootstrap/readme/29_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/31_example.png b/demo/doc/screenshots/bootstrap/readme/31_example.png
index 0dbd943f..eda66777 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/31_example.png and b/demo/doc/screenshots/bootstrap/readme/31_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/32_example.png b/demo/doc/screenshots/bootstrap/readme/32_example.png
index c2e9ac3e..0dbd943f 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/32_example.png and b/demo/doc/screenshots/bootstrap/readme/32_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/33_example.png b/demo/doc/screenshots/bootstrap/readme/33_example.png
index cd7f8118..c2e9ac3e 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/33_example.png and b/demo/doc/screenshots/bootstrap/readme/33_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/34_example.png b/demo/doc/screenshots/bootstrap/readme/34_example.png
index 63b851c0..cd7f8118 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/34_example.png and b/demo/doc/screenshots/bootstrap/readme/34_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/35_example.png b/demo/doc/screenshots/bootstrap/readme/35_example.png
index 1bc46168..63b851c0 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/35_example.png and b/demo/doc/screenshots/bootstrap/readme/35_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/36_example.png b/demo/doc/screenshots/bootstrap/readme/36_example.png
index f4d76bb7..1bc46168 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/36_example.png and b/demo/doc/screenshots/bootstrap/readme/36_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/37_example.png b/demo/doc/screenshots/bootstrap/readme/37_example.png
index 993f43d6..f4d76bb7 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/37_example.png and b/demo/doc/screenshots/bootstrap/readme/37_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/38_example.png b/demo/doc/screenshots/bootstrap/readme/38_example.png
index a51825eb..993f43d6 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/38_example.png and b/demo/doc/screenshots/bootstrap/readme/38_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/39_example.png b/demo/doc/screenshots/bootstrap/readme/39_example.png
index bcb761e9..a51825eb 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/39_example.png and b/demo/doc/screenshots/bootstrap/readme/39_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/40_example.png b/demo/doc/screenshots/bootstrap/readme/40_example.png
index 433d10a5..bcb761e9 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/40_example.png and b/demo/doc/screenshots/bootstrap/readme/40_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/41_example.png b/demo/doc/screenshots/bootstrap/readme/41_example.png
index 9d870ab7..433d10a5 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/41_example.png and b/demo/doc/screenshots/bootstrap/readme/41_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/42_example.png b/demo/doc/screenshots/bootstrap/readme/42_example.png
index 07ba29be..9d870ab7 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/42_example.png and b/demo/doc/screenshots/bootstrap/readme/42_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/43_example.png b/demo/doc/screenshots/bootstrap/readme/43_example.png
index 4c45e77a..07ba29be 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/43_example.png and b/demo/doc/screenshots/bootstrap/readme/43_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/44_example.png b/demo/doc/screenshots/bootstrap/readme/44_example.png
index 1a804a98..4c45e77a 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/44_example.png and b/demo/doc/screenshots/bootstrap/readme/44_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/45_example.png b/demo/doc/screenshots/bootstrap/readme/45_example.png
index 1116bc52..1a804a98 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/45_example.png and b/demo/doc/screenshots/bootstrap/readme/45_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/46_example.png b/demo/doc/screenshots/bootstrap/readme/46_example.png
index f57ab1b9..1116bc52 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/46_example.png and b/demo/doc/screenshots/bootstrap/readme/46_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/47_example.png b/demo/doc/screenshots/bootstrap/readme/47_example.png
index de9655e7..f57ab1b9 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/47_example.png and b/demo/doc/screenshots/bootstrap/readme/47_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/48_example.png b/demo/doc/screenshots/bootstrap/readme/48_example.png
index dd04773c..de9655e7 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/48_example.png and b/demo/doc/screenshots/bootstrap/readme/48_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/49_example.png b/demo/doc/screenshots/bootstrap/readme/49_example.png
index b065278c..dd04773c 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/49_example.png and b/demo/doc/screenshots/bootstrap/readme/49_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/50_example.png b/demo/doc/screenshots/bootstrap/readme/50_example.png
index 07dc83a0..b065278c 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/50_example.png and b/demo/doc/screenshots/bootstrap/readme/50_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/51_example.png b/demo/doc/screenshots/bootstrap/readme/51_example.png
index d0c6f864..07dc83a0 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/51_example.png and b/demo/doc/screenshots/bootstrap/readme/51_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/52_example.png b/demo/doc/screenshots/bootstrap/readme/52_example.png
index 340e9244..d0c6f864 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/52_example.png and b/demo/doc/screenshots/bootstrap/readme/52_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/53_example.png b/demo/doc/screenshots/bootstrap/readme/53_example.png
index a6451827..340e9244 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/53_example.png and b/demo/doc/screenshots/bootstrap/readme/53_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/54_example.png b/demo/doc/screenshots/bootstrap/readme/54_example.png
index b461c59f..a6451827 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/54_example.png and b/demo/doc/screenshots/bootstrap/readme/54_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/55_example.png b/demo/doc/screenshots/bootstrap/readme/55_example.png
index f116d753..b461c59f 100644
Binary files a/demo/doc/screenshots/bootstrap/readme/55_example.png and b/demo/doc/screenshots/bootstrap/readme/55_example.png differ
diff --git a/demo/doc/screenshots/bootstrap/readme/56_example.png b/demo/doc/screenshots/bootstrap/readme/56_example.png
new file mode 100644
index 00000000..f116d753
Binary files /dev/null and b/demo/doc/screenshots/bootstrap/readme/56_example.png differ
diff --git a/gemfiles/8.0.gemfile b/gemfiles/8.0.gemfile
index c25dfc7e..9e8686ae 100644
--- a/gemfiles/8.0.gemfile
+++ b/gemfiles/8.0.gemfile
@@ -4,6 +4,6 @@ eval File.read(gems), binding, gems # rubocop: disable Security/Eval
gem "bigdecimal" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0")
gem "drb" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0")
gem "mutex_m" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0")
-gem "rails", "~> 8.0.1"
gem "propshaft"
+gem "rails", "~> 8.0.1"
gem "sqlite3"
diff --git a/gemfiles/edge.gemfile b/gemfiles/edge.gemfile
index 62ef2e13..e0e3f56e 100644
--- a/gemfiles/edge.gemfile
+++ b/gemfiles/edge.gemfile
@@ -4,6 +4,6 @@ eval File.read(gems), binding, gems # rubocop: disable Security/Eval
gem "bigdecimal" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0")
gem "drb" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0")
gem "mutex_m" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0")
-gem "rails", git: "https://github.com/rails/rails.git", branch: "main"
gem "propshaft"
+gem "rails", git: "https://github.com/rails/rails.git", branch: "main"
gem "sqlite3"
diff --git a/lib/bootstrap_form/components/validation.rb b/lib/bootstrap_form/components/validation.rb
index 4c9c7400..affba190 100644
--- a/lib/bootstrap_form/components/validation.rb
+++ b/lib/bootstrap_form/components/validation.rb
@@ -71,7 +71,6 @@ def generate_error(name)
content_tag(help_tag, help_text, class: help_klass)
end
- # rubocop:disable Metrics/AbcSize
def get_error_messages(name)
object.class.try(:reflections)&.each do |association_name, a|
next unless a.is_a?(ActiveRecord::Reflection::BelongsToReflection)
diff --git a/lib/bootstrap_form/form_group.rb b/lib/bootstrap_form/form_group.rb
index 5039aa71..c244f4b2 100644
--- a/lib/bootstrap_form/form_group.rb
+++ b/lib/bootstrap_form/form_group.rb
@@ -29,7 +29,7 @@ def form_group_content_tag(name, field_name, without_field_name, options, html_o
end
end
- def form_group_content(label, help_text, options, &) # rubocop:disable Metrics/AbcSize
+ def form_group_content(label, help_text, options, &)
label ||= ActiveSupport::SafeBuffer.new
if group_layout_horizontal?(options[:layout])
label + tag.div(capture(&) + help_text, class: form_group_control_class(options))
diff --git a/lib/bootstrap_form/inputs/check_box.rb b/lib/bootstrap_form/inputs/check_box.rb
index 3c44ec6c..a902259e 100644
--- a/lib/bootstrap_form/inputs/check_box.rb
+++ b/lib/bootstrap_form/inputs/check_box.rb
@@ -84,7 +84,10 @@ def check_box_label_class(options)
def check_box_wrapper_class(options)
classes = ["form-check"]
classes << "form-check-inline" if layout_inline?(options[:inline])
- classes << "mb-3" unless options[:multiple] || %i[horizontal inline].include?(layout)
+ classes << "mb-3" unless options[:multiple] ||
+ %i[horizontal inline].include?(layout) ||
+ options[:wrapper_class] == false ||
+ options.dig(:wrapper, :class) == false
classes << "form-switch" if options[:switch]
classes << options.dig(:wrapper, :class).presence
classes << options[:wrapper_class].presence
diff --git a/test/bootstrap_checkbox_test.rb b/test/bootstrap_checkbox_test.rb
index 6fdfd454..674dc198 100644
--- a/test/bootstrap_checkbox_test.rb
+++ b/test/bootstrap_checkbox_test.rb
@@ -623,6 +623,20 @@ class BootstrapCheckboxTest < ActionView::TestCase
assert_equivalent_html expected, @builder.check_box(:terms, label: "I agree to the terms", wrapper_class: "custom-class")
end
+ test "check box with custom wrapper class false" do
+ expected = <<~HTML
+
+
+
+
+
+ HTML
+ assert_equivalent_html expected, @builder.check_box(:terms, label: "I agree to the terms", wrapper_class: false)
+ assert_equivalent_html expected, @builder.check_box(:terms, label: "I agree to the terms", wrapper: { class: false })
+ end
+
test "inline check box with custom wrapper class" do
expected = <<~HTML
diff --git a/test/bootstrap_fields_test.rb b/test/bootstrap_fields_test.rb
index 8d39d9d7..cdb2dea8 100644
--- a/test/bootstrap_fields_test.rb
+++ b/test/bootstrap_fields_test.rb
@@ -233,6 +233,28 @@ class BootstrapFieldsTest < ActionView::TestCase
assert_equivalent_html expected, @builder.text_field(:email)
end
+ test "text fields are wrapped correctly with wrapper_class and wrapper: { class: 'custom-class' }" do
+ expected = <<~HTML
+
+
+
+
+ HTML
+ assert_equivalent_html expected, @builder.text_field(:email, wrapper_class: "custom-class")
+ assert_equivalent_html expected, @builder.text_field(:email, wrapper: { class: "custom-class" })
+ end
+
+ test "text fields are wrapped correctly with wrapper_class false" do
+ expected = <<~HTML
+
+
+
+
+ HTML
+ assert_equivalent_html expected, @builder.text_field(:email, wrapper_class: false)
+ assert_equivalent_html expected, @builder.text_field(:email, wrapper: { class: false })
+ end
+
test "text fields are wrapped correctly when horizontal and gutter classes are given" do
expected = <<~HTML
diff --git a/test/bootstrap_radio_button_test.rb b/test/bootstrap_radio_button_test.rb
index fa922607..1b64a455 100644
--- a/test/bootstrap_radio_button_test.rb
+++ b/test/bootstrap_radio_button_test.rb
@@ -423,6 +423,21 @@ class BootstrapRadioButtonTest < ActionView::TestCase
@builder.radio_button(:misc, "1", label: "This is a radio button", wrapper_class: "custom-class")
end
+ test "radio button with wrapper class false" do
+ expected = <<~HTML
+
+
+
+
+ HTML
+ assert_equivalent_html expected,
+ @builder.radio_button(:misc, "1", label: "This is a radio button", wrapper_class: false)
+ assert_equivalent_html expected,
+ @builder.radio_button(:misc, "1", label: "This is a radio button", wrapper: { class: false })
+ end
+
test "inline radio button with custom wrapper class" do
expected = <<~HTML