Skip to content

Commit

Permalink
Set required and aria on input when input is required
Browse files Browse the repository at this point in the history
fixes #604
  • Loading branch information
Charlotte Hanekamp committed Nov 1, 2021
1 parent dd64827 commit d32c9fb
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 58 deletions.
9 changes: 9 additions & 0 deletions demo/app/assets/stylesheets/actiontext.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,12 @@
}
}
}
label.required {
&:after {
color: red;
content: '*';
}
}
input[required="required"]{
border: 1px solid red;
}
15 changes: 15 additions & 0 deletions demo/app/views/bootstrap/form.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
<h3>Horizontal Form</h3>

<%= form_with_source do %>
<%= bootstrap_form_with model: @user, layout: :horizontal, local: true do |form| %>
<%= form.text_field :email, placeholder: "Enter Email", label: "Email address", help: "Email pressence true" %>
<%= form.text_field :email, placeholder: "Enter Email", label: "Email address", help: "Email pressence true with required false", required: false %>
<%= form.text_field :email, placeholder: "Enter Email", label: "Email address", help: "Email pressence true with skip required false", skip_required: false %>
<%= form.text_field :email, placeholder: "Enter Email", label: "Email address", help: "Email pressence true with skip required true", skip_required: true %>
<%= form.text_field :misc, placeholder: "Enter Misc", label: "Misc", help: "Misc not required by model" %>
<%= form.text_field :misc, placeholder: "Enter Misc", label: "Misc", help: "Misc not required by model with required true", required: true %>
<%= form.text_field :misc, placeholder: "Enter Misc", label: "Misc", help: "Misc not required by model with required false", required: false %>
<%= form.text_field :comments, required: true %>
<%= form.check_box :misc, switch: true %>
<%= form.submit %>
<% end %>
<% end %>
<%= form_with_source do %>
<%= bootstrap_form_with model: @user, layout: :horizontal, local: true do |form| %>
<%= form.email_field :email, placeholder: "Enter Email", label: "Email address", help: "We'll never share your email with anyone else" %>
Expand Down
17 changes: 11 additions & 6 deletions lib/bootstrap_form/form_group_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ def form_group_builder(method, options, html_options=nil, &block)
def form_group_builder_options(options, method)
options.symbolize_keys!
options = convert_form_tag_options(method, options) if acts_like_form_tag
options[:required] = form_group_required(options) if !options[:skip_label] && options.key?(:skip_required)
options[:required] = form_group_required(options, method)
options[:aria] = { required: true } if options[:required]
options
end

Expand Down Expand Up @@ -77,11 +78,15 @@ def form_group_label_class(options)
classes
end

def form_group_required(options)
return unless options.key?(:skip_required)

warn "`:skip_required` is deprecated, use `:required: false` instead"
options[:skip_required] ? false : :default
def form_group_required(options, method)
if options[:skip_required]
warn "`:skip_required` is deprecated, use `:required: false` instead"
false
elsif options.key?(:required)
options[:required]
else
required_attribute?(object, method)
end
end

def form_group_css_options(method, html_options, options)
Expand Down
13 changes: 9 additions & 4 deletions lib/bootstrap_form/inputs/check_box.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@ module CheckBox
included do
def check_box_with_bootstrap(name, options={}, checked_value="1", unchecked_value="0", &block)
options = options.symbolize_keys!
check_box_options = options.except(:class, :label, :label_class, :error_message, :help,
:inline, :hide_label, :skip_label, :wrapper_class, :switch)
check_box_options[:class] = check_box_classes(name, options)

tag.div(class: check_box_wrapper_class(options)) do
html = check_box_without_bootstrap(name, check_box_options, checked_value, unchecked_value)
html = check_box_without_bootstrap(name, check_box_options(name, options), checked_value, unchecked_value)
html.concat(check_box_label(name, options, checked_value, &block)) unless options[:skip_label]
html.concat(generate_error(name)) if options[:error_message]
html
Expand All @@ -26,6 +23,14 @@ def check_box_with_bootstrap(name, options={}, checked_value="1", unchecked_valu

private

def check_box_options(name, options)
check_box_options = options.except(:class, :label, :label_class, :error_message, :help,
:inline, :hide_label, :skip_label, :wrapper_class, :switch)
check_box_options[:class] = check_box_classes(name, options)
check_box_options[:aria] = { required: true } if options[:required]
check_box_options
end

def check_box_label(name, options, checked_value, &block)
label_name = if options[:multiple]
check_box_value(name, checked_value)
Expand Down
8 changes: 4 additions & 4 deletions test/bootstrap_fields_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ class BootstrapFieldsTest < ActionView::TestCase
expected = <<~HTML
<div class="mb-3">
<label class="form-label required" for="user_email">Email</label>
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:email)
Expand All @@ -218,7 +218,7 @@ class BootstrapFieldsTest < ActionView::TestCase
<div class="mb-3 g-3">
<label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
<div class="col-sm-10">
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
</div>
HTML
Expand All @@ -230,7 +230,7 @@ class BootstrapFieldsTest < ActionView::TestCase
expected = <<~HTML
<div class="mb-3">
<label class="form-label required" for="custom_id">Email</label>
<input class="form-control" id="custom_id" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="custom_id" name="user[email]" type="text" value="steve@example.com" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:email, id: :custom_id)
Expand Down Expand Up @@ -420,7 +420,7 @@ class BootstrapFieldsTest < ActionView::TestCase
test "can have a floating label" do
expected = <<~HTML
<div class="mb-3 form-floating">
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" placeholder="Email" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" placeholder="Email" />
<label class="form-label required" for="user_email">Email</label>
</div>
HTML
Expand Down
46 changes: 23 additions & 23 deletions test/bootstrap_form_group_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
expected = <<~HTML
<div class="mb-3">
<label class="form-label required" for="user_email">Email Address</label>
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:email, label: "Email Address")
Expand All @@ -19,7 +19,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
expected = <<~HTML
<div class="mb-3">
<label class="form-label required" for="user_email">Email Address</label>
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:email, label: { text: "Email Address" })
Expand All @@ -29,7 +29,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
expected = <<~HTML
<div class="mb-3">
<label class="form-label sr-only required" for="user_email">Email</label>
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:email, hide_label: true)
Expand All @@ -39,7 +39,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
expected = <<~HTML
<div class="mb-3">
<label class="form-label btn required" for="user_email">Email</label>
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:email, label_class: "btn")
Expand All @@ -49,7 +49,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
expected = <<~HTML
<div class="mb-3">
<label class="form-label btn required" for="user_email">Email</label>
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:email, label: { class: "btn" })
Expand All @@ -59,7 +59,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
expected = <<~HTML
<div class="mb-3">
<label class="form-label btn required" for="user_email">Email Address</label>
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:email, label: { class: "btn", text: "Email Address" })
Expand All @@ -68,7 +68,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
test "skipping a label" do
expected = <<~HTML
<div class="mb-3">
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:email, skip_label: true)
Expand Down Expand Up @@ -100,7 +100,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
expected = <<~HTML
<div class="mb-3">
<label class="form-label required" for="user_comments">Comments</label>
<input class="form-control" id="user_comments" name="user[comments]" type="text" value="my comment" required="required" />
<input aria-required="true" required="required" class="form-control" id="user_comments" name="user[comments]" type="text" value="my comment" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:comments, required: true)
Expand All @@ -110,7 +110,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
expected = <<~HTML
<div class="mb-3">
<label class="form-label sr-only required" for="user_email">Email</label>
<input class="form-control" id="user_email" placeholder="Email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" placeholder="Email" name="user[email]" type="text" value="steve@example.com" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:email, label_as_placeholder: true)
Expand All @@ -122,7 +122,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
<label class="form-label required" for="user_email">Email</label>
<div class="input-group">
<span class="input-group-text">@</span>
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
</div>
HTML
Expand All @@ -134,7 +134,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
<div class="mb-3">
<label class="form-label required" for="user_email">Email</label>
<div class="input-group">
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<span class="input-group-text">.00</span>
</div>
</div>
Expand All @@ -144,7 +144,7 @@ class BootstrapFormGroupTest < ActionView::TestCase

test "append and prepend button" do
prefix = '<div class="mb-3"><label class="form-label required" for="user_email">Email</label><div class="input-group">'
field = '<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />'
field = '<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />'
button_src = link_to("Click", "#", class: "btn btn-secondary")
button_prepend = button_src
button_append = button_src
Expand All @@ -165,7 +165,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
<label class="form-label required" for="user_email">Email</label>
<div class="input-group">
<span class="input-group-text">$</div>
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<span class="input-group-text">.00</span>
</div>
</div>
Expand All @@ -184,7 +184,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
<label class="form-label required" for="user_email">Email</label>
<div class="input-group">
<span class="input-group-text">$</div>
<input class="form-control is-invalid" id="user_email" name="user[email]" type="text" />
<input aria-required="true" required="required" class="form-control is-invalid" id="user_email" name="user[email]" type="text" />
<span class="input-group-text">.00</span>
<div class="invalid-feedback">can't be blank, is too short (minimum is 5 characters)</span>
</div>
Expand All @@ -198,7 +198,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
expected = <<~HTML
<div class="mb-3">
<label class="form-label required" for="user_email">Email</label>
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<small class="form-text text-muted">This is required</small>
</div>
HTML
Expand All @@ -210,7 +210,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
<div class="mb-3 row">
<label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
<div class="col-sm-10">
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<small class="form-text text-muted">This is required</small>
</div>
</div>
Expand Down Expand Up @@ -462,7 +462,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
<label class="form-label required" for="user_email">Email</label>
</div>
<div class="field_with_errors">
<input class="form-control is-invalid" id="user_email" name="user[email]" type="email" />
<input aria-required="true" required="required" class="form-control is-invalid" id="user_email" name="user[email]" type="email" />
</div>
<div class="invalid-feedback">can't be blank, is too short (minimum is 5 characters)</div>
</div>
Expand All @@ -483,7 +483,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
#{'<input name="utf8" type="hidden" value="&#x2713;"/>' unless ::Rails::VERSION::STRING >= '6'}
<div class="mb-3 none-margin">
<label class="form-label required" for="user_email">Email</label>
<input class="form-control is-invalid" id="user_email" name="user[email]" type="text" />
<input aria-required="true" required="required" class="form-control is-invalid" id="user_email" name="user[email]" type="text" />
<div class="invalid-feedback">can't be blank, is too short (minimum is 5 characters)</div>
</div>
</form>
Expand Down Expand Up @@ -536,7 +536,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
<div class="mb-3 row">
<label class="form-label col-form-label col-sm-2 required" for="user_email">Email</label>
<div class="col-sm-10">
<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
</div>
HTML
Expand All @@ -554,15 +554,15 @@ class BootstrapFormGroupTest < ActionView::TestCase
end

test "rendering without wrapper" do
expected = '<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />'
expected = '<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />'
assert_equivalent_xml expected, @builder.text_field(:email, wrapper: false)
end

test "passing options to a form control get passed through" do
expected = <<~HTML
<div class="mb-3">
<label class="form-label required" for="user_email">Email</label>
<input autofocus="autofocus" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
<input aria-required="true" required="required" autofocus="autofocus" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />
</div>
HTML
assert_equivalent_xml expected, @builder.text_field(:email, autofocus: true)
Expand All @@ -587,7 +587,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
#{'<input name="utf8" type="hidden" value="&#x2713;"/>' unless ::Rails::VERSION::STRING >= '6'}
<div class="mb-3 col-auto g-3">
<label class="form-label mr-sm-2 required" for="user_email">Email</label>
<input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com" />
</div>
</form>
HTML
Expand Down Expand Up @@ -627,7 +627,7 @@ class BootstrapFormGroupTest < ActionView::TestCase
<div class="mb-3">
<label class="form-label required" for="user_email">Email</label>
<div class="input-group input-group-lg">
<input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com" />
<input aria-required="true" required="required" class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com" />
<input class="btn btn-primary" name="commit" type="submit" value="Subscribe" />
</div>
</div>
Expand Down
Loading

0 comments on commit d32c9fb

Please sign in to comment.