<html>
<head>
<style type="text/css">
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.selected {
    padding: 2px;
    border: black 2px solid;
   }

.offscreen {
  position: absolute;
	  left: -200em;
	  top: -20em;
}
</style>
</head> 
<body>

<div role="application">

  <h3 id="rg1_label">Lunch Options</h3>
 
  <ul class="radiogroup" id="rg1" role="radiogroup" aria-labelledby="rg1_label">
    <li id="r1" tabindex="-1" role="radio" aria-checked="false">
      <img role="presentation" src="radio-unchecked.gif" alt="">
      Thai
    </li>
    <li id="r2" tabindex="-1" role="radio" aria-checked="false">
      <img role="presentation" src="radio-unchecked.gif" alt="">
      Subway
    </li>
    <li id="r3" tabindex="-1" role="radio" aria-checked="false">
      <img role="presentation" src="radio-unchecked.gif" alt="">
      Jimmy Johns
    </li>
    <li id="r4" tabindex="0" role="radio" aria-checked="true">
      <img role="presentation" src="radio-checked.gif" alt="">
      Radio Maria
    </li>
    <li id="r5" tabindex="-1" role="radio" aria-checked="false">
      <img role="presentation" src="radio-unchecked.gif" alt="">
      Rainbow Gardens
    </li>	 
  </ul>	
  <h3 id="rg2_label">Drink Options</h3>
   
  <ul id="rg2" class="radiogroup" role="radiogroup" aria-labelledby="rg2_label">
    <li id="r6" tabindex="0" role="radio" aria-checked="false">
      <img role="presentation" src="radio-unchecked.gif" alt="">
      Water
    </li>
    <li id="r7" tabindex="-1" role="radio" aria-checked="false">
      <img role="presentation" src="radio-unchecked.gif" alt="">
      Tea
    </li>
    <li id="r8" tabindex="-1" role="radio" aria-checked="false">
      <img role="presentation" src="radio-unchecked.gif" alt="">
      Coffee
    </li>
    <li id="r9" tabindex="-1" role="radio" aria-checked="false">
      <img role="presentation" src="radio-unchecked.gif" alt="">
      Cola
    </li>
    <li id="r10" tabindex="0" role="radio" aria-checked="false">
      <img role="presentation" src="radio-unchecked.gif" alt="">
      Ginger Ale
    </li>	 
  </ul>	
 
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {

	var group1 = new radioGroup('rg1');
	var group2 = new radioGroup('rg2');

}); // end ready

function keyCodes () {
  // Define values for keycodes
  this.enter      = 13;
  this.space      = 32;

  this.left       = 37;
  this.up         = 38;
  this.right      = 39;
  this.down       = 40;
} 

//
// Function radioGroup() is a class to define an ARIA-enabled radiogroup widget.
//
// This widget attaches to an unordered list and makes each list entry a group
// of radio buttons.
//
// @param (id object) id is the html id of the <ul> to attach to
//
// @return N/A
//
function radioGroup(id) {

	var thisObj = this;

	///////// define widget properties ///////////////

	this.$id = $('#' + id);

	// find all list items with a role of radio
	this.$buttons = this.$id.find('li').filter('[role=radio]');

	// Store the currently checked item
	this.$checked = this.$buttons.filter('[aria-checked=true]');

	this.checkButton = true; // set to false during ctrl+arrow operations;

	this.$active = null; // the selected button (may not be checked)
	
	this.keys = new keyCodes();

	///////////// Bind Event handlers ////////////////

	this.$buttons.click(function(e) {
		return thisObj.handleClick(e, $(this));
	});

	this.$buttons.keydown(function(e) {
		return thisObj.handleKeyDown(e, $(this));
	});

	this.$buttons.keypress(function(e) {
		return thisObj.handleKeyPress(e, $(this));
	});

	this.$buttons.focus(function(e) {
		return thisObj.handleFocus(e, $(this));
	});

	this.$buttons.blur(function(e) {
		return thisObj.handleBlur(e, $(this));
	});
}

// 
// Function selectButton() is a member function to select and possibly check a button in the
// radioGroup.
//
// @param ($id object) $id is the jQuery object of the button to select
//
// @return N/A
//
radioGroup.prototype.selectButton = function($id) {

	if (this.checkButton == true) {
		// checking the button

		// remove the checked image from the previously checked button
		this.$checked.find('img').attr('src', 'radio-unchecked.gif');

		// update the button image
		$id.find('img').attr('src', 'radio-checked.gif');

		if (this.$checked.length == 0) { // no previously checked group buttons
			// the first and last items in the group will have
			// tabindex=0. Remove them both from the tab order.
			this.$buttons.first().attr('tabindex', '-1');

			this.$buttons.last().attr('tabindex', '-1');
		}
		else {
			// remove the previously checked item from
			// the tab order and modify it's aria attributes accordingly
			this.$checked.attr('tabindex', '-1').attr('aria-checked', 'false');
		}

		// Place this button in the tab order and modify it's aria attributes
		$id.attr('tabindex', '0').attr('aria-checked', 'true');

		// update the stored $checked object
		this.$checked = $id;
	}

	// update the stored $active object
	this.$active = $id;

	// give this button the selected class
	$id.addClass('selected');

	// Reset checkButton flag - in case it was false
	this.checkButton = true;

} // end selectButton()

//
// Function handleClick() is a member function to process keydown events for the radioGroup.
//
// @param (e object) e is the event object
//
// @param ($id object) $is is the jquery object of the triggering element
//
// @return (boolean) Returns false if consuming event; true if propagating
//
radioGroup.prototype.handleClick = function(e, $id) {

	if (e.altKey || e.ctrlKey || e.shiftKey) {
		// do nothing
		return true;
	}

	// simply consume the event - browser calls focus()

	e.stopPropagation();
	return false;

} // end handleClick()

//
// Function handleKeyDown() is a member function to process keydown events for the radioGroup.
//
// @param (e object) e is the event object
//
// @param ($id object) $is is the jquery object of the triggering element
//
// @return (boolean) Returns false if consuming event; true if propagating
//
radioGroup.prototype.handleKeyDown = function(e, $id) {

	if (e.altKey) {
		// do nothing
		return true;
	}

	switch (e.keyCode) {
		case this.keys.space:
		case this.keys.enter: {
			if (e.ctrlkey || e.shiftKey) {
				// do nothing
				return true;
			}

			// select and check the button
			this.selectButton($id);

			e.stopPropagation();
			return false;
		}
		case this.keys.left:
		case this.keys.up: {

			var $prev = $id.prev(); // the previous button

			if (e.shiftKey) {
				// do nothing
				return true;
			}

			// if this was the first item
			// select the last one in the group.
			if ($id.index() == 0) {
				$prev = this.$buttons.last();
			}

			if (e.ctrlKey) {
				// set checkButton to false so
				// focus does not check button
				this.checkButton = false;
			}

			// select the previous button
			$prev[0].focus();

			e.preventDefault();
			e.stopPropagation();
			return false;
		}
		case this.keys.right:
		case this.keys.down: {

			var $next = $id.next(); // the next button

			if (e.shiftKey) {
				// do nothing
				return true;
			}

			// if this was the last item,
			// select the first one in the group.
			if ($id.index() == this.$buttons.length - 1) {
				$next = this.$buttons.first();
			}

			if (e.ctrlKey) {
				// set checkButton to false so
				// focus does not check button
				this.checkButton = false;
			}

			// select the next button
			$next[0].focus();

			e.preventDefault();
			e.stopPropagation();
			return false;
		}
	} // end switch

	return true;

} // end handleKeyDown()

//
// Function handleKeyPress() is a member function to process keydown events for the radioGroup.
// This is needed to prevent browsers that process window events on keypress (such as Opera) from
// performing unwanted scrolling of the window, etc.
//
// @param (e object) e is the event object
//
// @param ($id object) $is is the jquery object of the triggering element
//
// @return (boolean) Returns false if consuming event; true if propagating
//
radioGroup.prototype.handleKeyPress = function(e, $id) {

	if (e.altKey) {
		// do nothing
		return true;
	}

	switch (e.keyCode) {
		case this.keys.space:
		case this.keys.enter: {
			if (e.ctrlKey || e.shiftKey) {
				// do nothing
				return true;
			}
		}
		case this.keys.left:
		case this.keys.up:
		case this.keys.right:
		case this.keys.down: {
			if (e.shiftKey) {
				// do nothing
				return true;
			}
			e.stopPropagation();
			return false;
		}
	} // end switch

	return true;

} // end handleKeyPress()

//
// Function handleFocus() is a member function to process focus events for the radioGroup.
//
// @param (e object) e is the event object
//
// @param ($id object) $is is the jquery object of the triggering element
//
// @return (boolean) Returns false if consuming event; true if propagating
//
radioGroup.prototype.handleFocus = function(e, $id) {

	// select the button
	this.selectButton($id);

	return true;
} // end handleFocus()

//
// Function handleBlur() is a member function to process blur events for the radioGroup.
//
// @param (e object) e is the event object
//
// @param ($id object) $is is the jquery object of the triggering element
//
// @return (boolean) Returns false if consuming event; true if propagating
//
radioGroup.prototype.handleBlur = function(e, $id) {

	// remove the focus styling from this buttons
	$id.removeClass('selected');

	return true;
} // end handleBlur()
  </script>
</body>
</html>