Radio Navigation Menu
Radio Example 4: JQuery
Lunch Options
-
Thai
-
Subway
-
Jimmy Johns
-
Radio Maria
-
Rainbow Gardens
Drink Options
-
Water
-
Tea
-
Coffee
-
Cola
-
Ginger Ale
Keyboard Shortcuts
The following keyboard shortcuts are implemented for this example (based on recommended shortcuts specified by the DHTML Style Guide Working Group.):
- Tab: Move between radio button groups.
- Up/Left and Down/Right Arrow: Move selection between radio items in a group
- Ctrl + Arrow: Move between radio items in a group without changing checked state
- Space Bar: Check the radio button that currently has focus
ARIA Roles and Properties
-
Roles:
role="application"
role="radiogroup"
role="radio"
- States and properties:
aria-checked
aria-describedby
aria-labelledby
HTML Source Code
Show HTML Source Code: radio4.inc
<div role="application">
<h3 id="rg1_label">Lunch Options</h3>
<ul class="radiogroup"
id="rg1"
role="radiogroup"
aria-labelledby="rg1_label"
>
<li id="r1"
class="first"
tabindex="-1"
role="radio"
aria-checked="false">
<img role="presentation" src="images/unchecked.gif" alt=""/>
Thai
</li>
<li id="r2"
tabindex="-1"
role="radio"
aria-checked="false">
<img role="presentation" src="images/unchecked.gif" alt=""/>
Subway
</li>
<li id="r3"
tabindex="-1"
role="radio"
aria-checked="false">
<img role="presentation" src="images/unchecked.gif" alt=""/>
Jimmy Johns
</li>
<li id="r4"
tabindex="0"
role="radio"
aria-checked="true">
<img role="presentation" src="images/checked.gif" alt=""/>
Radio Maria
</li>
<li id="r5"
class="last"
tabindex="-1"
role="radio"
aria-checked="false">
<img role="presentation" src="images/unchecked.gif" alt=""/>
Rainbow Gardens
</li>
</ul>
<!-- Start of second Radio Group -->
<h3 id="rg2_label">Drink Options</h3>
<ul id="rg2"
class="radiogroup"
role="radiogroup"
aria-labelledby="rg2_label"
>
<li id="r6"
class="first"
tabindex="0"
role="radio"
aria-checked="false">
<img role="presentation" src="images/unchecked.gif" alt=""/>
Water
</li>
<li id="r7"
tabindex="-1"
role="radio"
aria-checked="false">
<img role="presentation" src="images/unchecked.gif" alt=""/>
Tea
</li>
<li id="r8"
tabindex="-1"
role="radio"
aria-checked="false">
<img role="presentation" src="images/unchecked.gif" alt=""/>
Coffee
</li>
<li id="r9"
tabindex="-1"
role="radio"
aria-checked="false">
<img role="presentation" src="images/unchecked.gif" alt=""/>
Cola
</li>
<li id="r10"
class="last"
tabindex="0"
role="radio"
aria-checked="false">
<img role="presentation" src="images/unchecked.gif" alt=""/>
Ginger Ale
</li>
</ul>
</div>
Javascript Source Code
Show Javascript Source Code: radio4.js
<script type="text/javascript">
$(document).ready(function() {
// key code definitions
var KEY_SPACE = 32;
var KEY_LEFT = 37;
var KEY_UP = 38;
var KEY_RIGHT = 39;
var KEY_DOWN = 40;
$('ul.radiogroup li').click(function() {
$(this).siblings('li').each(
function() {
$(this).attr('aria-checked', 'false');
$(this).attr('tabindex', '-1');
$(this).children('img').attr('src','images/unchecked.gif');
} // end each function
) // end each
$(this).attr('aria-checked', 'true');
$(this).children('img').attr('src','images/checked.gif');
$(this).attr('tabindex', '0');
}); // end click event handler
//
// radio group keypress handler
//
// The Opera browser performs some window commands from the keypress event,
// not keydown like Firefox, Safari, and IE. This event handler consumes
// keypresses for relevant keys so that Opera behaves when the user is
// manipulating a radiobutton group with the keyboard.
//
$('ul.radiogroup li').keypress(function(e) {
var key = e.which
switch(e.which) {
case KEY_SPACE:
case KEY_LEFT:
case KEY_UP:
case KEY_RIGHT:
case KEY_DOWN: {
e.stopPropagation;
return false;
break;
}
} // end switch
return true;
}); // end radiogroup keypress handler
$('ul.radiogroup li').keydown(function(e) {
var selected_node = this;
var key = e.which
if( key == KEY_SPACE ||
key == KEY_LEFT ||
key == KEY_UP ||
key == KEY_RIGHT ||
key == KEY_DOWN) {
if (e.ctrlKey == false) {
// This is not part of a ctrl+arrow key combination:
// Clear all the buttons and tabs.
$(selected_node).parent().children('li').each(function() {
$(this).attr('aria-checked', 'false');
$(this).attr('tabindex', '-1');
$(this).children('img').attr('src','images/unchecked.gif');
}); // end each function
} // endif
switch (key) {
case KEY_LEFT:
case KEY_UP: {
selected_node = $(this).prev();
if ( !$(selected_node).length ) {
selected_node = $(this).parent().children('li:last');
} // endif
break;
}
case KEY_RIGHT:
case KEY_DOWN: {
selected_node = $(this).next();
if( !$(selected_node).length ) {
selected_node = $(this).parent().children('li:first');
} // endif
break;
}
} // end switch
selected_node.focus();
if (e.ctrlKey == false) {
// This is not part of a ctrl+arrow key combination:
// Check the selected button
$(selected_node).attr('aria-checked', 'true');
$(selected_node).children('img').attr('src','images/checked.gif');
$(selected_node).attr('tabindex', '0');
} // endif
e.preventDefault();
e.stopPropagation();
return false;
} // endif
return true;
}); // end keydown event handler
$('ul.radiogroup li.first').focus(
function() {
if( $(this).siblings('li:last').attr('tabindex') == '0' &&
$(this).siblings('li:last').attr('aria-checked') == 'false' ) {
$(this).siblings('li:last').attr('tabindex', '-1');
}
}); // end focus event handler
$('ul.radiogroup li.last').focus(function() {
if( $(this).siblings('li:first').attr('tabindex') == '0' &&
$(this).siblings('li:first').attr('aria-checked') == 'false' ) {
$(this).siblings('li:first').attr('tabindex', '-1');
}
}); // end focus event handler
$('ul.radiogroup li.first').blur(function() {
if( $(this).attr('tabindex') == '0' &&
$(this).attr('aria-checked') == 'false' ) {
$(this).siblings('li:last').attr('tabindex', '0');
}
}); // end blur event handler
$('ul.radiogroup li.last').blur(function() {
if( $(this).attr('tabindex') == '0' &&
$(this).attr('aria-checked') == 'false' ) {
$(this).siblings('li:first').attr('tabindex','0');
}
}); // end blur event handler
}); // end ready function
</script>
CSS Source Code
Show CSS Source Code: radio4.css
<style type="text/css">
/* Example 1 CSS
// This example uses CSS background-image to visual display checkbox status
*/
ul.radiogroup {
margin: 0;
padding: 0;
}
ul.radiogroup li {
padding: 0;
margin: 0;
margin-left: 1em;
padding: 4px;
list-style: none;
width: 6em;
}
ul.radiogroup li:hover {
padding: 2px;
border: gray 2px solid;
}
ul.radiogroup li:focus,
ul.radiogroup li:active {
padding: 2px;
border: black 2px solid;
}
.offscreen {
position: absolute;
left: -200em;
top: -20em;
}
</style>
W3C Validation of HTML5