msdn
Developing Accessibile Web Applications Popup Dialog Sample

Demo


Features Summary

The "Universal" model is used in this example, with Progressive Enhancement, where a single code-base is used for all the different browsers, with standard semantic HTML markup being used where possible. While Web Accessibility Initiative-Accessible Rich Internet Applications ( WAI-ARIA ) can improve the accessibility of page elements, accessibility is best provided by the browser handling the web page elements natively.

For example, it's better to use an <h1> element in HTML than to use the ARIA role attribute on a <div> element, and where native elements handle accessibility it is not necessary to add ARIA attributes to page elements. With this approach, users of older browsers that don't support ARIA accessibity attributes ( such as IE 6 and 7 ) experience keyboard accessible pages, users of newer browsers experience an enhanced interface, and it isn't necessary to detect the browser in use when the page loads and branch to different sections of code for different browsers.

This example shows how a dynamically created page element ( the Popup Dialog Box ) is made to appear as required, and is positioned as needed in the DOM and on the page, using a combination of the native element's in-line style property ( style="display:none;" ), CSS parameters ( e.g. in the "div.dialog" class ), and JavaScript such as the code used to set the " .. style.position=absolute;" property.

Usage

The HTML for the Popup Dialog contains two active elements, the button labelled "Options" that pops up the dialog box and the empty <div> container for the dialog box. The dialog box and its elements - 2 Radio buttons, a submit button, and a cancel button - are inserted into the empty <div> container when the "Options" button is activated, and removed when the buttons marked "OK" or "Cancel" in the dialog box are activated. Pressing the "Esc" key also cancels the form submission, although it may need to be pressed twice if the screen reader intercepts Esc for its own use. See the JavaScript code section below.

The Tab and Shift+Tab keys navigate the elements of the Options popup, and the Left and Right arrow keys select an item in the radio button list.

HTML

Setting the tabindex to 0 ( "tabindex=0") for the empty <div> element that will contain the popup dialog box, puts the <div> ( which would not normally be tabbed to ) in to the tab order of the web page in the place in which it was declared, and the actual position is set by giving values to the CSS parameters with JavaScript code, e.g. style.position="absolute". In this example, the Popup Dialog box <div> tab order is after the "Options" button. If the tab button is activated with the focus on the "Cancel" button, focus shifts to the first item in the tab order, the browser address field.

  <body>
    <div class="header1">
	  <div class="header2"></div>
    </div>
    <div class="content">
      <h1>
	  <img alt="msdn" height="32" width="120" align="right" src="../msdn.png">
	  <div><span>Developing Accessibile Web Applications</span> Popup Dialog Sample</div>
      </h1>
      <h2>Demo</h2>
      <button id="optButton" aria-owns="dlg_options" aria-haspopup="true" onclick="togglePopup(event,true,'dlg_options');">Options</button>
      <div role="dialog" class="dialog" id="dlg_options" style="display:none;" onkeypress="onPopupKeypress(event,this.id);" tabindex="0"></div>
    </div>
  </body>

    


Script

  The JavaScript used  is shown below, with the popup dialog box code laid out in separate lines for each HTML element, for clarity.

  Note that manipulating the DOM with appendChild and its associated commands is not fully supported to W3C standards in IE 6 and 7, 
  so adding HTML code to an empty <div> element allows a single code-base to be cross-browser compatible.  Also, the Popup Dialog 
  box position in the page / DOM is set with JavaScript when the popup occurs, but can be set in the HTML code of the container <div>.
  
  <script type="text/javascript">

  function harmonizeEvent(evt)													//  This function harmonizes the event
  {																		//  handling code for Internet
     if (!evt.target)															//  Explorer and the other browsers
     {
	 evt.target = evt.srcElement;
	 if (evt.type == 'mouseover')
	 {
		evt.relatedTarget = evt.fromElement;
	 }
	 else if (evt.type == 'mouseout')
	 {
		evt.relatedTarget = evt.toElement;
	 }
	 evt.preventDefault = function() { this.returnValue = false; }
	 evt.stopPropagation = function() { this.cancelBubble = true; }
     }
  }

  function setFocus()
  {
	document.getElementById("optButton").focus();
  }

  function togglePopup(evt,show,dlgID)												  
  {																			
	harmonizeEvent(evt);		
	var src = evt.target;														
	if (evt.type == "click")													
	{
		evt.returnValue = false;
	}

	var dlg = document.getElementById(dlgID);	
	dlg.style.border = "2px solid gray";

	if (show == true)															//  This section of JavaScript code
	{																	//  places the HTML form code in
	  dlg.innerHTML = "<h3>Options</h3>"+										//  the innerHTML of the empty
                                             "<form onreset=togglePopup(event,false,'dlg_options');>"+				//  <div> container to "pop-up"
                                                 "<fieldset><legend>Sort Order</legend>"+					//  the Dialog Box when the
                                                     "<input type='radio' name='order' id='order_alpha' value='alpha'>"+		//  "Options" button is activated
                                                     "<label for='order_alpha'>Alphabetical</label>"+
                                                     "<input type='radio' name='order' id='order_default' value='default' checked='true'>"+
                                                     "<label for='order_default'>Default</label>"+
                                                 "</fieldset>"+
                                                 "<div class='buttons'>"+
                                                     "<input role='button' id='okButton' type='submit' value='OK'>"+
                                                     "<input role='button' type='reset' value='Cancel' onclick='setFocus()'>"+			//  This focus() instruction sets the
                                                 "</div>"+														//  focus to the Dialog Box "OK" button
                                             "</form>";														// on activating the "Options" button
	}
	else if (show == false)
	{
		dlg.innerHTML = "";														//  Here, the HTML form code is
		dlg.style.border = 0;														//  removed from the <div>
	}																		//  container, "hiding" the popup
	if (dlg.innerHTML != "")
	{
		dlg.style.position = "absolute";												//  If the Dialog Box is popped up,
		dlg.style.top = "185px";													//  set its position in the page / DOM
		dlg.style.left = ((document.documentElement.offsetWidth - dlg.offsetWidth) / 2) + "px";
		document.getElementById("okButton").focus();
	}
  }

  function onPopupKeypress(evt,dlgID)												//  The code here enables the Esc
  {																		//  key to Cancel form submission,
	harmonizeEvent(evt);														//  "hide" the popup, and set focus
	if (evt.keyCode == 27)														//  back to the "Options" button
	{
		togglePopup(evt,false,dlgID);
		setFocus();
	}
  }

  </script>