Creating Accessible Web 2.0 Applications Using AXS

By Brice Mason
August 26, 2008

Web developers are the ultimate communicators. We often are tasked with realizing the vision of an entire team whose job is to market, promote, and service their stakeholders. But what happens when your users are limited, or even excluded from, the experience you worked so hard to offer them? Whether it be a case of reduced vision, dexterity, or hearing, a growing percentage of users experience some form of barrier to accessibility. Although helping users overcome these barriers is itself enough reason to start designing for accessibility now, a variety of other factors, including government regulation, profitability, and user perception all are important motivations to design to support accessibility. In this article, I will describe and demonstrate some of the most common accessibility features you can incorporate into your Web 2.0 applications by using the AOL AXS JavaScript library. You can follow along as we work through the development of a web-based client for the popular AOL Xdrive virtual storage system using the Yahoo! User Interface Toolkit (YUI) and AXS.

Today's Web

Given the ubiquity of web development today, it is harder than ever to set apart from competitors your skills and the applications you produce. We all want to create eye-catching, engaging experiences for our users in the hope that they'll stay longer at our sites and become repeat visitors. However, it would be unwise to assume these are the only characteristics the applications and web services we create should offer. The truth is, there are many worthy additions you can make to your existing site that incorporate features designed to include a broad audience.

Accessibility

While most developers focus on the sexy tools and applications that make their sites pop, you're still faced with the same problem that's been around since the birth of the Internet: accessibility. Accessibility refers simply to removing any barrier that prevents or limits participation. These barriers encompass three major areas:

  • Vision
  • Dexterity
  • Hearing

You're probably already at least familiar with these issues as they relate to web development. However, if we consider our definition of accessibility, we could add one more item to this list: technology. Creating software that requires special installations or contains generally non-intuitive interfaces and behaviors serves as a limitation to its accessibility.

It's a simple fact that the potential adult audience you try to attract to your sites is getting older and larger in number. According to Microsoft researchers, at least 20% of adult computer users experience difficulty in at least one of the three major accessibility categories. With 70 million computer users projected by 2010, that 20% is an incredibly large audience that deserves attention.

And, although the main categories I've listed here have been proven to be critical, we shouldn't stop trying to learn and understand the makeup of our audience and of its needs.

Why Should I Care?

Now that we have a common definition of accessibility and are aware of the types of barriers developers need to design for, consider our motivation for accommodating them. The reasons vary by individual and range from social responsibility to law to profit. I'm sure profit is a common concern, so let's look at that first.

Many web sites today generate their income from the number of visitors they can attract and how long they stay. With this focus on traffic as the means to profit, it would make the most sense to prepare for and accommodate the broadest audience. Furthermore, incorporating a core sense of accessibility into your site increases the loyalty a user feels for the product, which is a major driver of site retention and repeat use. Profit can even come down to you, the individual developer. The knowledge and skills necessary to incorporate accessibility come at a premium. Not only does accessibility set your web site apart from others, but it can give you a very unique edge in the marketplace.

Another reason to care about accessibility is social responsibility. This is one of those things that you're not required to have (yet) but almost everyone does. It's a social norm--it's the right thing to do to help other people. But again, to take accessibility further on your site is what produces brand loyalty and even, possibly, publicity. All of this feeds into a positive image and potential for increased profit.

In the U.S., we aren't required by law to design for accessibility (yet), but legal issues should be a consideration. The truth is, we live in a litigious society, and excluding or limiting a person's ability to participate in the products and services you have to offer pins a target on your back. Although there is no general U.S. law mandating accessible web sites, there is Section 508, which does mandate accessible electronic assets procured by federal agencies. So in essence, if you want to produce work for the government, you better understand accessibility.

AXS, A New Solution in Accessibility

To solve the issues surrounding the three main accessibility categories--vision, dexterity, and hearing--users typically implement screen readers, magnifiers, captions, and contrasting displays. These traditional accessibility products can only be as good as your development efforts allow. To take advantage of them as a developer, you must pay special attention to the structure of code and the placement of embedded metadata that interact with external, add-on accessibility products. In addition, much of the new technology we use in our sites today (e.g., Flash content) requires an even finer level of attention.

At this point, you might be asking, "What does this means to me, anyway?"

Developing for accessibility basically means meeting four criteria:

  1. Managing the focus of objects to produce an intuitive experience.
  2. Incorporating predictability.
  3. Providing shortcuts to key functions for a simpler experience.
  4. Letting it be known--documenting in clear terms what is available to your audience.

We've covered a lot of ground here, and it might seem like we have a long way to go in solving these issues. Surprisingly, however, these issues can be solved quite easily by using the AXS JavaScript library that's freely available from AOL, who designed the library specifically to address accessibility. AXS is a lightweight (approximately 2.6 KB compressed, without comments) library whose sole purpose is to inject accessible features into your Web 2.0 applications. Already in use in AOL's web-based mail system and tested and proven to function on popular browser platforms such as Safari, Firefox, and Internet Explorer, AXS is a reliable, production-ready solution that you can start working with right now. Your users will appreciate the intuitive and predictable features AXS can bring to your site. As a developer, you'll appreciate not only the compact nature of AXS, but also the level of smarts it brings to the table with such a small amount of code.

AXS Rundown

AXS has condensed many of the most common features developers use into nine library functions. Within these, AXS offers two categories of functions: primary and secondary. The four primary functions are:

  • axs.focus - This function provides focus to the Document Object Model (DOM) object passed in as an argument. This is important for screen readers to be able to understand application flow and context.
  • axs.keyreg - This function registers key combinations you can define with your own JavaScript functions, making the user experience simpler and its behavior more desktop-oriented.
  • axs.keychart - Given the current set of key registrations, this function reports to the user in a screen reader-friendly fashion all the shortcut capabilities available in your application.
  • axs.gdoc - This function handles many of the most common Asynchronous JavaScript and XML (AJAX) requests you would want to support.

The five secondary AXS functions are:

  • axs.id - Shorthand for document.getElementById().
  • axs.ids - Shorthand for document.getElementById().style.
  • axs.r - Shorthand for the innerHTML property of an element.
  • axs.ae - Registers functions to specific events.
  • axs.log - In debugging mode, provides an on-screen debugging window.

At first glance, these nine core functions might not seem like much. However, they add an incredible amount of flexibility and value to your sites. Perhaps even better is that all the browser quirks and nonstandard behavior you've cringed at in the past are addressed within the library itself.

We've defined what accessibility is, its impact on your work and on your target audience, and even suggested the perfect solution. Now it's time to demonstrate the power of AXS. To get the full benefit of this example, you should at least be familiar with JavaScript and AJAX techniques, and it would be ideal if you are familiar with YUI. The solution I will demonstrate uses a proxy developed using PHP, but we won't be examining its technical aspects.

Example - Xdrive Client

Xdrive is a popular virtual storage solution from AOL. With full CRUD support, sharing, permissions management, and contacts administration, all accessible through its API, Xdrive is an incredible platform full of possibility. In this example, I will demonstrate simple authentication in Xdrive and the rendering of a directory tree that is populated using AJAX requests. As you'll soon find out, this example takes advantage of all the functions provided by AXS.

To prepare your workspace, extract the download files to your webroot directory, which creates the following directory structure:

<webroot>
   +--- axs
         +---assets
         |     +--- script
         |     |      +--- axs.js
         |     |      +--- main.js
         |     |
         |     +--- service
         |     |      +--- XdriveProxy.php
         |     |
         |     +--- style
         |            +--- main.css
         |
         +--- index.html

As you can see, this example comes fully loaded with the AXS library, and with a proxy service written in PHP. The proxy service brokers requests between the client and the remote Xdrive service. For security purposes, browsers are by default bound to a limited request model. A common pattern used to alleviate the limitation of AJAX requests to assets that reside in the current domain is to develop a proxy service. The proxy basically just passes the data through itself on to Xdrive, then passes information back from Xdrive to the client. Also note that the files necessary to support YUI are not included in this listing. For more information on the files you need from YUI to support the Xdrive client, take a look at index.html in the code download.

Start by examining the bones of the Xdrive client, which consist of some relatively lightweight HTML sprinkled with some basic JavaScript function calls. See Listing 1 for the full source of the <body> tag.

Listing 1 - Xdrive Client Structure

<body class="yui-skin-sam">

	<div id="xdr-main">
    
    	<div id="xdr-main-header" class="hd">
		<div id="xdr-user"></div>        
        	<div id="xdr-brand">Xdrive Client</div>
        </div>
        
        <div id="xdr-main-body" class="bd">
        	<div id="xdr-login">
             <form id="frm-login" onsubmit="doLogin();return false;">
            	   u: <input id="txt-username" type="text"     value="" />
                p: <input id="txt-password" type="password" value="" />
                   <input id="btn_login"    type="submit"   value="Login" />
            </form>
            </div>
            <div id="xdr-logout">
			<a href="javascript:expandTree();">Expand All</a>
                	<a href="javascript:collapseTree();">Collapse All</a>
            		<a href="javascript:doLogout();">Logout</a>
          	</div>
            
            <div id="xdr-directory"></div>
        </div>
        
        <div id="xdr-main-footer" class="ft"></div>
    
    </div>

</body>

This is pretty familiar stuff. Some items to note are the definition of the yui-skin-sam class in the <body> tag, which enables YUI default styling, and the use of explicit IDs in all the major containers we'll be working with. The naming conventions used in the definition of these containers create a self-documenting system that serves as a quick reference for where data will be dynamically populated or how a function is to be fired. Now that you've seen the structure you'll be building upon, you can move on to the dynamic aspects of the application and really start to dig in to AXS.

The Brains

The first AXS function you're going to use is axs.ae, which registers functions to events. Your Xdrive client has implemented this function by registering an init function with the window.onload event:

axs.ae( window, "load", init );

The parameters you pass here take the window object, listen for the load event, and fire the init function. One of the more useful features of this function is that subsequent definitions of the same target object and event do not overwrite the previous definition. This feature allows you to chain together functions and make your architecture clean and simple.

The next function to explore, although listed as a secondary function, is perhaps the biggest developer's lifesaver: axs.log. This function configures a log window to which you can send debugging messages during development. To enable it, simply define:

axs.debug = 1;

This enables the logging feature, so any calls to axs.log will produce and append data to a log window similar to that shown in Figure 1.

Figure 1. The axs.log window

To send a message to the log window, just pass a string as an argument to the axs.log function. When you turn off debugging, logging is disabled, so it's completely in your control.

In addition, logging with timestamps, becomes particularly helpful when debugging AJAX applications. Unlike using alerts, the browser won't stop, which tends to mask timing bugs. The best part is that you don't need to install a plug-in, and it works across browsers.

Configuring Shortcuts

One of the keys to designing for accessibility is creating an intuitive and predictable interface for the user. In AXS, this is accomplished through the axs.keyreg and axs.keychart functions. The init function in Listing 2 is what you hooked in to the window.onload event. This listing demonstrates a few shortcuts you've defined and how this configuration is communicated to the user.

Listing 2 - init()

function init() {
	
	// create main panel
	mainPanel = new YAHOO.widget.Panel( "xdr-main", {
		
		fixedCenter: true,
		close:       false,
		visible:     true,
		draggable:   false,
		zIndex:      1
		
	} );
	mainPanel.render();
	
	// register some key actions
	axs.keyreg( "control+alt+e", expandTree, {
		
		des: "Expands the entire Xdrive directory tree"
			   
	} );
	
	axs.keyreg( "control+alt+c", collapseTree, {
		
		des: "Collapses the entire Xdrive directory tree"
		
	} );
	
	axs.keyreg( "control+alt+l", whichAuth, {
			   
		des: "If the user is already logged in, logs them out. Otherwise, attempts login using current credentials in the form."
		
	} );	
	
	// configure the keychart 
	axs.keychart();
	
	// focus the login form
	axs.focus( axs.id( "txt-username" ) );

	// construct the footer based on platform
	var footerText = "For a list of shortcuts, press ";
	var keyCombo   = "Control+Alt+H";
	if( axs.onmac ) {
		keyCombo = "Control+Option+H";
	}
	footerText += keyCombo + "
Made smarter with AXS"; axs.r( axs.id( "xdr-main-footer" ), footerText ); }

In Listing 2, you configured three key sequence registrations: one to expand the directory tree, another to collapse the nodes in the directory tree, and one to invoke login/logout functionality, depending on the context of the application. The axs.keyreg function helps meet accessibility requirements that the user experience be intuitive by using letters that allow the user to associate them with a function from the system. The predictable part comes in the form of an HTML table, hidden by default, that describes the key sequences configured in the application. This table is structured so that screen readers can easily pick it up, in addition to giving the user the option to view it. By default, pressing CTRL+ALT+H displays the following key combination shortcut window in your application:

Figure 2. Key combination shortcut menu

The key chart is easy to read and offers a clear and simple roadmap to the user. This form of self-documentation, coupled with useful shortcuts, helps produce a desktop feel to web applications produced using AXS.

Putting Together the Rest

The final function you created, doLogin, takes advantage of the rest of the AXS functions. I'll cover these in chunks, starting with the following:

// proxy = "assets/service/XdriveProxy.php?xdriveMethod="
var url = PROXY_BASE_ADDRESS + "member.login";

// get the username and password
var username = axs.id( "txt-username" ).value;
var password = axs.id( "txt-password" ).value;
	
// create a MemberObject used for authentication with Xdrive
var oMember = { "user":
	{ 
		"type":     "MemberObject",
		"username": username,
		"password": password
	}
};

// decode the object for transfer
var data = "data=" + YAHOO.lang.JSON.stringify( oMember );

// attach as url parm
url += "&" + data;

The Xdrive API member.login function is used to authenticate the user. The function expects a MemberObject that is defined in the variable oMember. To obtain the username and password to pass to the service, use the axs.id secondary function, which is just a shortcut to document.getElementById(). This function accepts a string argument of the ID to the element you want to retrieve. It might not seem like much now, but if you do any type of heavy AJAX or DOM processing, you'll appreciate it. This code rounds out by converting the data to a string so it can be appended to the query string as a GET parameter to the Xdrive service.

The following section of code is the beginning of a definition of a callback function, which is used with axs.gdoc, a core function used for easy cross-browser AJAX requests. This function holds a number of standard options, such as the HTTP method to use, the parameters to pass in, and data to pass back to the callback function, if configured. Take a look at Listing 3, which is the beginning definition of the callback.

Listing 3 - Callback for axs.gdoc (First Half)

var fncCallback = function( response, package ) {
	
	// decode the response
	var jsonResponse = YAHOO.lang.JSON.parse( response.responseText );
	
	// basic check for Xdrive exceptions
	if( jsonResponse.exceptions ) {
		alert( "Login failed, please try again" );
		
		axs.log( "doLogin failed: " );
		axs.log( response.responseText );
		
		axs.focus( axs.id( "txt-username" ) );
		
		return;
	}

The callback is defined to accept the response obtained from the request performed in axs.gdoc (more on that coming up), in addition to an optional package of variables sent to the callback. You have not sent a package in this case, but you defined the callback to accept it. The response data is parsed into the variable jsonResponse so it can be used for further processing, first of which is a check for an Xdrive exception. If there are any exceptions, an alert is presented to the user and messages are logged to the debug output using axs.log. Finally, focus is brought back to the username field so authentication can be attempted again. Remember, the action of bringing focus to objects provides hints to accessibility software about the flow and operational context of your code. This is a very important, subtle concept to accessibility awareness. Now take a look at the second half of the callback function in Listing 4.

Listing 4 - Second Half of the Callback

	// set cookies to maintain state with the proxy
	setCookie( "JSESSIONID", jsonResponse.jsessionid    );
	setCookie( "XDRecTok",   jsonResponse.recoveryToken );
	
	// set the username in the header
	axs.r( axs.id( "xdr-user" ), jsonResponse.results.user.username );
	
	// save the root folder id
	rootFolderId = jsonResponse.results.user.rootFolderId;
	
	// hide the login form, show the logout option
	axs.ids( "xdr-login" ).display = "none";
	axs.ids( "xdr-logout" ).display = "block";
	
	isLoggedIn = true;
	
	// load the directory tree
	loadTree( {
		"folderId": rootFolderId,
		"isRoot":   true
	} );
	
	// move focus to the directory tree
	axs.focus( axs.id( "xdr-directory" ) );
};

// execute the call
axs.gdoc( url, {
	
	cb:   fncCallback
	
} );

If there are no Xdrive exceptions, processing continues by setting cookies using the jsessionid and recovery token from Xdrive. This maintains state between the client, proxy, and the Xdrive service itself. Next, I'll introduce another AXS function, axs.r, which replaces content in an element, and acts as a shortcut to the innerHTML property. Use this function to place the username of the authenticated user in the header of the main panel. The next AXS function to cover is axs.ids, which is a shortcut to document.getElementById().style. Again, this might not seem like much, but it is definitely useful. Here we use axs.ids to hide the login form, and to show the logout bar. When the authentication block is complete, we focus on the directory tree. The last bit of code executes the AJAX request using axs.gdoc, passing in the fncCallback function as a callback. For a peek at what the full application looks like, see Figure 3. You can also test it for yourself here.

Figure 3. The completed Xdrive client

Conclusion

The purpose of this article is to demonstrate the key features of AXS--a lightweight, intelligent JavaScript library you can easily use to incorporate accessibility features into your Web 2.0 applications. The example client you created supports more functionality, which you can examine by downloading the code files mentioned earlier in the article.

Accessibility has always been a very important part of software, and now of web design. If developers can start to turn the community mindset toward understanding that designing for accessibility is itself a form of innovation, users and developers both will realize a high level of enjoyment in the applications web developers produce.

The accessibility has always

The accessibility has always been a very important part of lipoaspiração software, and now of web design. The problemas is that im having some problems in xdrive too. Is there an update released yet.

getting error message String index out of range: -71

I am having a lot of problems with xdrive in the last week. My latest problem is I have the file uploaded I put in the e-mail address and click on send and it give me the above error message can you please help.

same problem

i am getting same problem but the number at the end changes when i change the file I am trying to send. any ideas????