Login Register

Radio buttons, grouping, keyboard control, ARIA

This post is about dijit/form/Checkbox.js and the implementation of (grouped) radios.

There are at least 5 approaches to fully implementing radio group keyboard, mouse, and aria behavior:

  1. Smart dojo radio buttons that can interact with the sibling radio buttons in the same group with respect to checked status as well as aria states "setsize" and "posinset". Note that each time a radio button is created or destroyed we must iterate over all elements in the same group to make sure the tab index, and the aria states are correct. We don't know in the context of a widget if it is the last in the group or if there are more coming (perhaps during initial creation, or perhaps coming programmatically at any time).
  2. Use a real "html radio button" for keyboard navigation and operation that is higher in the z-order, but is transparent (opacity:0). This would interact with the dojo "view" that sits underneath.
  3. Create a dojo radio group widget.
  4. Have the dojo radio widget pass all events on to the inner inputNode (html radio widget that has "display: none" style), and have the dojo radio widget react only to onchange events from the html widget. This didn't work. I include it only so we don't redo the work.
  5. Try the former but instead of keeping the current "display: none" style, hide it in some other way. Feels kludgey?.

My first attempt was #1. In case you want to play with radio groups with my changes you can try my sandbox test. You can try tabbing around and once you get to a radio group you can try selecting a radio button (spacebar), or if one is already selected the tab should only take you to that radio and then arrowing should provide the ability to change the selected (checked) radio. Related trac ticket is: Ticket #2420 (updated radio a11y support). It is felt that the radio button widget might be becoming too heavy as we implement group behavior to mimic the browser implementation and as we implement aria states that are based on grouping. I feel we may have to live with allowing users the option of these smart radios or using the regular html ones.

My second attempt was #2. After chatting with Bill Keese, we decided it is worthwhile for me (David Bolter) to investigate this approach. To reduce the problem space an investigation was conducted using vanilla JavaScript (with no dojo core). The CSS might not be right and any help is welcome. Here are the first pass efforts for approach #2:

The first attempt is a little less embarrassing. It only seems to work in FF, and even there the labels are not lined up properly. The user interacts with the transparent (html) radio overlays, and the onchange handler updates the views underneath. If you want to see details please view the source, and also consider using the Firebug inspect tool (on FF) which will let you "see" the overlay. The second attempt doesn't seem to provide the user with the ability interact with the radio overlays.

I haven't attempted #3. It moves away from the current way web developers implement radio groups (which is grouping by common name attribute values).

#4 is a no go.

I haven't tried #5 yet.

I think that if we want to stay as close to possible to the way existing radios work and have consistency and stability across browsers we should continue with approach #1 but I am very new to Dojo and would be interested to hear from others.

Thoughts?

#2 looks good. Probably

#2 looks good. Probably what you need is to mark the outer-div as inline-block style. Try this CSS:

.dojoInlineBox {
	display:inline-block;
	display: -moz-inline-stack;
	_display:inline;
	border:0px;
	padding:0px;
}

Also, you shouldn't have your text ("Apples", etc.) inside of the radio button template. The text comes after the radio button (preferably inside a <label>)

Typicially, the way to put two things on top of each other is to mark the first one or both of them as position: absolute. I see you are not doing that, but rather moving the second element back on top of the first element by setting top: -20px. I guess that's OK too, although it's maybe better to do it with position: absolute.

Thanks Bill. I will try

Thanks Bill. I will try that.

I have in the meantime got quite far with a version of approach #5. I should mention that this is exploratory, unpolished coding and I link it here in case others want to see the direction I went. It could be cleaned up. I'd like to figure out what event to listen to on IE for radio selections.... I'm starting my commute home now but may get to it tonight. Note: this work is not disjunct from work needed in approach #2.

Update: the user interaction

Update: the user interaction now seems to work on both FF and IE. Same test page.

I haven't tested edge cases, like if a screen reader user wants to send a mouse click instead of using a keyboard and I'll need to add some checks for whether a radio is disabled.

Note this is not the transparent overlay approach. The keyboard user is interacting directly with html radio buttons offscreen. The mouse user is interacting indirectly with those radios via the on screen radio "views". Note the views are not polished yet as I don't know if we are to pursue this.

Thoughts?

Let's compare it to the

Let's compare it to the transparent overlay approach and see which is less code. It seems like a transparent overlay would be easier because it's just basically plain radio buttons with a handler to change an image based on changes to the radio button. Also, I'm a bit nervous about how clicking the image shifts focus to a different node, because I'm worried it might confuse screen readers and also because it doesn't print the dotted "I'm focused" border around the image (although I know some browsers strangely don't print the focus border around radio buttons at all).

I created simplified overlay

I created simplified overlay test to make sure the overlay approach was doable. As I had feared, it doesn't work in IE -- no idea why, perhaps a security thing? I think we might have to choose between the off-screen approach and the smart dojo radio approach. Thoughts?

I prefer the smart radio

I prefer the smart radio approach

Based on David's tests and conversations with both David and Simon, I think we should use the smart dojo radio approach. While this may require a bit more code to implement browser radio behavior I think it is the safer approach. I am concerned about the offscreen approach on this test page as it currently does not work with the Window-Eyes screen reader. Also, I don't think we should rely on the browser and screen reader vendors continuing support of allowing focus to be set to off-screen elements - it seems like something that is likely to break or be changed in new browser or assistive technology versions.

While I understand that the goal of dijit is to keep the code as small as possible, I think that if people want to have "cool" looking radio buttons and have those radio buttons behave the same as standard radios they have to be willing to take the fairly small code hit to implement them properly. I also believe that it is very important that the dijit radios work in the same manner as the standart input type=radio buttons where the arrow key is used to navigate etween grouped radio buttons.

my two cents

Becky, thanks for this

Becky, thanks for this feedback. FWIW, I agree on all points. I'm poised to tighten up and polish the smart radio button patch if Bill agrees?

Try this. It seems to work

Try this. It seems to work fine for IE and webkit. Firefox is being very stubborn; this special version work on all three browsers though. (I didn't add the code to change the background image but that's trivial; just changing the margin-left on the image.)

Usually there's a way to get what you want to work via CSS; you just have to hack on it a long time.

screen reader support

screen reader support  

Well, this does seem to work with the screen readers. Except in FF 2.0.0.3 using the special version I don't see the images at all? We'll need to play around with associating the labels properly (with a for attirbute that points to the id of the input type=radio element) to make sure the screen reader still works. Nice!

Bill, nice to see you are

Bill, nice to see you are taking it closer to a solution.

I dug a little more into why my simple overlay test didn't work in IE. It turns out if I change my transparent overlay to an input element (see overlaytest2.html) instead of a div element (see overlaytest.html) then it works! (Why on earth IE? Why, why, why?)

woops, apparently "opacity:

woops, apparently "opacity: 0" doesn't work on FF (it blocks the element behind it), if (and only if) firebug is disabled. Changed it to "opacity: 0.01" and that seemed to fix it.

Success with transparent

Success with transparent input overlay! Works in FF, Opera, IE, and (mostly) in WebKit, I just need to somehow tweak Safari/WebKit to make the checkbox labels happy.
My online sandbox: test_Checkbox.html. (Note it isn't static; what is there can change after this posting).