Hi folks,
You start with something like this:
<%= check_box_tag :foo, 1 %>
<%= label_tag :foo, "Foo?" %>
The logic may be broken if you expect the unchecked state to arrive in a param on the server. But a11y-wise the example is OK.
You discover the logical error (Maybe google leads you to the “Gotcha” that f.check_box smooths over for us at check_box (ActionView::Helpers::FormHelper) - APIdock . A sensible place to look since generally in Rails the f.* methods have corresponding *_tag methods to be used independently of a form builder).
And you think “Well that’s no big deal, I’ll just add the hidden input myself”, right? And you wind up with this:
<%= hidden_field_tag :foo, 0 %>
<%= check_box_tag :foo, 1 %>
<%= label_tag :foo, "Foo?" %>
Now there’s a subtle a11y bug where the label is no longer hooked up to the checkbox, since by default hidden_field_tag generates an an id
of “foo” (anti-a11y behavior observed in Chromium 43 and Iceweasel 31 (incidentally, this browser behavior is contrary to my interpretation of Note 2 of H44: Using label elements to associate text labels with form controls | Techniques for WCAG 2.0)). Once again, this is an issue that f.check_box takes care of for you.
We should address this because
-
Current check_box_tag behavior lends itself to “gotcha” logical errors
-
Most obvious solution to “gotcha” error leads to subtle a11y bug
-
Dissonance between f.checkbox and check_box_tag violates Rails’ pattern of f.* methods having corresponding *_tag methods.
Solutions I can think of
a) Deprecate check_box_tag completely
b) Make check_box_tag automatically generate the same perfect hidden input that f.check_box generates
- This would be a breaking change, and there is no precedence for a *_tag method generating more than a single HTML element, but if f.checkbox is special, maybe check_box_tag should be special, too?
c) Offer an option on check_box_tag fix_gotcha: true
that is well-documented and generates the perfect hidden input
- We can later output a deprecation warning on check_box_tags with no value for fix_gotcha: “fix_gotcha will default to true on future versions, please add fix_gotcha: false to opt out of this behavior”
Thoughts?
Gabe