Basic AJAX - Incorporating alternatives
Now the AJAX class is made as screen reader friendly as possible it should be considered that JavaScript could be disabled or the user could choose to not use the AJAX parts of the site.
One of the most important considerations for making the page accessible is to understand what happens when JavaScript is disabled. The previous example would simply no nothing. The use of a JavaScript hyperlink reference gives no alternatives for the user. The most common solution to overcome this is to set the link to a server side solution and add an event listener to activate the AJAX instead of following the link.
For example the previous page could be updated with the following:
window.onload = init;
function init(){
if (!document.getElementById || !document.createTextNode ||
(typeof XMLHttpRequest == 'undefined' && !ActiveXObject)){
return;
}
var objAnchor = document.getElementById('link');
if (objAnchor)
{
objAnchor.onclick = function(event){return makeCall();};
objAnchor.onkeypress = function(event){return makeCall();};
}
}
This checks for XMLHttpRequest compatibility and sets the anchor 'link' to run the AJAX request. For this to work we must set the makeCall to return false otherwise the link will still be followed and the id attribute to the link must be added.
The link now sends get information to the page and the server side php retrieves the information from Data.txt if no JavaScript is enabled.
<body>
<div id="content">
<h1>My First Accessible AJAX call</h1>
<p><a id="link" href="?mess=1">Make Call</a></p>
<p><span id="dataTarget">
<?php
if(isset($_GET['mess'])){
echo'Without JavaScript: ';
include('Data.txt');
}
?>
</span></p>
</div>
</body>
See example (opens in new window).
Giving the user the option of AJAX
As a screen reader user may have JavaScript enabled it is now possible to add a function to display a link that gives the user the option to disable the AJAX functionality. We will place the link as part of the init method so it only shows if JavaScript is enabled. The function sets a cookie to enable or disable the AJAX. This cookie can be checked when a new page is loaded. The function must also disable any AJAX links that have been set.
The following example uses the following basic layout to demonstrate the dynamic affect of incorporating all that has been discussed:
- Cascading Style Sheet to set layout and colours
- HTML page with basic DOM structure with menus
- Accessibility options and help page
- Accessible AJAX class
- JavaScript to handle the actions on the page
- Php page to generate dynamic text
Within the example there are added accessibility options. This enables user the choice of how to use the site. The majority of able bodied users will not be affected by this and still get the fully dynamic content.
For the full effect I am incorporating a few functions to handle cookies:
function get_cookie ( cookie_name ){
var results = document.cookie.match
( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)' );
if ( results )
return ( unescape ( results[2] ) );
else
return false;
}
function delete_cookie ( cookie_name ){
var cookie_date = new Date ( );
cookie_date.setTime ( cookie_date.getTime() - 1 );
document.cookie = cookie_name += "=; expires=" + cookie_date.toGMTString();
}
function set_cookie(name,value,exp_y,exp_m,exp_d,path,domain,secure){
var cookie_string = name + "=" + escape ( value );
if ( exp_y ){
var expires = new Date ( exp_y, exp_m, exp_d );
cookie_string += "; expires=" + expires.toGMTString();
}
if ( path )
cookie_string += "; path=" + escape ( path );
if ( domain )
cookie_string += "; domain=" + escape ( domain );
if ( secure )
cookie_string += "; secure";
document.cookie = cookie_string;
}
This is stored in cookie.js. This is to manage setting the cookie on the site.
The following amendments are now made to the init method. This loads up when the page is loaded and creates a link to enable or disable AJAX. If JavaScript is disabled then this link will not be displayed.
window.onload = init;
function init(){
giveOptions();
The first change is to make a function that will add a link to enable or disable AJAX in the accessibility menu. This refers to the function below. We then add a condition to check to see if the cookie is set before loading the AJAX functionality.
if (get_cookie ( 'isAJAX' )||!document.getElementById ||
!document.createTextNode || (typeof XMLHttpRequest
== 'undefined' && !ActiveXObject)){
return;
}
We now add a function to add listeners to the page. This can then be updated for multiple listeners
createListeners(); }
Within the function create listeners we hold all the code that listens for events.
function createListeners(){
var objAnchor = document.getElementById('link');
if (objAnchor){
objAnchor.onclick = function(event){return makeCall();};
objAnchor.onkeypress = function(event){return makeCall();};
}
}
There is also code to remove the listeners if AJAX gets disabled.
function removeListeners(){
var objAnchor = document.getElementById('link');
if (objAnchor){
objAnchor.onclick = function(event){return true;};
objAnchor.onkeypress = function(event){return true;};
}
}
Then create the function to display the link in the accessibility menu.
function giveOptions(){
var accesslist=document.getElementById('accessMenu');
if(accesslist){
var newOpt=createLink();
var listItem=document.createElement('li');
listItem.appendChild(newOpt);
accesslist.appendChild(listItem);
}
}
This calls the function that creates the DOM of the link.
function createLink(){
var newOpt=document.createElement('a');
newOpt.setAttribute('href' , '#');
newOpt.setAttribute('id' , 'AJAXchoice');
newOpt.setAttribute('onclick' , 'setAJAX()');
if(get_cookie ( 'isAJAX' )){
newOpt.appendChild(document.createTextNode('Enable AJAX'));
}else{
newOpt.appendChild(document.createTextNode('Disable AJAX'));
}
return newOpt;
}
When creating the link the cookie is checked to see if AJAX is enabled
Finally a function is created to toggle the cookie and update the page notifying the user weather AJAX is enabled.
function setAJAX(){
if(get_cookie ( 'isAJAX' )){
delete_cookie ( 'isAJAX' );
var newOpt=createLink();
var AJAXLink=document.getElementById('AJAXchoice');
AJAXLink.parentNode.replaceChild(newOpt,AJAXLink);
createListeners();
alert("AJAX is enabled on this site");
}else{
set_cookie('isAJAX', 1);
var newOpt=createLink();
var AJAXLink=document.getElementById('AJAXchoice');
AJAXLink.parentNode.replaceChild(newOpt,AJAXLink);
removeListeners();
alert("AJAX is disabled on this site");
}
}
The method of calling the AJAX stays the same but we call the results from a php file that generates the string. The function replaces the span rather than adding to the end of it.
function makeCall(){
var myAJAX= new AJAXClient();
myAJAX.isAsync=true;
myAJAX.focusElement='dataTarget';
myAJAX.callback= function(result){
var oldspan=document.getElementById('dataTarget');
var newspan=document.createElement('span');
newspan.setAttribute('id' , 'dataTarget');
newspan.appendChild(document.createTextNode
(myAJAX.xmlhttp.responseText));
oldspan.parentNode.replaceChild(newspan,oldspan);
}
myAJAX.makeRequest('Data.php', null);
return false;
}
Finally the html page is re-written with menus and a style sheet:
<body>
<div id="contentFrame">
<div id="accessOptions">
<ul id="accessMenu">
<li><a href="#content">Skip Navigation</a></li>
<li><a href="accessibilityOptions.php">Accessibility Options</a></li>
</ul>
</div>
<div id="header">
<h1>My AJAX website</h1>
</div>
<div id="menu">
<ul>
<li><a href="AJAX4.php">Display the time</a></li>
<li><a href="subForm.php">Submitting a form</a></li>
<li><a href="DynamicContent.php">Dynamically Display Content</a></li>
<li><a href="dropdown.php">Populating drop down boxes</a></li>
</ul>
</div>
<div id="content">
<p><a id="link" href="?mess=1">Get the Time</a></p>
<p><span id="dataTarget">
<?php
if(isset($_GET['mess'])){
echo'Without JavaScript: ';
include('Data.php');
}?>
</span></p>
</div>
</div>
</body>
Here is a full example of a simple page that makes an AJAX Call with the option to disable the AJAX.
Previous: Basic AJAX - Making the AJAX class more accessible Next: Basic AJAX - Best Practice
References
Elated Communications Ltd. (2002). Tutorial: JavaScript and cookies. Retrieved January 18, 2008, from elated.com: http://www.elated.com/articles/javascript-and-cookies/
Lemon, G., Faulkner, S. (2006, May 25) Making Ajax Work with Screen Readers. Retrieved March 31, 2008, from http://juicystudio.com/article/making-ajax-work-with-screen-readers.php
Lemon, G., Faulkner, S. (2007, January 19) Improving Ajax applications for JAWS users. Retrieved March 31, 2008, from http://juicystudio.com/article/improving-ajax-applications-for-jaws-users.php
Eichorn, J. (2006). Understanding AJAX. Upper Saddle River, NJ: Pearson Education, Inc.
Zakas, N. C. (2005). Proffessional JavaScript for web developers. Indianapolis: Wiley Publishing Inc.