The Problem: Currently, radio buttons are the only form control that breaks the association of 1 element (possibly with descendants) = 1 self-contained form control. Libraries need to special case it, both for getting its value, setting its value, and monitoring changes to it. Furthermore, it's impossible to link to it, e.g. as an input to a function expecting a form control, because it鈥檚 scattered all over the place.
Proposed solution: <radiogroup> would be to <input type="radio"> what <select> is to <option>.
If <radiogroup> is used, the name is only specified once, on the <radiogroup> element and it applies to all its descendant radios without a name. For backwards compatibility, the same name can also be used on the radios.
Similarly to <select> menus, HTMLRadiogroupElement.value would return the value of the selected radio and would be a getter/setter. HTMLRadiogroupElement.radios would be a RadioNodeList with all radios in the group.
Edit: Also, accessibility: a <radiogroup> element would enable you to label the entire radio group which is currently impossible. Consider a form field about gender:
Gender:
<input type="radio" value="female" /> Female
<input type="radio" value="male" /> Male
<input type="radio" value="other" /> Other
In the example above, "Female", "Male", "Other" should be labels for their respective radio buttons. But what is "Gender:" a label for?
This would certainly make forms easier. How would you handle nested <radiogroup>s?
If there are radio buttons outside radiogroup with the same name, are they in the same group or not?
It is not always possible to have radio buttons have a common radiogroup ancestor, e.g. in a table with different groups per row. (This is essentially why form="" exists.)
Would it be better to expose a list for the group on HTMLInputElement instead, and an attribute to get the selected radio button?
Excellent questions both! My two cents:
How would you handle nested
<radiogroup>s?
Given that this:
<radiogroup name="foo">
<input type="radio" value="1">
<input type="radio" value="2">
<radiogroup name="bar">
<input type="radio" value="3">
<input type="radio" value="4">
</radiogroup>
</radiogroup>
is basically equivalent to:
<input type="radio" value="1" name="foo">
<input type="radio" value="2" name="foo">
<input type="radio" value="3" name="bar">
<input type="radio" value="4" name="bar">
I don't think there鈥檚 any ambiguity in the general case. Perhaps more interesting is what happens in this case:
<radiogroup name="foo">
<input type="radio" value="1">
<input type="radio" value="2">
<radiogroup name="bar">
<input type="radio" value="3">
<input type="radio" value="4">
<input type="radio" value="5" name="foo">
</radiogroup>
</radiogroup>
where I think it makes more sense that the name on the radio button overrides any implicit name via the <radiogroup>, making that radio belong to the outer group. I think that's most likely the author intent, but no strong opinions here.
Similarly, since <radiogroup> is essentially syntactic sugar for treating all radios as 1 element, if elements outside the group have the same name, they should probably be part of the group. I also suggested a group IDL attribute which is independent of this proposal, since even if <radiogroup> is introduced it would be optional, not mandatory.
HTMLRadiogroupElement.value would definitely be more intuitive than HTMLFormControlsCollection.RadioNodeList.value.
Specifying role="radiogroup is already necessary if using custom radio buttons using role="radio", so there might as well be an element for it.
Let's try to evaluate how well this proposal and the other proposals solves the problems outlined in the OP.
Libraries need to special case it, both for getting its value, setting its value,
Getting and setting value would be solved by https://github.com/whatwg/html/issues/2462 in that you could do
aRadioButton.group.value;
aRadioButton.group.value = 'other';
The radiogroup.value attribute would then essentially be an alias for radiogroup.radios.value.
and monitoring changes to it.
That would be solved by https://github.com/whatwg/html/issues/2461
I assume you would want an event on the radiogroup element as well?
Furthermore, it's impossible to link to it, e.g. as an input to a function expecting a form control, because it鈥檚 scattered all over the place.
This seems like a problem that only this proposal tries to address.
What should happen when the user follows a link to a radiogroup element? Should one of the radio buttons in the group be focused (which one)?
If it shouldn't focus one of the radio buttons but just act like normal when linking to an element, then it would be possible to use a div or span and link to that. If it should focus the first element in tree order then it would be possible to link to that instead. If it should focus the checked radio button in the group then it is more complicated.
How common is it to link to a radio group?
@zcorpan By "link" I didn't mean an HTML link, I meant a JS reference. For example, in my use case, I needed to make certain elements on a page editable, and they could optionally reference form controls for how they should be edited via attributes or nesting. This is impossible to do with radio buttons. My specific use case might be fairly niche, but the general case of passing self-contained form controls to functions is not.
Also, accessibility: a <radiogroup> element would enable you to label the entire radio group which is currently impossible. Consider a form field about gender:
Gender:
<input type="radio" name="gender" value="female" /> Female
<input type="radio" name="gender" value="male" /> Male
<input type="radio" name="gender" value="other" /> Other
In the example above, "Female", "Male", "Other" should be labels for their respective radio buttons. But what is "Gender:" a label for?
(edited first post to add this point, as I think it's important)
Also, accessibility: a
element would enable you to label the entire radio group which is currently impossible. Consider a form field about gender:
This is how to provide an accessible group label accessibility wise:
<fieldset>
<legend>Gender:</legend>
<label><input type="radio" name="gender" value="female" /> Female </label>
<label><input type="radio" name="gender" value="male" /> Male </label>
<label><input type="radio" name="gender" value="other" /> Other </label>
</fieldset>
@stevefaulkner I鈥檓 aware, but that鈥檚 not always a desirable solution. E.g. you may want a fieldset with a broader grouping than just this one field. You can label a <select> menu for this exact same choice, so why not be able to label a radio group? Note that just switching to a <select> menu instead is inadvisable for usability reasons: <select> menus are a usability bad practice when their options are too few (or too many, but that's not relevant here).
I'm going to add-in my proposal from w3c/html#1508 to this ticket: Add parent element functionality for radio inputs. I originally proposed creating a new element <inputgroup>, but this feature could be implemented on the existing <fieldset> element. Just like Lea's proposal, my intention was to make grouping easier, rather than relying on the name attribute.
My old w3c ticket got a good amount of 馃憤's. Hear the voice of the people!
Most helpful comment
If there are radio buttons outside
radiogroupwith the same name, are they in the same group or not?It is not always possible to have radio buttons have a common
radiogroupancestor, e.g. in a table with different groups per row. (This is essentially whyform=""exists.)Would it be better to expose a list for the group on
HTMLInputElementinstead, and an attribute to get the selected radio button?