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`. +![Example 16](demo/doc/screenshots/bootstrap/readme/16_example.png "Example 16") +```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: -![Example 16](demo/doc/screenshots/bootstrap/readme/16_example.png "Example 16") +![Example 17](demo/doc/screenshots/bootstrap/readme/17_example.png "Example 17") ```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: -![Example 17](demo/doc/screenshots/bootstrap/readme/17_example.png "Example 17") +![Example 18](demo/doc/screenshots/bootstrap/readme/18_example.png "Example 18") ```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: -![Example 18](demo/doc/screenshots/bootstrap/readme/18_example.png "Example 18") +![Example 19](demo/doc/screenshots/bootstrap/readme/19_example.png "Example 19") ```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: -![Example 19](demo/doc/screenshots/bootstrap/readme/19_example.png "Example 19") +![Example 20](demo/doc/screenshots/bootstrap/readme/20_example.png "Example 20") ```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: -![Example 20](demo/doc/screenshots/bootstrap/readme/20_example.png "Example 20") +![Example 21](demo/doc/screenshots/bootstrap/readme/21_example.png "Example 21") ```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: -![Example 21](demo/doc/screenshots/bootstrap/readme/21_example.png "Example 21") +![Example 22](demo/doc/screenshots/bootstrap/readme/22_example.png "Example 22") ```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: -![Example 22](demo/doc/screenshots/bootstrap/readme/22_example.png "Example 22") +![Example 23](demo/doc/screenshots/bootstrap/readme/23_example.png "Example 23") ```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`: -![Example 23](demo/doc/screenshots/bootstrap/readme/23_example.png "Example 23") +![Example 24](demo/doc/screenshots/bootstrap/readme/24_example.png "Example 24") ```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: -![Example 24](demo/doc/screenshots/bootstrap/readme/24_example.png "Example 24") +![Example 25](demo/doc/screenshots/bootstrap/readme/25_example.png "Example 25") ```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: -![Example 25](demo/doc/screenshots/bootstrap/readme/25_example.png "Example 25") +![Example 26](demo/doc/screenshots/bootstrap/readme/26_example.png "Example 26") ```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: -![Example 26](demo/doc/screenshots/bootstrap/readme/26_example.png "Example 26") +![Example 27](demo/doc/screenshots/bootstrap/readme/27_example.png "Example 27") ```erb <%= f.range_field :excellence %> ``` @@ -848,7 +862,7 @@ This generates: You can create a static control like this: -![Example 27](demo/doc/screenshots/bootstrap/readme/27_example.png "Example 27") +![Example 28](demo/doc/screenshots/bootstrap/readme/28_example.png "Example 28") ```erb <%= f.static_control :email %> ``` @@ -864,7 +878,7 @@ This generates: Here's the output for a horizontal layout: -![Example 28](demo/doc/screenshots/bootstrap/readme/28_example.png "Example 28") +![Example 29](demo/doc/screenshots/bootstrap/readme/29_example.png "Example 29") ```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: -![Example 29](demo/doc/screenshots/bootstrap/readme/29_example.png "Example 29") +![Example 30](demo/doc/screenshots/bootstrap/readme/30_example.png "Example 30") ```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: -![Example 30](demo/doc/screenshots/bootstrap/readme/30_example.png "Example 30") +![Example 31](demo/doc/screenshots/bootstrap/readme/31_example.png "Example 31") ```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. -![Example 31](demo/doc/screenshots/bootstrap/readme/31_example.png "Example 31") +![Example 32](demo/doc/screenshots/bootstrap/readme/32_example.png "Example 32") ```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: -![Example 32](demo/doc/screenshots/bootstrap/readme/32_example.png "Example 32") +![Example 33](demo/doc/screenshots/bootstrap/readme/33_example.png "Example 33") ```erb <%= f.primary "Optional Label" %> ``` @@ -965,7 +979,7 @@ This generates: You can specify your own classes like this: -![Example 33](demo/doc/screenshots/bootstrap/readme/33_example.png "Example 33") +![Example 34](demo/doc/screenshots/bootstrap/readme/34_example.png "Example 34") ```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 -![Example 34](demo/doc/screenshots/bootstrap/readme/34_example.png "Example 34") +![Example 35](demo/doc/screenshots/bootstrap/readme/35_example.png "Example 35") ```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 -![Example 35](demo/doc/screenshots/bootstrap/readme/35_example.png "Example 35") +![Example 36](demo/doc/screenshots/bootstrap/readme/36_example.png "Example 36") ```erb <%= f.primary "My Nice Button", extra_class: 'my-button' %> @@ -1033,7 +1047,7 @@ will be rendered as ## Rich Text Areas AKA Trix Editor -![Example 36](demo/doc/screenshots/bootstrap/readme/36_example.png "Example 36") +![Example 37](demo/doc/screenshots/bootstrap/readme/37_example.png "Example 37") ```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: -![Example 37](demo/doc/screenshots/bootstrap/readme/37_example.png "Example 37") +![Example 38](demo/doc/screenshots/bootstrap/readme/38_example.png "Example 38") ```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. -![Example 38](demo/doc/screenshots/bootstrap/readme/38_example.png "Example 38") +![Example 39](demo/doc/screenshots/bootstrap/readme/39_example.png "Example 39") ```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. -![Example 39](demo/doc/screenshots/bootstrap/readme/39_example.png "Example 39") +![Example 40](demo/doc/screenshots/bootstrap/readme/40_example.png "Example 40") ```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. -![Example 40](demo/doc/screenshots/bootstrap/readme/40_example.png "Example 40") +![Example 41](demo/doc/screenshots/bootstrap/readme/41_example.png "Example 41") ```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: -![Example 41](demo/doc/screenshots/bootstrap/readme/41_example.png "Example 41") +![Example 42](demo/doc/screenshots/bootstrap/readme/42_example.png "Example 42") ```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: -![Example 42](demo/doc/screenshots/bootstrap/readme/42_example.png "Example 42") +![Example 43](demo/doc/screenshots/bootstrap/readme/43_example.png "Example 43") ```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`: -![Example 43](demo/doc/screenshots/bootstrap/readme/43_example.png "Example 43") +![Example 44](demo/doc/screenshots/bootstrap/readme/44_example.png "Example 44") ```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: -![Example 44](demo/doc/screenshots/bootstrap/readme/44_example.png "Example 44") +![Example 45](demo/doc/screenshots/bootstrap/readme/45_example.png "Example 45") ```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: -![Example 45](demo/doc/screenshots/bootstrap/readme/45_example.png "Example 45") +![Example 46](demo/doc/screenshots/bootstrap/readme/46_example.png "Example 46") ```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: -![Example 46](demo/doc/screenshots/bootstrap/readme/46_example.png "Example 46") +![Example 47](demo/doc/screenshots/bootstrap/readme/47_example.png "Example 47") ```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. -![Example 47](demo/doc/screenshots/bootstrap/readme/47_example.png "Example 47") +![Example 48](demo/doc/screenshots/bootstrap/readme/48_example.png "Example 48") ```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: -![Example 48](demo/doc/screenshots/bootstrap/readme/48_example.png "Example 48") +![Example 49](demo/doc/screenshots/bootstrap/readme/49_example.png "Example 49") ```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. -![Example 49](demo/doc/screenshots/bootstrap/readme/49_example.png "Example 49") +![Example 50](demo/doc/screenshots/bootstrap/readme/50_example.png "Example 50") ```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. -![Example 50](demo/doc/screenshots/bootstrap/readme/50_example.png "Example 50") +![Example 51](demo/doc/screenshots/bootstrap/readme/51_example.png "Example 51") ```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: -![Example 51](demo/doc/screenshots/bootstrap/readme/51_example.png "Example 51") +![Example 52](demo/doc/screenshots/bootstrap/readme/52_example.png "Example 52") ```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: -![Example 52](demo/doc/screenshots/bootstrap/readme/52_example.png "Example 52") +![Example 53](demo/doc/screenshots/bootstrap/readme/53_example.png "Example 53") ```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: -![Example 53](demo/doc/screenshots/bootstrap/readme/53_example.png "Example 53") +![Example 54](demo/doc/screenshots/bootstrap/readme/54_example.png "Example 54") ```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. -![Example 54](demo/doc/screenshots/bootstrap/readme/54_example.png "Example 54") +![Example 55](demo/doc/screenshots/bootstrap/readme/55_example.png "Example 55") ```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. -![Example 55](demo/doc/screenshots/bootstrap/readme/55_example.png "Example 55") +![Example 56](demo/doc/screenshots/bootstrap/readme/56_example.png "Example 56") ```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