AccDC Technical Style Guide

Introduction

The AccDC Technical Style Guide is designed to provide reliable and consistent interaction designs that are accessible to the highest percentage of people possible, and to establish a baseline for Functional Accessibility that can be utilized, built upon, studied, and tested against.

Functional Accessibility means that each component is fully accessible from the keyboard, with or without a screen reader running.

AccDC Technical Style Guide Mirrors:

Please address any direct questions to Bryan Garaventa, or to the Accessible Innovators Group for community support.

AccDC API

  • Browse All WhatSock Projects on GitHub
  • The AccDC API (Standalone) [ GitHub | Zip ]
  • The AccDC API (for jQuery) [ GitHub | Zip ]
  • The AccDC API (for Dojo) [ GitHub | Zip ]
  • The AccDC API (for MooTools) [ GitHub | Zip ]
  • AccDC Bootstrap (Standalone) [ GitHub | Zip ]
  • AccDC Bootstrap (for jQuery) [ GitHub | Zip ]
  • AccDC Bootstrap (for Dojo) [ GitHub | Zip ]
  • AccDC Bootstrap (for MooTools) [ GitHub | Zip ]
  • The AccDC Technical Style Guide and Coding Arena (for AccDC Standalone and jQuery) [ GitHub | Zip ]
  • The AccDC Technical Style Guide and Coding Arena (for Dojo) [ GitHub | Zip ]
  • The AccDC Technical Style Guide and Coding Arena (for MooTools) [ GitHub | Zip ]

AccDC is a JavaScript based Application Programming Interface (API) that can be used with other libraries and frameworks, or by itself, to create new or enhance pre-existing web technologies with accessible features.

This is accomplished by utilizing the AccDC API properties and methods, and by leveraging the features that are available within all instantiated AccDC Objects.

The primary purpose of the AccDC API, is to recursively process AccDC Objects, which are rendered as encapsulated dynamic content components.

The majority of AccDC API properties and methods are prototyped within every AccDC Object, making every AccDC Object fully autonomous and programmatically configurable using JavaScript.

This is how AccDC Objects can dynamically control the behaviors of other AccDC Objects at runtime.

An AccDC Object is literally an instantiated JavaScript Object, which stores all relevant data and AccDC API properties and methods within it.

The shell construct of an AccDC Object declaration is as follows:

var myObjArray = [
{id: 'uniqueObjectId', role: 'Object Role Name'
// Other AccDC API property and method declarations go here...
}];

The array of AccDC Object declarations is passed as a parameter to the $A() function, which instantiates them as registered AccDC Objects.

$A(myObjArray);

All instantiated AccDC Objects are then registered within the $A.reg associative array, which can be queried directly using the ID of each AccDC Object in order to reference, configure, and control specific objects using JavaScript.

Example:

var dc = $A.reg['uniqueObjectId'];

Or

var dc = $A.reg.uniqueObjectId;

An instantiated AccDC Object can then be programmatically configured by modifying or invoking properties and methods within the object instance.

Examples:

// Set literal content to be rendered

dc.source = 'Hello World';

// Set the body as the container insertion point

dc.isStatic = 'body';

// Prepend the rendered content to the body content instead of replacing

dc.prepend = true;

// Set a top level class name for the newly rendered container Div  element

dc.className = 'banner';

dc.runAfter = function(dc){
// Do something after the content finishes loading
};

// Render the new content

dc.open();

Alternatively, all of the above property and method declarations can be included within the object literal declaration, before the object array is passed to the $A() function.

Example:

var myObjArray = [
{
	id: 'uniqueObjectId',
	role: 'Object Role Name',
	source: 'Hello World',
	isStatic: 'body',
	prepend: true,
	className: 'banner',
	runAfter: function(dc){
// Do something after the content finishes loading
},
runAfterClose: function(dc){
// Do something after the content finishes closing
},
// Render the object immediately
autoStart: true,
// Automatically announce the rendered textual content for screen reader users
announce: true
}];

// Then register the object array

$A(myObjArray);

All AccDC API properties and methods are applicable to AccDC Objects, and are confined within the scope of that object.

To learn about sibling and global overrides for AccDC Objects, view the details about the $A() function within the AccDC Core API documentation.

AccDC Objects can also be used to store specific data that relates only to that object, which can then be accessed by other AccDC Objects.

Example:

// Save data within one AccDC Object

dc.tmp = {form: formElement};

// Then access the data from another AccDC Object or process

var dataString = serialize( $A.reg.uniqueObjectId.tmp.form.elements );

All data stored within an AccDC Object remains within the object, even after the close() method is used to close the object and remove its content from the DOM.

Only the $A() method will completely destroy an AccDC Object and all of its stored data.

All of the Accessible Component Modules tap into this functionality by interfacing with the AccDC API.

If, for some reason an AccDC Object is not rendering properly when the open() method is invoked, Debugging Mode can be used to diagnose the cause of the issue.

Example:

// Enable Debugging Mode

$A.fn.debug = true;

When set to true, this will throw an alert with specific instructions if the issue is caused by a lack of or improper combination of AccDC API properties.

Debugging Mode is set to false by default.

Currently there are four versions of the AccDC API available:

  1. The Standalone version, which requires no third party dependencies and is compatible with all JavaScript libraries and frameworks without conflict.
  2. The jQuery extension, which requires jQuery 1.8.3 or greater.
  3. The Dojo module, which uses the Dojo AMD Loader.
  4. The MooTools extension, which requires MooTools 1.4.5 or greater.

Since all Accessible Component Modules plug into the AccDC API, the same module code will work correctly in all AccDC API versions equally.

Example using the Standalone, jQuery, or MooTools AccDC versions:

<head>

<!-- If using the AccDC jQuery or MooTools extension, load jQuery or MooTools here first. -->

<script type="text/javascript" src="Acc.DC.API.js">
// Load AccDC, which will create the $A namespace
</script>

<script type="text/javascript" src="module_name.js">
// Load as many of the Accessible Component Modules as desired,
// which will add them to the $A namespace.
</script>

<script type="text/javascript" src="setup.js">
// Then load the setup script to invoke module functionality after the page finishes loading.
</script>

</head>

Example using Dojo:

<head>

<script type="text/javascript" src="dojo/dojo.js" data-dojo-config="async:true">
// Load Dojo asynchronously.
</script>

<script type="text/javascript">

// Configure AccDC modules and scripts to be loaded synchronously for flow control
InitAccDC = [
	'module1.js',
	'module2.js'
];

// Now load the AccDC API using the Dojo AMD Loader
// The referenced AccDC API file is located at dojo/acc.dc.api.js
require(['dojo/acc.dc.api']);

</script>

</head>

This will set up AccDC, and load all of the declared modules into the $A namespace, ready for use within your web application.

If the AccDC Bootstrap module is also loaded, then there is no need to include a setup script.

All configurations are controlled through HTML5 attributes within the markup and by editing the "accdc_bootstrap.js" file as desired to customize functionality.

When the Bootstrap Module is executed, it parses the newly loaded DOM, recognizes class names that correspond with specific Accessible Component Modules, then configures and invokes the specified module using HTML5 attributes within the markup to customize both output and behavior.

Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.

To enable this functionality, simply load the AccDC Bootstrap module after all of the desired Accessible Component Modules have been loaded.

Example using the Standalone, jQuery, or MooTools AccDC API versions:

<head>

<!-- If using the AccDC jQuery or MooTools extension, load jQuery or MooTools here first. -->

<script type="text/javascript" src="Acc.DC.API.js">
// Load AccDC, which will create the $A namespace
</script>

<script type="text/javascript" src="module_name.js">
// Load as many of the Accessible Component Modules as desired,
// which will add them to the $A namespace.
</script>

<script type="text/javascript" src="accdc_bootstrap.js">
// Then load AccDC Bootstrap to parse the DOM automatically
</script>

</head>

Example using Dojo:

<head>

<script type="text/javascript" src="dojo/dojo.js" data-dojo-config="async:true">
// Load Dojo asynchronously.
</script>

<script type="text/javascript">

// Configure AccDC modules and scripts to be loaded synchronously for flow control
InitAccDC = [
'module1.js',
'module2.js',
// Then load AccDC Bootstrap to parse the DOM automatically
'accdc_bootstrap.js'
];

// Now load the AccDC API using the Dojo AMD Loader
// The referenced AccDC API file is located at dojo/acc.dc.api.js
require(['dojo/acc.dc.api']);

</script>

</head>

Some modules refer to offscreen text, which can be used to provide textual information for screen reader users that is not displayed visually and has no impact on visual layout.

The following CSS class has been proven to work well for this purpose, which is the same that is built into AccDC as the "$A.sraCSS" object.

.offscreenText {
position: absolute;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
padding: 0;
border: 0;
height: 1px; 
width: 1px; 
overflow: hidden;
white-space: nowrap;
}

This styling configuration is based on the research done by Thierry Koblentz, which is more fully described at
https://developer.yahoo.com/blogs/tenydnblog/clip-hidden-content-better-accessibility-53456.html

Accessible Component Modules

IMPORTANT: All of the HTML markup syntax examples found within the expandable Accessible Component Module sections represent the minimal code necessary for using the associated JavaScript module included with the AccDC API, though the actual markup is flexible when implemented.

Since the associated JavaScript module handles key attributes such as tabindex, amongst relevant ARIA state and property attributes, these are not included within the HTML markup syntax examples, since assigning these manually would complicate the scripting setup process for each module.

To see how tabindex and relevant ARIA attributes are handled, use a DOM viewer utility to examine the rendered output of each live demo within the Coding Arena, where dynamic behaviors can be observed.

Accordions are a fairly simple control type that are easy to make accessible.

Though similar in both concept and execution to Tab Controls, they are not the same.

A Tab Control has a series of grouped triggering elements that expand and collapse, the rendered content of which is inserted directly after the triggering element group when opened. The container element insertion point for all Tab Control triggering elements is shared between them. Also, the group of triggering elements in a Tab Control has only one tab stop. The arrow keys are then used to switch focus between each Tab, and the Enter or Space key is used to expand the desired Tab content panel.

In contrast, an Accordion has a series of triggering elements that expand and collapse, the rendered content of which is inserted directly after the triggering element when opened. The container element insertion points for Accordions are not shared. Also, all Accordion links appear in the tab order. The reason why ARIA attributes such as role="tablist" and role="tab" are not included within accordions, is because the insertion of inline content would place dynamic content sections within the same Tablist container, making it impossible to determine the order of nested Tab controls when present within the inserted content.

The chosen implementation should always match the UI that it's being applied to, to prevent confusion.

The Accordion Module automates these processes by adding all related event handlers and managing all related rendering procedures.

  • Accordion with offscreen text to indicate role and state, aria-controls, role=region, and aria-labelledby: Demo
  • Accordion with ARIA role=button, aria-pressed, aria-controls, role=region, and aria-labelledby: Demo
  • Accordion with ARIA role=link, aria-expanded, aria-controls, role=region, and aria-labelledby: Demo

HTML Syntax

Referencing external content:

<div class="accordionGroup">
<a href="#" class="accAccordion" data-src="files/accordions.html#containerId1" data-insert="sectId1" data-defaultopen="true"  id="accordionId1">
Triggering Element One Name
</a>
<div id="sectId1"><!--
(accordionId1 content will be inserted here when opened)
--></div>
<a href="#" class="accAccordion" data-src="files/accordions.html#containerId2" data-insert="sectId2" id="accordionId2">
Triggering Element Two Name
</a>
<div id="sectId2"><!--
(accordionId2 content will be inserted here when opened)
--></div>
</div>

Or referencing internal content:

<div class="accordionGroup2">
<a href="#" class="accAccordion" data-internal="containerId1" data-insert="x-sectId1" data-defaultopen="true"  id="x-accordionId1">
Triggering Element One Name
</a>
<div id="x-sectId1"><!--
(x-accordionId1 content will be inserted here when opened)
--></div>
<a href="#" class="accAccordion" data-internal="containerId2" data-insert="x-sectId2" id="x-accordionId2">
Triggering Element Two Name
</a>
<div id="x-sectId2"><!--
(x-accordionId2 content will be inserted here when opened)
--></div>
</div>

HTML5 "data-" attributes are used to configure specific functionality for each accordion expand/collapse link. These include the following:

  • data-src : The resource path and pointer to the ID attribute of the accordion content container element. If set, data-internal should be blank or not included.
  • data-internal : The ID attribute of the accordion content container element within the same document. If data-internal is set, data-src should be blank or not included.
  • data-insert : The ID attribute of the container element where the accordion content will be inserted when rendered. (This must not be inside the triggering element)
  • data-defaultopen="true" : Specifies that the referenced accordion node will open automatically. Only one accordion node per group should include this attribute.

Required attributes:

  • All accordion triggering elements must include unique ID attribute values.

Important: The insertion point where accordion content is rendered must be inline with (meaning directly after) the triggering element, to ensure accessibility for screen reader and keyboard only users. (No other active elements or page content should separate them.)

The examples above use DIV tags as container elements, but it doesn't really matter what the container element is, as long as the IDs match up. For instance, the interactive samples in the Coding Arena use DL tags as the main container, DTs to hold the triggering element, and DDs to act as the insertion points, which works well and is easy to format.

Container Element HTML Syntax

<div id="containerId1">
Accordion panel 1 content goes here.
</div>

<div id="containerId2">
Accordion panel 2 content goes here.
</div>

JavaScript

$A.generateAccordion( 'div.accordionGroup a.accAccordion' , {
// Configuration key / value mappings
}, document , callbackFunction(dc){
// Run every time an accordion expand/collapse link is toggled
// 'dc' is the registered Accordion AccDC Object
// dc.triggerObj is the triggering element
// dc.containerDiv is the DOM node where all accordion panel content is rendered
// dc.loaded reflects whether the accordion panel is currently open
} );

Parameters

  1. The first parameter is a CSS Selector that specifies all accordion expand/collapse links that are part of the same accordion group.

    If multiple accordions are present on the same page, each accordion should be declared separately using the above statement, and the CSS Selector should only reference the expand/collapse node links that apply to that particular accordion, and to no other.

    The reason for this is simple. When an accordion is active, it will close all open accordion nodes when an expand link is activated. So if you don't want all of the nodes of every other accordion on the page to be closed at the same time as well, then you should separate them using unique CSS Selectors for each group.

  2. The second parameter is used to configure accordion functionality using key / value map overrides.

    Example:

    {
    
    // Set the hidden text role and state that will be added to the triggering element for screen reader users
    accordionRole: 'Accordion',
    accordionState: 'Expanded',
    
    // Set the accordion AccDC Object to render literal content
    // (only when pulling content from within the same page, remove otherwise)
    mode: 0,
    
    // Preload HTML markup to speed rendering
    // (only when pulling content from an external page, remove otherwise)
    preload: true,
    
    // Preload images to speed rendering
    // (only when pulling content from an external page, remove otherwise)
    preloadImages: true,
    
    // Set the class name that will be added to the triggering element of the currently open accordion
    toggleClass: 'open',
    
    // Choose whether or not to make accordion expand/collapse links toggles as well
    isToggle: false
    
    // Additional AccDC API properties and methods may be applied here as well if desired.
    
    }
    
  3. The third parameter (contextDOM_Node) specifies the container DOM node where the accordion is contained, which confines the CSS Selector to the contents of this node. This can also be used to reference accordion groups contained within iFrame documents.

  4. The fourth parameter is a callback function that can be used to configure additional functionality whenever an accordion is opened or closed.

Programmatic Control

Every accordion node is registered as an AccDC Object, the ID of which matches the ID attribute value on the accordion expand/collapse link. For this reason, all accordion expand/collapse links must have unique ID attribute values.

This means that you can programmatically control each accordion node using JavaScript if desired, like so:

// Get a reference to the accordion AccDC Object for the accordion expand/collapse link with id="uniqueId"
var dc = $A.reg['uniqueId'];

// Now invoke the object
dc.open();

// Or close it
dc.close();

// All other AccDC API properties and methods can be applied here as well.

Triggering Element Requirements

Regarding the triggering element for expand/collapse links, you should always use an active element for this purpose to ensure accessibility for both screen reader and keyboard only users.

Within the Coding Arena samples, these are standard links (A tags with an Href attribute), which includes a SPAN tag with a changeable background image. However, you can use whatever type of triggering element you wish, a standard link, button, or image link, with any type of styling. There must be an active element as a triggering element though, to ensure accessibility.

Styling

The sample accordions in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the accordion. This is also useful as a practice template for trying out different styling designs with custom content.

When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled accordion will be accessible.

Bootstrapping

Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.

The accordions within the Bootstrap folders are configured using HTML5 "data-" attributes within the HTML markup.

When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class "accAccordion", then configures the same module declaration as previously described using these HTML5 attributes.

Available HTML5 attributes for the triggering element:

  • data-src : The resource path and pointer to the ID attribute of the accordion content container element. If set, data-internal should be blank or not included.
  • data-internal : The ID attribute of the accordion content container element within the same document. If data-internal is set, data-src should be blank or not included.
  • data-defaultopen="true" : Specifies that the referenced accordion node will open automatically. Only one accordion node per group should include this attribute.
  • data-role : The role name that is conveyed to screen reader users within the accordion link. Accordion is set by default if no value is specified.
  • data-openstate : The open state text that is conveyed to screen reader users within the accordion link when open. Expanded is set by default if no value is specified.
  • data-insert : The ID attribute of the container element where accordion node content will be inserted. The referenced container element must not be included within the accordion link node.
  • data-group : The shared group name for all related nodes within an accordion. This is used to differentiate separate accordion groups within the same document.

Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".

Required attributes for the triggering element:

  • class="accAccordion" : The bootstrap class name that specifies an accessible accordion node.
  • id : The unique ID of the element. This value is also registered as the ID of the individual accordion node AccDC Object, making it possible to invoke the object programmatically.
    E.G $A.reg.uniqueID.open();
    // All other AccDC API properties and methods are similarly available.

Tabs are a fairly simple control type that are easy to make accessible.

Though similar in both concept and execution to Accordions, they are not the same.

An Accordion has a series of triggering elements that expand and collapse, the rendered content of which is inserted directly after the triggering element when opened. The container element insertion points for Accordions are not shared. Also, all Accordion links appear in the tab order. The reason why ARIA attributes such as role="tablist" and role="tab" are not included within accordions, is because the insertion of inline content would place dynamic content sections within the same Tablist container, making it impossible to determine the order of nested Tab controls when present within the inserted content.

In contrast, a Tab Control has a series of grouped triggering elements that expand and collapse, the rendered content of which is inserted directly after the triggering element group when opened. The container element insertion point for all Tab Control triggering elements is shared between them. Also, the group of triggering elements in a Tab Control has only one tab stop. The arrow keys are then used to switch focus between each Tab, and the Enter or Space key is used to expand the desired Tab content panel.

The chosen implementation should always match the UI that it's being applied to, to prevent confusion.

The Tab Module automates these processes by adding all related event handlers and managing all related rendering procedures.

HTML Syntax

Referencing external content:

<div role="tablist" id="tabList1">
<div>
<a href="#" class="accTab" data-src="files/tabs.html#containerId1" data-insert="tabPanelId" data-defaultopen="true"  id="tabId1" role="tab">
<span>Triggering Element One Name</span>
</a>
</div>
<div>
<a href="#" class="accTab" data-src="files/tabs.html#containerId2" data-insert="tabPanelId" id="tabId2" role="tab">
<span>Triggering Element Two Name</span>
</a>
</div>
</div>

<div id="tabPanelId"><!--
(All Tab panel content will be inserted here when a Tab is opened)
--></div>

Or referencing internal content:

<div role="tablist" id="tabList2">
<div>
<a href="#" class="accTab" data-internal="containerId1" data-insert="tabPanelId2" data-defaultopen="true"  id="x-tabId1" role="tab">
<span>Triggering Element One Name</span>
</a>
</div>
<div>
<a href="#" class="accTab" data-internal="containerId2" data-insert="tabPanelId2" id="x-tabId2" role="tab">
<span>Triggering Element Two Name</span>
</a>
</div>
</div>

<div id="tabPanelId2"><!--
(All Tab panel content will be inserted here when a Tab is opened)
--></div>

HTML5 "data-" attributes are used to configure specific functionality for each Tab expand/collapse link. These include the following:

  • data-src : The resource path and pointer to the ID attribute of the Tab content container element. If set, data-internal should be blank or not included.
  • data-internal : The ID attribute of the Tab content container element within the same document. If data-internal is set, data-src should be blank or not included.
  • data-insert : The ID attribute of the container element where the Tab content will be inserted when rendered. (This must not be inside the triggering element, and must be the same for all Tab links within the same group)
  • data-defaultopen="true" : Specifies that the referenced Tab panel will open automatically. (Only one Tab link per group should include this attribute.)

Required attributes:

  • role="tablist" must be included within the container element (where all Tab links are contained).
  • role="tab" must be included within all Tab links.
  • Both the Tablist container element (with role="tablist") and all Tab links (with role="tab") must include unique ID attribute values.

Important: The insertion point where Tab panel content is rendered must be inline with (meaning directly after) the Tablist group, to ensure accessibility for screen reader and keyboard only users. (No other active elements or page content should separate them.)

The examples above use DIV tags as container elements, but it doesn't really matter what the container element is, as long as the IDs match up. For instance, the interactive samples use standard list markup to group related Tab links, which works well and is easy to format.

Container Element HTML Syntax

<div id="containerId1">
Tab panel 1 content goes here.
</div>

<div id="containerId2">
Tab panel 2 content goes here.
</div>

The following attributes are handled automatically by the Tab Module:

  • tabindex
  • aria-label
  • aria-owns
  • aria-selected
  • aria-expanded
  • aria-posinset
  • aria-setsize

JavaScript

$A.setTabs( 'div.tabGroup a.accTab' , {
// Configuration key / value mappings
}, useARIA? , document ,
function(dc){
// Optional callback to execute after a Tab panel opens
// 'this' is the same as dc.triggerObj, and is the DOM node for the triggering element
// dc.containerDiv is the DOM container node that contains the newly loaded Tab panel content.
} );

Parameters

  1. The first parameter is a CSS Selector that specifies all Tab expand/collapse links that are part of the same Tablist group.

    If multiple Tablist groups are present on the same page, each Tablist should be declared separately using the above statement, and the CSS Selector should only reference the expand/collapse node links that apply to that particular Tablist, and to no other.

    The reason for this is simple. When a Tab panel is opened, it will close all other Tab panels when an expand link is activated. So if you don't want all of the nodes of every other Tablist group on the page to be closed at the same time as well, then you should separate them using unique CSS Selectors for each group.

  2. The second parameter is used to configure Tab functionality using key / value map overrides.

Example:

{

// Set the Tab panel boundary text that will be conveyed to screen reader users
role: 'Tab',
accStart: 'Start',
accEnd: 'End',

// Set the Tab AccDC Object to render literal content
// (only when pulling content from within the same page, remove otherwise)
mode: 0,

// Preload HTML markup to speed rendering
// (only when pulling content from an external page, remove otherwise)
preload: true,

// Preload images to speed rendering
// (only when pulling content from an external page, remove otherwise)
preloadImages: true,

// Set a className that will be added to the triggering element for the currently active tab
toggleClass: 'active',

// Choose whether or not to make Tab expand/collapse links toggles as well
isToggle: false

// Additional AccDC API properties and methods may be applied here as well if desired.

}
  • The third parameter (useARIA?) is a Boolean (true or false), that specifies whether the Tab Control will be configured as an ARIA Tab widget.
    If true, role="tablist" and role="tab" must be present within the markup in the correct locations.
    If false, role="tablist" and role="tab" must not be included within the markup.

    Important: The ARIA attributes role="tablist" and role="tab" must only be used on client side widgets that don't require a page refresh or navigate to another page.
    The reasons why are fully discussed in the article at http://lnkd.in/5nPudh

  • The fourth parameter (contextDOM_Node) specifies the container DOM node where the Tablist markup is contained, which confines the CSS Selector to the contents of this node. This can also be used to reference Tab groups contained within iFrame documents.

  • The fifth parameter is a callback function that can be used to configure additional functionality whenever a Tab panel finishes rendering.

  • Programmatic Control

    Every Tab panel is registered as an AccDC Object, the ID of which matches the ID attribute value on the Tab expand/collapse link. For this reason, all Tab expand/collapse links must have unique ID attribute values.

    This means that you can programmatically control each Tab panel using JavaScript if desired, like so:

    // Get a reference to the Tab AccDC Object for the Tab expand/collapse link with id="uniqueId"
    var dc = $A.reg['uniqueId'];
    
    // Now invoke the object
    dc.open();
    
    // Or close it
    dc.close();
    
    // All other AccDC API properties and methods can be applied here as well.
    

    Triggering Element Requirements

    Regarding the triggering element for expand/collapse links, you should always use an active element for this purpose to ensure accessibility for both screen reader and keyboard only users.

    Within the Coding Arena samples, these are standard links (A tags with an href attribute). However, you can use whatever type of triggering element you wish, a standard link, button, or image link, with any type of styling. There must be an active element as a triggering element though, to ensure accessibility.

    If using an image link however, the img tag must have a null alt attribute (alt="") to hide it from screen reader users, and offscreen text must be included if no visible screen text is present. This will ensure the highest level of accessibility for the highest percentage of screen reader users across all platforms.

    Styling

    The sample Tabs in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the Tablist. This is also useful as a practice template for trying out different styling designs with custom content.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled Tablist will be accessible.

    Bootstrapping

    Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.

    The Tablists within the Bootstrap folders are configured using HTML5 "data-" attributes within the HTML markup.

    When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class "accTab", then configures the same module declaration as previously described using these HTML5 attributes.

    Available HTML5 attributes for the triggering element:

    • data-src : The resource path and pointer to the ID attribute of the tab content container element. If set, data-internal should be blank or not included.
    • data-internal : The ID attribute of the tab panel container element within the same document. If data-internal is set, data-src should be blank or not included.
    • data-defaultopen="true" : Specifies that the referenced tab will open automatically. Only one tab per group should include this attribute.
    • data-role : The role name that is conveyed to screen reader users as beginning and ending boundary text for the tab panel content. "Tab" is set by default if no value is specified.
    • data-insert : The ID attribute of the container element where tab panel content will be inserted.
    • data-group : The shared group name for all related tabs. This is used to differentiate separate tab groups within the same document.
    • data-headinglvl : The heading level of the tab panel section for screen reader users. This should reflect proper nesting. If the tab panel content is inserted within an H1, data-headinglvl should be set to '2', and so on. If no value is specified, and if no override is set within accdc_bootstrap.js via ariaLevel:#, '3' will be set by default.

    Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".

    Required attributes for the triggering element:

    • role="tablist" : The ARIA role that specifies a group of tab controls. This must only be included within the element that contains all individual tabs.
    • role="tab" : The ARIA role that specifies an individual tab control. To ensure accessibility, this element must not contain any other active elements.
    • class="accTab" : The bootstrap class name that specifies an accessible Tab link.
    • id : The unique ID of the element. This value is also registered as the ID of the individual Tab AccDC Object, making it possible to invoke the object programmatically.
      E.G $A.reg.uniqueID.open();
      // All other AccDC API properties and methods are similarly available.

    Implementation Notes

    As an ARIA widget implementation, the Tablist container element must include the attribute role="tablist", and all Tab item links must include the attribute role="tab" to ensure accessibility for screen reader users.

    Both the Tablist container element and all Tab item links must include unique ID attribute values.

    The innerHTML for each Tab item link must contain a textual label, which may be positioned offscreen to hide it visually if desired. (This textual label is necessary so that screen reader users will be able to identify the purpose of the node, and also to ensure proper feedback in iOS devices when using VoiceOver.)

    Images may also be used within Tab item links if desired, however, they must include the attribute alt="" to hide them from screen reader users.

    To add tooltips for sighted users, use the Title attribute instead, and make sure that the tooltip text matches the text contained within the textual label if positioned offscreen to hide it visually.

    ARIA Comboboxes are used to trigger dynamic lists of related options, such as with auto-suggest filters and custom dropdowns.

    Expected behaviors:

    • All Combobox controls are keyboard focusable unless explicitly disabled, and must include an accessible close or toggle icon for sighted mouse and mobile touch device users when applicable.
    • Interactive editable Combobox controls that use an Input+type=text element, open using the Down arrow, are navigated using Up and Down, are saved and closed by pressing Alt+Up or Enter, are canceled and closed by pressing Escape, and support uninterrupted editability when Left or Right or any other non-control key is pressed.
    • Interactive readonly Combobox controls that use an Input+type=text element, open using the Down arrow, are navigated using Up and Down, are saved and closed by pressing Alt+Up or Enter, are canceled and closed by pressing Escape, and require a toggleable triggering element for sighted mouse and mobile touch device users.
    • Interactive Combobox controls that use simulated active elements such as Divs or Spans, open using the Down arrow or Enter key, are navigated using Up and Down, are saved and closed by pressing Alt+Up or Enter, are canceled and closed by pressing Escape, and act as their own actionable toggle control.

    The ARIA Combobox Module automates these processes by adding all related event handlers.

    HTML Syntax

    The HTML syntax varies depending on which type of implementation is desired.

    Editable Input

    <input role="combobox" type="text" title="Explicit label text" />
    

    Readonly Input

    <input role="combobox" type="text" readonly title="Explicit label text" />
    

    Simulated Active Element

    <span title="Explicit label text" role="combobox" tabindex="0" class="focusableElement" >
    <span class="childContainerToUpdate"></span>
    </span>
    
    • The markup structure for simulated active elements doesn't require the use of Spans, and may consist of any HTML container markup with embedded tags.
    • The tabindex attribute is required on the same container element that includes role=combobox to ensure keyboard accessibility, and an empty child container element must be included where dynamically saved values will be inserted.

    All Combobox controls are bound to a standard Select element instance, which may be hidden within the page using CSS, or dynamically generated using JavaScript to support dynamic population via AJAX.

    To enable multiselect functionality, add the attribute multiple="multiple" to the hidden select element. (Only available when using the ARIA Combobox Module R2.0 or greater.)

    <select name="control-name">
    <option value="value-1"> Value 1 name </option>
    <option value="value-2"> Value 2 name </option>
    <option value="value-3"> Value 3 name </option>
    </select>
    

    To set a default value for the Combobox other than index[0], add the selected attribute to the default option.

    The following attributes are handled automatically by the Combobox Module:

    • aria-activedescendant
    • aria-expanded
    • aria-controls
    • aria-autocomplete
    • aria-describedby
    • role=listbox
    • role=option

    JavaScript

    // Create a new Combobox instance and bind the relevant elements
    
    var myCombobox = new $A.Combobox( selectElementDOM-Node , inputDOM-Node , optionalChildDOM-Node );
    
    // Configure settings here prior to invocation
    
    // Then invoke the Combobox for auto-rendering
    
    myCombobox.start();
    

    Parameters

    1. The first parameter is the hidden Select element DOM node that will be bound to the Combobox control.

    2. The second parameter is the focusable role=combobox element that will be bound to the hidden Select element.

    3. The third parameter is the embedded child container element that will be bound to the role=combobox element, which is only applicable if the role=combobox element is not a standard Input or Textarea element.

    Programmatic Control

    After a Combobox control is instantiated, the following public properties and methods are available.

    Methods:

    // Set the listbox to render all Select Options regardless of the current value
    myCombobox.setShowAll(Boolean); // Default: False
    
    // Set the listbox to render only Select Options that match the substring value
    myCombobox.setSubstringMatch(Boolean); // Default: False
    
    // Set the listbox to render only Select Options that include all of the space delimited words in the current value
    myCombobox.setWordMatch(Boolean); // Default: False
    
    // Set the Combobox to automatically display the currently selected value within the hidden Select element onStart
    myCombobox.setDefault(Boolean); // Default: True
    
    // Set the currently selected listbox value to automatically be saved when focus moves away from the Combobox control
    myCombobox.setAutoComplete(Boolean); // Default: False
    
    // Set the parent/child tag markup structure for the dynamically rendered listbox
    myCombobox.setTags({
    parentTag: 'ul',
    childTag: 'li'
    });
    
    // Set dynamic class names
    myCombobox.setClassNames({
    toplevelClass: 'toplevel-div clearfix', // Top level Div class of Combobox listbox
    middleClass: 'middle-div clearfix', // Mid level Div class of Combobox listbox
    listboxClass: 'listbox clearfix', // // parentTag class
    optionClass: 'option clearfix', // childTag class
    activeClass: 'active', // Currently active Combobox listbox option
    toggleClass: 'pressed' // Pressed state class of the altTrigger element
    });
    
    // Set CSS autopositioning relative to the triggering Combobox element.
    // Accepted AccDC API values between 0-disabled-default and 12
    // For details, see WhatSock.com > Core API > CSS > .autoPosition
    myCombobox.setAutoPosition(Number); // Default: 0
    
    	// Set a positive or negative top/left offset to be applied to the autoPosition property calculation
    myCombobox.setOffset({
    top: Number,
    left: Number
    });
    
    // Set the number of listbox options to render when displayed
    myCombobox.setSize(Number); // Default: 5
    
    // Set a different element to act as an autoPosition focus element instead of the Combobox control
    myCombobox.setPosAnchor(alternateDOM-Node); // Will not change the DOM insertion point and reading order
    
    // Set a different element to act as an insertion point and autoPosition focus element instead of the Combobox control
    myCombobox.setTargetObj(alternateDOM-Node); // Will change the DOM reading order
    
    // Invoke the Combobox control and apply all saved settings
    myCombobox.start();
    
    // Close the Combobox control and pause functionality
    myCombobox.stop();
    
    // Manually open the Combobox listbox using all applied settings
    myCombobox.open();
    
    // Set a handler to execute every time the Combobox listbox is rendered
    myCombobox.onOpen(function(dc){
    // this = the Combobox control
    // dc = the AccDC Object instance for the Combobox listbox
    });
    
    // Manually close the Combobox listbox
    myCombobox.close();
    
    // Set a handler to execute every time the Combobox listbox is closed
    myCombobox.onClose(function(dc){
    // this = the Combobox control
    // dc = the AccDC Object instance for the Combobox listbox
    });
    
    // Set a toggle control to open or close the Combobox listbox
    // Must always be set when implementing readonly Input+type=text elements to ensure sighted mouse and mobile touch device support
    myCombobox.setAltTrigger(toggleElementDOM-Node);
    
    // Set a handler to execute every time the toggle altTrigger element is activated
    myCombobox.onTriggerChange(function(altTriggerElement, toggleState){
    // this = altTriggerElement
    // toggleState = true or false
    });
    
    // Set a handler to execute every time a new value is saved to the Combobox control
    // This will override the default functionality
    myCombobox.onSelect(function(optionName, optionValue, comboboxControl, selectElement){
    // this = comboboxControl
    // optionName = the visible string for the hidden Select option that is highlighted.
    // optionValue = the value attribute for the hidden Select option that is selected. This parameter changes to an array of selected option nodes when multiple is set instead. (Only available when using the ARIA Combobox Module R2.0 or greater.)
    // comboboxControl = the Combobox control element
    // selectElement = the hidden Select element
    // Save the new value accordingly
    // then return the saved string to prevent auto reopening of the Combobox listbox
    return 'saved string';
    });
    
    // Set multiple divider to break up list item markup properly when updated.
    // Automatically becomes available when the multiple attribute is set on the hidden select element. (Only available when using the ARIA Combobox Module R2.0 or greater.)
    myCombobox.setMultipleDivider(function(values){
    // 'values' is an array of string names for the selected option nodes.
    return values.join('	');
    });
    
    // Clear all selected options when multiple is set on the hidden select element.
    // (Only available when using the ARIA Combobox Module R2.0 or greater.)
    myCombobox.clearAll();
    
    // Set a character minimum when typing into an editable combobox before autosuggested options are rendered.
    // (Only available when using the ARIA Combobox Module R2.0 or greater.)
    myCombobox.setCharMin(#); // Default = 0
    
    // Get the current value of the hidden select element
    // Returns a value property string for single select elements, or an array of selected option DOM nodes when the multiple attribute is set on the select element.
    // (Only available when using the ARIA Combobox Module R2.0 or greater.)
    myCombobox.getValue();
    
    // Manually resynchronize the hidden Select to rebuild available Options for the Combobox listbox
    // This can be used to repopulate rendered options after remote API queries via AJAX cause the hidden Select to contain new Options
    myCombobox.update();
    
    // Set a string to be announced to screen reader users when the Combobox control receives focus
    myCombobox.setPromptText(String); // Default: ''
    
    // Set a name for the offscreen Close link for screen reader users
    // Necessary for non-sighted touch screen device users to detect the end of the Combobox listbox when rendered
    // To disable the offscreen Close link when needed, pass a null value ("") to the method.
    myCombobox.setCloseText(String); // Default: 'Close Popup'
    

    Properties:

    // Access the hidden Select element DOM node
    myCombobox.select
    
    // Access the role=combobox element DOM node
    myCombobox.combobox
    
    // Access the dynamically rendered listbox AccDC Object, including all AccDC API properties and methods
    // View the Core API tab at WhatSock.com for a full index of available AccDC API properties and methods.
    myCombobox.dc
    

    Styling

    The samples in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.

    You can change the styling however you wish to fit the layout of any UI, and the comboboxes will still be accessible to both screen reader and keyboard only users regardless. Simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus.

    An ARIA Data Grid is one of the most complicated of ARIA Widget types to make accessible, since it involves many different types of user interaction.

    Expected behaviors: The entire grid should have only one tab stop, one cell should be focusable at a time, the arrow keys should move focus between cells, Home and End should move focus to the beginning or end of a row, PageUp and PageDown should open the previous or next page of the grid, Alt+PageUp and Alt+PageDown should move focus to the first or last page in the grid, Space and Enter should activate the current cell or row, and textual equivalents should indicate the role and state of each interactive control type for screen reader users.

    The Data Grid Module automates these processes by adding all related event handlers and managing all related rendering procedures.

    HTML Syntax

    <div id="gridContainerId" ></div>
    

    The following attributes are handled automatically by the Data Grid Module:

    • tabindex
    • aria-owns
    • role=grid
    • role=rowgroup
    • role=row
    • role=gridcell
    • role=columnheader
    • role=rowheader
    • aria-rowindex
    • aria-colindex
    • aria-labelledby
    • aria-describedby
    • aria-selected
    • title
    • aria-hidden

    JavaScript

    var grid = new $A.DataGrid( ContainerNodeOrID );
    

    Parameters

    1. The first parameter specifies the container element where the data grid will be rendered, and may be a DOM node or an ID string.

    Programmatic Control

    // Set the registered columns including unique IDs and label text
    // The order of items in the array will dictate the default column ordering when rendered
    
    grid.mapColumnNames([
    {
    // ID that is associated with all cells in the column
    id: 'col1id',
    // The text that will be rendered as the column header
    lbl: 'User Name',
    // Set an optional class to be added to all cells within the column
    colClass: 'col1'
    },
    {
    id: 'col2id',
    lbl: 'Email Address',
    colClass: 'col2'
    },
    {
    id: 'col3id',
    lbl: 'Publish Record',
    colClass: 'col3'
    }
    ]);
    
    // Programmatically change the order of rendered columns
    // This method rearanges the array order of the objects passed to grid.mapColumnNames(ObjArray)
    // Which is used to determine rendering order
    // This must be followed by grid.open() to rerender the grid after a change is made
    
    // E.G Change the third column to the first column
    grid.changeColumnOrder(2, 0);
    
    // Enable row headers and specify the column ID to be used for this purpose
    // This must be followed by grid.open() to rerender the grid after a change is made
    
    grid.enableRowHeaders(true, 'col1id');
    // Or disable
    grid.enableRowHeaders(false);
    
    // Set a maximum number of rows to render before pagination is applied
    // If set to 0, all records will render and no pagination will occur
    // This must be followed by grid.open() to rerender the grid after a change is made
    
    grid.setRowMax(25);
    
    // Enable or disable editability for grid cells
    // This will render an edit field for strings or handle toggle events for buttons.
    // This must be followed by grid.open() to rerender the grid after a change is made
    
    grid.editable(true);
    // Or to disable
    grid.editable(false);
    
    // Add rows to a grid instance
    
    grid.add(rowObject_or_rowObjectArray);
    
    // Each row must adhere to the following object literal format:
    
    {
    
    id: 'uniqueRowId',
    
    cells: {
    
    'col1id': {
    // Set the cell type, may be either 'text' or 'toggle'
    // Defaults to 'text' if omitted
    type: 'text',
    // Set an optional readonly flag to disable editability if the grid is editable
    // Defaults to false if omitted
    readonly: true,
    // Set the initial value of the cell
    value: 'My User Name'
    },
    
    'col2id': {
    value: 'email_address@whatever.com'
    },
    
    'col3id': {
    type: 'toggle',
    readonly: false,
    value: true,
    // For toggles, set the name property to specify a visual textual label
    name: 'Published',
    // For toggles, specify an optional class to be added when the toggle is set to true
    // This will override the general toggle class specified within grid.setStaticClasses
    toggleClass: 'toggle-button-pressed'
    }
    
    }
    
    }
    
    // Set a value changed listener for handling serverside posting when cell values change
    
    grid.setChangeListener(function(originalCellObject, newValue, rowObject, gridInstance){
    // rowObject reflects the same object passed to grid.add
    // so that rowObject.id reflects the original unique row ID
    // originalCellObject reflects the cell object instance passed within 'cells' when passed to grid.add
    // and cellObject.id reflects the column ID, so that rowObject.id and cellObject.id can be used as X Y coordinates to identify the correct cell in the grid.
    // Compare originalCellObject.value with newValue to perform input validation or other processes.
    // To prevent rendering the changed input or new toggle state, simply return false
    });
    
    // Enable or disable double click or single click mouse interaction for selectable rows and editable cells
    // This must be followed by grid.open() to rerender the grid after a change is made
    // When set to false, a single mouse click will toggle selectability or trigger an edit action
    
    grid.useDblClick(false);
    
    // Enable or disable row selectability
    // This must be followed by grid.open() to rerender the grid after a change is made
    // When set to true, editability will automatically be set to false to prevent functionality and keyboard accessibility conflicts
    
    grid.setSelect({
    enable: true,
    // Set a class to be added to the TR node every time a row is selected
    toggleClass: 'selected',
    // Set single or multiSelect
    multiSelect: false,
    // Use ARIA for selection or cross-platform offscreen text instead
    // Important: The use of aria-selected for row selection is not well supported by screen readers at this time
    ariaSelect: false,
    // Choose whether rendering another page will automatically unselect previously selected rows
    // Set to false to unselect rows automatically, or true to keep selection active
    preserve: false,
    // Set a callback to execute every time a row is toggled
    callback: function(rowObject, state, prevSelectedRowsArray, gridInstance){
    // rowObject is the activated row object.
    // rowObject.rowNode is the TR DOM node for the toggled row.
    // 'state' reflects the proposed state change, which is the opposite of rowObject.selected.
    // prevSelectedRowsArray is an array of all previously selected rowObjects, not counting the current rowObject.
    // To cancel the toggle action, return false
    }
    });
    
    // Or pass single properties to set functionality
    
    grid.setSelect({
    enable: false
    });
    
    // Unselect all previously selected rows
    
    grid.unselectAll();
    
    // Select all rows on the currently rendered page
    
    grid.selectAll();
    
    // Get an array of all currently selected rowObjects
    // Each rowObject reflects the same object literal passed in grid.add()
    
    // Get an array of selected rowObjects
    var selected = grid.getSelected(),
    // Get the row ID for the first selected row
    rowId = selected[0].id,
    // Or get the TR DOM node of the first selected row
    rowNode = selected[0].rowNode;
    
    // Programmatically select one or more rows using an array of row IDs
    
    grid.select(['rowId1', 'rowId2']);
    
    // Enable or disable row deletion
    // This must be followed by grid.open() to rerender the grid after a change is made
    // When enabled, the Delete key will delete all currently selected rows from the grid and destroy their rowObjects in the cache
    // Selectability must be set to true for this functionality to be used
    
    grid.setDelete({
    enable: true,
    // Set a function to execute prior to deletion
    runBefore: function(selectedRowIDs_array){
    // Return false to cancel deletion
    },
    // Set a callback to execute on every row that is deleted
    callback: function(rowObject, gridInstance){
    // rowObject.id is the table row ID that is being deleted
    // alert(rowObject.id);
    // return false to cancel deletion from the grid
    },
    // Set a function to execute after deletion is completed
    runAfter: function(deletedRowIDs_array){
    // Do something
    }
    });
    
    // Or to disable
    
    grid.setDelete({
    enable: false
    });
    
    // Programmatically delete all currently selected rows and destroy their rowObjects in the cache
    
    grid.deleteRows();
    
    // Programmatically delete one or more rows and destroy their rowObjects in the cache using an array of row IDs
    
    grid.deleteRows(['rowId1', 'rowId2']);
    
    // Programmatically delete all rows in the grid instance and destroy their rowObjects in the cache
    
    grid.deleteAllRows();
    
    // set accessible text for screen reader users
    
    grid.setAccessibleText({
    // Set offscreen and tooltip text for toggle cells
    toggleButtonRole: 'Toggle Button',
    toggleButtonState: 'Pressed',
    disabledText: 'Disabled',
    // Set the page text to be announced to screen reader users during infinite scrolling. E.G "Page 2", "Page 3", etc.
    pageRole: 'Page',
    // Set the active state and help tooltip text for mouse users
    selectState: 'Selected',
    editLinkAction: 'Editable',
    dblClickTitle: 'Click to activate',
    // Set the title text for the edit field
    editFieldTitle: 'Press Enter to save, or Escape to cancel.'
    });
    
    // Set static classes
    
    grid.setStaticClasses({
    // General Table element class for the grid
    gridClass: 'data-grid',
    // Additional Table element class when the grid is set to Readonly
    gridReadOnlyClass: 'data-grid-readonly',
    // Additional Table element class when the grid is set to Editable
    gridEditableClass: 'data-grid-editable',
    // Additional Table element class when the grid is set to Selectable
    gridSelectableClass: 'data-grid-selectable',
    // General TR element class for the grid
    gridRowClass: 'data-grid-row',
    // Additional TR element class when a grid row has focus
    gridRowFocusedClass: 'data-grid-row-focused',
    // General TH and TD element class for the grid
    gridCellClass: 'data-grid-cell',
    // Additional TD element class when a grid cell is set to Readonly
    cellReadOnlyClass: 'data-grid-cell-readonly',
    // Additional TD element class when a grid cell has focus
    gridCellFocusedClass: 'data-grid-cell-focused',
    // General STRONG element class for grid text cells
    gridCellLinkClass: 'data-grid-cell-link',
    // General STRONG element class for grid toggle cells
    gridCellToggleClass: 'data-grid-cell-toggle',
    // Additional STRONG element class for grid toggle cells when set to True
    gridCellTogglePressedClass: 'data-grid-cell-toggle-pressed',
    // General DIV and INPUT element class for grid edit field popups
    editFieldClass: 'data-grid-cell-link-edit'
    });
    
    // Get the total number of rows in the grid instance
    
    grid.totalRows();
    
    // Pagination: Get the current page number
    
    grid.currentPage();
    
    // Pagination: Get the total number of pages in the grid instance
    
    grid.totalPages();
    
    // Set a page index changed listener to execute every time the current or total number of pages changes within the grid instance
    
    grid.setPageIndexChangeListener(function(currentPage, totalPages, gridInstance){
    // Do something
    });
    
    // Open a specific page without rerendering the parent grid
    
    grid.openPage(number);
    
    // Open the first page in the grid
    
    grid.firstPage();
    
    // Open the previous page in the grid
    
    grid.prevPage();
    
    // Open the next page in the grid
    
    grid.nextPage();
    
    // Open the last page in the grid
    
    grid.lastPage();
    
    // Execute listener every time a grid object is opened in the DOM
    
    grid.setOpenListener(function(container, dc, gridInstance){
    // 'dc' is the grid AccDC Object
    });
    
    // Execute listener every time a grid object is closed in the DOM
    
    grid.setCloseListener(function(container, dc, gridInstance){
    // 'dc' is the grid AccDC Object
    });
    
    // Execute listener every time a grid TR object is rendered in the DOM
    
    grid.setAddListener(function(rowObject, dc, gridInstance){
    // rowObject.id is the unique row ID as passed in grid.add()
    // rowObject.rowNode is the rendered TR DOM node
    // 'dc' is the grid AccDC Object
    });
    
    // Execute listener every time a grid TR object is removed from the DOM
    
    grid.setRemoveListener(function(rowObject, dc, gridInstance){
    // rowObject.id is the unique row ID as passed in grid.add()
    // rowObject.rowNode is the rendered TR DOM node
    // 'dc' is the grid AccDC Object
    });
    
    // Execute listener every time a grid TD node receives focus
    
    grid.setMoveListener(function(newCell, oldCell, dc, gridInstance){
    // 'newCell' is the TD DOM node that has been given focus
    // 'oldCell' is the TD DOM node that used to have focus
    // 'dc' is the grid AccDC Object
    });
    
    // Assign a character maxLength value for the edit text popup
    
    grid.setEditMaxLength(255);
    
    // Set a positioning override for the placement of the edit text popup
    // Must return an object literal that contains the following properties: top, left, width, height
    
    grid.setEditOffset(function(cellObject){
    // cellObject.cellNode is the DOM node for the TD element that has focus
    // cellObject.cellNodeA is the DOM node for the STRONG element contained within the TD element that has focus
    var o = $A.xOffset(cellObject.cellNodeA); // Get top and left properties
    o.height = $A.xHeight(cellObject.cellNodeA); // Add height
    o.width = $A.xWidth(cellObject.cellNodeA); // Add width
    return o;
    });
    
    // Set an edit field load listener to execute every time the string edit field is opened for a cell
    
    grid.setEditLoadListener(function(editFieldNode, cellObject){
    // editFieldNode is the rendered edit Input element
    // cellObject is the cellObject that was triggered, providing access to all data associated with that cell
    // E.G
    // cellObject.cellNode is the actionable TD node that was activated
    // cellObject.value is the original value of the cell
    // cellObject.id is the column id for that cell
    // cellObject.rowObject.id is the unique row ID for that row
    // cellObject.rowObject.rowNode is the TR node for that row
    });
    
    // Set the value of a specific cell in the grid using its unique row ID and column ID as X Y coordinates
    // Row ID refers to the same value stored within rowObject.id, and col ID refers to the same value stored within cellObject.id
    
    grid.setValue('rowID', 'colID', value);
    
    // Get the value of a specific cell in the grid using its unique row ID and column ID as X Y coordinates
    // Row ID refers to the same value stored within rowObject.id, and col ID refers to the same value stored within cellObject.id
    
    grid.getValue('rowID', 'colID');
    
    // Programmatically store data within a specific cell in the grid using its unique row ID and column ID as X Y coordinates
    // Row ID refers to the same value stored within rowObject.id, and col ID refers to the same value stored within cellObject.id
    // When set, the data is alternatively available within the cellObject via cellObject.data['keyname']
    
    grid.setData('rowID', 'colID', 'keyname', data);
    
    // Programmatically retrieve data within a specific cell in the grid using its unique row ID and column ID as X Y coordinates
    // Row ID refers to the same value stored within rowObject.id, and col ID refers to the same value stored within cellObject.id
    
    grid.getData('rowID', 'colID', 'keyname');
    
    // Open a grid instance and render a page within the DOM
    // If no page number is passed as the first parameter, then 1 is inferred by default
    
    grid.open();
    // Or to open a specific page
    grid.open(number);
    
    // Close a grid instance and remove it from the DOM
    // This will not delete any of the cached rowObjects that were added via grid.add()
    
    grid.close();
    
    // Programmatically set focus to the grid
    // This always references the TD node that is currently active
    
    grid.focus();
    
    // Access the grid AccDC Object instance for optional modification
    
    var dc = getAccDCObject();
    
    // Access the container DOM node
    
    var myContainer = grid.container;
    

    Styling

    The sample data grids in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.

    You can change the styling however you wish to fit the layout of any UI, and the data grids will still be accessible to both screen reader and keyboard only users regardless.

    Simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled data grid will be accessible.

    Implementation Notes

    Notes about keyboard interactivity

    A focusable ARIA Grid is a complicated concept, and there are only a certain number of keyboard commands available that don't directly conflict with the screen reader or browser. The following keyboard commands should not be used for this reason:

    • Control+PageUp/PageDown: Is automatically intercepted by JAWS and never gets passed through to the grid.
    • Control+Up/Down: Is automatically intercepted by JAWS and never gets passed through to the grid.
    • Alt+Home: Automatically loads the home page in the browser.
    • Alt+Left/Right: Automatically activates the Back and Forward buttons in the browser.
    Notes about mouse interactivity

    When activating a selectable row or editable cell using the mouse, double click must be used. If a single click is used to0 invoke this functionality, it will conflict with screen reader behavior. For example, when browsing the page using JAWS in Virtual Cursor mode, it is necessary to press Enter on the desired grid cell to enter Applications Mode. When JAWS does this, it automatically activates the click event, which automatically invokes selection or editing for that cell.

    When double click is used instead, this conflict does not occur. Single tapping of a selectable or editable cell using a touch screen device however, works using one click.

    The ARIA Date Picker is a complex control type with a simple implementation.

    Expected behaviors: The associated INPUT field should not include readonly, an external triggering element should activate the date picker, the arrow keys should move between calendar cells and the calendar should scroll automatically between months, PageUp/PageDown should switch between months, Alt+PageUp/PageDown should switch between years, Enter should activate the selected date, and pressing Escape or Tab should close the calendar and return focus to the triggering element.

    The Calendar Module automates these processes by adding all related event handlers and managing all related rendering procedures.

    HTML Syntax

    <input type="text" id="dateInputId" title="Label text if no Label element is associated" />
    
    <a href="#" id="datePickerId"> Calendar Icon Name </a>
    
    Form field HTML markup requirements:
    • The INPUT field must not be set to readonly, so that users can manually edit date string entries.
    • Form field constraints, such as the desired date string format, must also be included with the form field label to maximize clarity. E.G "MM/DD/YYYY"

    JavaScript

    $A.setCalendar( 'UniqueCalendarId' , $A.getEl('datePickerId'), $A.getEl('dateInputId'), EnableComments<true/false> ,
    clickHandlerCallbackFunction(ev, dc, targetElementObj){
    // Configure date string and save it within targetElementObj
    targetElementObj.value = dc.range.wDays[dc.range.current.wDay].lng + ' ' + dc.range[dc.range.current.month].name + ' '
    + dc.range.current.mDay + ', ' + dc.range.current.year;
    // Then close the calendar
    dc.close();
    }, {
    // Configuration key / value map overrides
    });
    

    Parameters

    1. The first parameter must be unique for every calendar declaration, since this is registered as the ID of the Calendar AccDC Object when instantiated.

    2. The second parameter is the DOM object for the triggering element.

    3. The third parameter is the DOM object for the target INPUT element.

    4. The fourth parameter is a Boolean that determines whether comments will be displayed when associated with dates. False is set by default if no value is specified.

    5. The fifth parameter specifies a callback function where the returned date string can be customized.

    6. The sixth parameter is a key / value map where overrides can be declared to further customize functionality.

      Example:

      {
      
          // Configure optional overrides
      
          // If not included, all of the below values are set by default
      
          // Set role name text for screen reader users
          role: 'Calendar',
      
          // Set screen reader text to automatically be announced
          // This is also set within the data-helptext attribute in the top level div element of the calendar for CSS pseudo element referencing via attr(data-helptext) for sighted keyboard only users if desired.
          helpText: 'Press the arrow keys to navigate by day, PageUp and PageDown to navigate by month, Alt+PageUp and Alt+PageDown to navigate by year, or Escape to cancel.',
      
          // Set tooltip text
          tooltipTxt: 'Press Escape to cancel',
          disabledTxt: 'Disabled',
          markedTxt: 'Selected',
          commentedTxt: 'Has Comment',
          prevTxt: 'Previous',
          nextTxt: 'Next',
          monthTxt: 'Month',
          yearTxt: 'Year',
      
          // Set month names
          months: [
              'January',
              'February',
              'March',
              'April',
              'May',
              'June',
              'July',
              'August',
              'September',
              'October',
              'November',
              'December'
          ],
      
          // Set short and long weekday names
          days: [
              {
                  s: 'S',
                  l: 'Sunday'
              },
              {
                  s: 'M',
                  l: 'Monday'
              },
              {
                  s: 'T',
                  l: 'Tuesday'
              },
              {
                  s: 'W',
                  l: 'Wednesday'
              },
              {
                  s: 'T',
                  l: 'Thursday'
              },
              {
                  s: 'F',
                  l: 'Friday'
              },
              {
                  s: 'S',
                  l: 'Saturday'
              }
          ],
      
          // Switch the behaviour when the PageUp or PageDown keys are pressed to a "natural" behaviour
          // (PageUp goes to previous month, PageDown goes to next month)
          pageUpDownNatural: false,
      
          // Append a "dayToday" CSS class to the current day cell element - this allows styling to be targeted to this specific element
          highlightToday: true,
      
          // Fill in the day cells outside of the current month so that the calendar grid is always filled with day cells
          drawFullCalendar: true,
      
          // Run custom functions at the end of the code within the following component functions.
          // Receives a single parameter "dc", which provides access to the Datepicker object.
          runBefore: function (dc) {
              console.log('runBefore');
              console.log(dc);
          },
          runAfterClose: function (dc) {
              console.log('runAfterClose');
              console.log(dc);
          },
      
          // Override the character used on the month / year change buttons
          leftButtonYearText: '<',
          rightButtonYearText: '>',
          leftButtonMonthText: '<',
          rightButtonMonthText: '>',
      
          // Set specific start / end boundaries of a date range. Can be Date objects (absolute boundaries), or positive/negative integers (relative boundaries).
          // If undefined, no date range will be enforced.
          minDate: undefined,
          maxDate: undefined,
      
          // Using a token system, set a specific date string format to be used when setting the selected value into the calendar input box
          inputDateFormat: 'dddd MMMM D, YYYY',
      
          // Using a token system, set a specific date string format to be read out to screen reader users
          audibleDateFormat: 'D, MMMM YYYY (dddd)',
      
          // Allow a date that isn't today to be set as the initial date. If unset, this value is initialised to today's date
          initialDate: new Date(),
      
          // Disable weekdays from selection
          disableWeekdays: false,
      
          // Disable weekends from selection
          disableWeekends: false,
      
          // Set positive or negative offset for differing column arrangements, or 0 for none
          wdOffset: 0,
      
          // Set CSS positioning calculation for the calendar
          // Set to 0 to disable auto positioning
          autoPosition: 9,
      
          // Customize with positive or negative offsets
          offsetTop: 0,
          offsetLeft: 0,
      
          // Set class for the calendar container
          className: 'calendar',
      
          // Set custom CSS styling for the calendar container when rendered
          cssObj: {
              position: 'absolute',
              zIndex: 1
          },
      
          // Choose a different insertion point in the DOM; must be a DOM node; defaults to the triggering element if not specified.
          targetObj: null,
      
          // Choose a different focus element in the DOM for CSS autoPositioning; may be a DOM node or CSS Selector; defaults to the triggering element if not specified.
          posAnchor: '',
      
          // Reset date to the current calendar date every time the date picker opens
          resetCurrent: false,
      
          // Configure the Comments tooltip pane
          comments: {
              role: 'Comment',
              autoPosition: 1,
              offsetTop: 0,
              offsetLeft: 0,
              className: 'commentTooltip'
          },
      
          // Configure the editor form pane
          editor: {
              // Choose to show the form, defaults to false
              show: false,
              // Set the section name, and the Edit button text
              role: 'Edit',
              autoPosition: 6,
              offsetTop: 0,
              offsetLeft: 0,
              className: 'commentAdd',
              // Set the Save button text
              action1: 'Save'
          },
      
          // Condense the year display by removing the year nav buttons. Requires the Calendar Module version 1.25 or greater.
          condenseYear: false,
      
          // Manually configure the calendar using AJAX or a customization script
          ajax: function(dc, save){
              // 'save' is true when closing the Editor, false otherwise for fetching content when the calendar is opened.
      
              // If save is false, execute load script
      
              if (!save){
                  // Optionally load custom values into the dc.range associative array.
      
                  // And optionally prevent this script from running again
                  // dc.stopAjax = true;
      
                  // Then open the calendar after processing is finished
                  dc.open();
              }
      
              else{
                  // Otherwise do something with the newly saved values within the dc.range associative array.
              }
          }
      }
      

    Programmatic Control

    Every Date Picker is registered as an AccDC Object, the ID of which matches the ID string declared in the first parameter of the invocation statement.

    This also makes it possible to control the calendar programmatically using JavaScript, like so:

    var dc = $A.reg['UniqueCalendarId'];
    
    // Which you can then open
    
    dc.open();
    
    // Or close
    
    dc.close();
    
    // All other AccDC API properties and methods can be applied here as well.
    

    Triggering Element Requirements

    Regarding the triggering element, you should always use an active element for this purpose to ensure accessibility for both screen reader and keyboard only users.

    Within the Coding Arena samples, these are standard image links (A tags with an Href attribute and an embedded IMG tag with an informative Alt attribute). However, you can use whatever type of triggering element you wish, a standard link, button, or image link, with any type of styling. There must be an active element as a triggering element though, to ensure accessibility.

    Styling

    The sample calendars in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.

    You can change the styling however you wish to fit the layout of any UI, and the calendars will still be accessible to both screen reader and keyboard only users regardless.

    Simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled calendar will be accessible.

    Bootstrapping

    Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.

    The calendars within the Bootstrap folders are configured using HTML5 "data-" attributes within the HTML markup.

    When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class accCalendar, then configures the same module declaration as previously described using these HTML5 attributes.

    Available HTML5 attributes for the triggering element:

    • data-name : The name value for the calendar picker. The Name attribute of the accompanying text field must match the data-name attribute value. The selected date will then be inserted into the text field. (Must be on the triggering element.)

    Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".

    Required attributes:

    • name="whatever" : The Input field name attribute that matches the value of data-name. (Must be on the Input field with type="text")
    • class="accCalendar" : The bootstrap class name that specifies an accessible calendar picker. (Must be on the triggering element.)
    • id : The unique ID of the element. This value is also registered as the ID of the calendar AccDC Object, making it possible to invoke the object programmatically. (Must be on the triggering element.)

    Implementation Notes

    The date string format is configurable within the callback function, or within the "accdc_bootstrap.js" module if bootstrapped.

    The variables to reference are as follows:

    var weekDay = dc.range.wDays[dc.range.current.wDay].lng; // 'Friday'
    
    var monthName = dc.range[dc.range.current.month].name; // 'November'
    // or
    (dc.range.current.month+1) = numerical month string
    
    var monthDay = dc.range.current.mDay; // '30'
    
    var year = dc.range.current.year; // '2012'
    

    The returned values will reflect the date selected.

    The ARIA Listbox is a simple concept, turned into a powerful component.

    Expected behaviors: ARIA Listboxes should only receive one tab stop, the Up/Down/Home/End keys should move focus appropriately, and every listbox and listbox option should be explicitly labeled.

    The Listbox Module automates these processes by adding all related event handlers and managing all related rendering procedures.

    HTML Syntax

    <ul role="listbox" id="uniqueId1" >
    <li>
    <a href="#" role="option" id="uniqueId2" >
    <span class="lbl"> Option One Name </span>
    </a>
    </li>
    <li>
    <a href="#" role="option" id="uniqueId3" >
    <span class="lbl"> Option Two Name </span>
    </a>
    </li>
    <li>
    <a href="#" role="option" id="uniqueId4" >
    <span class="lbl"> Option Three Name </span>
    </a>
    </li>
    </ul>
    

    Required attributes:

    • role="listbox" : Specifies a Listbox group container for screen reader users. (Must be on the container element that surrounds the list items.)
    • role="option" : Specifies a Listbox Option node for screen reader users. (Must be on the keyboard focusable link elements that comprise the listbox option elements.)
    • ID : Specifies unique ID attribute values for both the listbox container element and all list option links.
    • Href : Included within every list option A tag, this ensures keyboard accessibility.

    The following attributes are handled automatically by the Listbox Module:

    • tabindex
    • aria-label
    • aria-owns
    • aria-setsize
    • aria-posinset
    • aria-selected
    • aria-checked (if applicable)
    • aria-grabbed (if applicable)
    • aria-dropeffect (if applicable)

    JavaScript

    var myListbox = new $A.Listbox( $A.getEl('uniqueId1'), {
    // Configuration key / value mappings
    });
    

    Parameters

    1. The first parameter is the DOM node for the listbox container element that includes role="listbox".

    2. The second parameter is the object literal used to configure listbox functionality using key / value map overrides.

      Example:

      {
      
      // Set the initial list option node to be selected
      defaultIndex: 0,
      
      // Set a label for screen reader users
      label: 'Unique field label text',
      
      // Choose whether the Listbox is single or multiselect (multiselect is ignored when isSortable=true)
      isMultiselect: false,
      
      // Choose whether the Listbox is sortable
      isSortable: false,
      
      // Choose whether the Delete key can be used to remove list option nodes
      allowDelete: false,
      
      // Help messages that are announced to screen reader users when isSortable=true
      grabInstruct: 'Press Space to grab',
      dropInstruct: 'Press Space to drop',
      grabMsg: 'Grabbed',
      dropMsg: 'Moved',
      cancelDrop: 'Grab canceled',
      
      // Do stuff whenever the selection changes
      callback: function(optionNode, optionsArray){
      // this.val() returns the current value of the Listbox control, a string if single-select or an array of strings if multiselect
      }
      
      }
      

    Programmatic Control

    Since the Listbox control is an instantiated object, all of the following public properties and methods are available:

    myListbox.container; // The Listbox DOM node for the element with role="listbox"
    
    myListbox.options; // The array of list option DOM nodes that contain role="option"
    
    myListbox.index; // The array index number for the currently selected list option element (relative to myListbox.options)
    
    myListbox.grabbed; // The ID string value of the currently grabbed list option DOM node (when isSortable=true)
    
    myListbox.val(); // Returns the current value of the Listbox control: An ID string when the listbox is single-select; an array of ID strings when the Listbox is a multiselect.
    
    myListbox.val(indexValue); // Sets the current Listbox selection to the specified array index value (relative to myListbox.options)
    
    myListbox.val('IdString'); // Sets the current Listbox selection to the specified list option DOM node that matches this ID (contained within myListbox.options)
    
    myListbox.val(['IdString1', 'IdString2']); // Sets the current Listbox selection to all of the list option DOM nodes that match the ID strings in the array (when isMultiselect=true and contained within myListbox.options)
    
    myListbox.val([]); // Clears all previously 'grabbed' or 'checked' list options if either isSortable or isMultiselect is set to True.
    
    myListbox.rem(indexValue); // Removes the list option DOM node from myListbox.options at the specified array index value, and returns the removed A tag DOM node.
    
    myListbox.rem('IdString'); // Removes the list option DOM node from myListbox.options by matching the ID, and returns the removed A tag DOM node.
    
    myListbox.rem(['IdString1', 'IdString2']); // Removes the array of list option DOM nodes from myListbox.options by matching the IDs, and returns the removed A tag DOM nodes in an array.
    
    myListbox.add(A-TagDOM-Node); // Adds a new list option to the Listbox. (Must be an A tag DOM node that includes a unique ID attribute value, an Href attribute for keyboard accessibility, and innerText to set the screen reader accessible label text)
    
    myListbox.add([A-TagDOM-Node1, A-TagDOM-Node2]); // Adds an array of new list options to the Listbox. (Must include A tag DOM nodes that include a unique ID attribute value, an Href attribute for keyboard accessibility, and innerText to set the screen reader accessible label text)
    
    myListbox.activate.apply(listOptionDOM-Node); // Programmatically activate the 'grab' or 'check' functionality for a specific list option DOM node (within myListbox.options when either isSortable or isMultiselect is set to True). The single parameter for this statement must consist of the A tag DOM node for the list option that you wish to activate. This simply performs a toggle action on the specified option, and does not specify a particular state.
    

    Styling

    The sample listboxes in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the listbox. This is also useful as a practice template for trying out different styling designs with custom content.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled listbox will be accessible.

    Implementation Notes

    All list option elements must be marked up as links (A tags with an Href attribute) to ensure backwards compatibility and graceful degradation. These are the only elements that will receive keyboard focus.

    All list option elements, as well as the listbox container, must include unique ID attribute values.

    In the case of the list option elements, the ID is used as the value of the Listbox control, so when an item is activated, the value of the Listbox will be returned as the ID value for the active A tag. For standard Listboxes, this is the ID of the currently selected list option as a string. E.G "uniqueId2" For Multiselect Listboxes, This is an array of the ID strings of the currently checked list options. E.G ["uniqueId2", "uniqueId4"]

    An innerText label for each A tag must be included to ensure accessibility for screen reader users, though you may position this text offscreen to hide it visually if desired.

    Alternatively, you may also include IMG tags within the A tags to form image links. When an IMG tag includes an informative Alt attribute, this text is also included as part of the list option label for screen reader users.

    If a background image is used instead however, then there must be an innerText label, even if positioned offscreen, to ensure accessibility for screen reader users.

    All list option label text must be unique, to prevent confusion for screen reader users.

    An ARIA Menu is a simple control type that can easily be made accessible.

    Expected behaviors: A keyboard accessible mechanism opens the menu, the arrow keys are used to browse available menu items or open and close submenus, pressing Tab will close all open menus, and pressing Escape will close the currently open menu.

    ARIA menus can be implemented in two ways, horizontally or vertically. This has nothing to do with what they look like, since the CSS styling can be set to whatever you like, but rather, refers to the keyboard interaction model for each menu.

    A vertical menu is navigated using the Up and Down arrow keys to scroll through menu items, and Left and Right are used to close or open submenus.

    A horizontal menu is navigated using the Left and Right arrow keys to scroll through menu items, and Up and Down are used to close or open submenus.

    You can optionally set different interaction models for specific menus or submenus depending on how the menu is visually presented, so that the behavior properly fits the UI design.

    Additionally, a menu may be triggered using either the left or right click, with accompanying behaviors for each.

    A left click menu often uses a link or button as the triggering element, and also supports the Down arrow, Space, and Enter keys to invoke the menu from the keyboard.

    For more complex controls, such as interactive ARIA Widgets that include their own functionality attached to the arrow keys and the left click handler, the right click menu may be used, which also supports the Shift+F10 and Application keystrokes for keyboard support.

    The right click menu may also be used on the Body element to present a customized page wide context menu that has no dedicated triggering element.

    The Menu Module automates these processes by adding all related event handlers and managing all related rendering procedures.

    HTML Syntax

    Basic menu structure with no submenus:

    <ol class="menu" id="uniqueId1">
    <li>
    <a href="#" class="link" id="uniqueId2">
    Menu Item One Name
    </a>
    </li>
    <li>
    <a href="#" class="link" id="uniqueId3">
    Menu Item Two Name
    </a>
    </li>
    <li>
    <a href="#" class="link" id="uniqueId4">
    Menu Item Three Name
    </a>
    </li>
    </ol>
    

    Basic menu structure with nested submenus:

    <ol class="menu" id="uniqueId1">
    <li>
    
    <a href="#" class="submenu" id="-uniqueId2">
    Subfolder Menu Item One Name (Level 1)
    </a>
    
    <ol class="menu" id="uniqueId1-uniqueId2">
    <li>
    
    <a href="#" class="submenu" id="-uniqueId2-1">
    Subfolder Submenu Item One Name (Level 2)
    </a>
    
    <ol class="menu" id="uniqueId1-uniqueId2-uniqueId2-1">
    <li>
    
    <a href="#" class="link" id="uniqueId2-1-1">
    Submenu Item One Name (Level 3)
    </a>
    
    </li>
    </ol>
    
    </li>
    <li>
    
    <a href="#" class="link" id="uniqueId2-2">
    Submenu Item Two Name (Level 2)
    </a>
    
    </li>
    </ol>
    
    </li>
    <li>
    
    <a href="#" class="link" id="uniqueId3">
    Menu Item Two Name (Level 1)
    </a>
    
    </li>
    </ol>
    

    The HTML menu syntax is flexible, and may consist of UL tags, OL tags, DIV tags, or any other combination, as long as the container element includes a unique ID, as well as each menu item tag.

    For simplicity, these have been marked up as list elements, which is generally preferable since it includes native screen reader support for nested lists. Also, the use of standard A tags with an Href attribute ensures keyboard accessibility across all Assistive Technologies for graceful degradation.

    You may also use additional HTML markup within the menu item links for formatting purposes (such as SPAN tags), as long as you don't add additional active elements such as clickable images. The only actionable element should be the menu item link, and nothing else.

    Submenus are mapped by combining the ID attribute value of the container element, with the ID attribute value of the submenu link. The two combined point to the full ID attribute value of the associated submenu container element.

    For example, notice the ID value on the top level menu OL tag above is id="uniqueId1", and the ID of the first Subfolder A tag within that structure is id="-uniqueId2".

    When you combine the two ("uniqueId1-uniqueId2"), notice that this directly points to the submenu OL tag as its ID attribute value.

    You can experiment with this in the Coding Arena "Shell" folders, where the same code is used.

    Important: Don't add any ARIA attributes to the markup, and don't add tabindex attributes. All of these are handled automatically when the menus are rendered.

    If the menu constructs are contained within the same page, they must be contained within a container element that has an ID attribute. This is used by the setup function to confine the parsing query to this node only.

    Example:

    <div id="hiddenDivId" class="hidden">
    
    <ol class="menu" id="uniqueId1">
    ...
    </ol>
    
    </div>
    

    The following attributes are handled automatically by the Menu Module:

    • role="menubar" (horizontal)
    • role="menu" (vertical)
    • aria-owns
    • tabindex
    • role="menuitem"
    • aria-posinset
    • aria-setsize
    • aria-haspopup

    HTML5 attributes that can optionally be added to the menu list container markup:

    • data-horizontal="true"/"false" : Sets or unsets a horizontal flyout menu where the Left and Right arrow keys will be used to navigate menu item nodes, and Up and Down will be used to close or open submenus. This temporarily overrides the interaction model set within the JavaScript declaration statement.
    • data-offsetleft="number" : Specifies a positive or negative offsetLeft value that will be applied to the menu after it is rendered.
    • data-offsettop="number" : Specifies a positive or negative offsetTop value that will be applied to the menu after it is rendered.
    • data-autoposition="number between 0 and 12" : Specifies a custom autoPosition value that will control where the menu is visually positioned relative to the triggering element.

      Value Definitions:

      • 0: Disabled
      • 1: Above/Center/Left Edge Aligned
      • 2: Above/Right/Right Edge Aligned
      • 3: Level/Right/Right Edge Aligned
      • 4: Below/Right/Right Edge Aligned
      • 5: Below/Center/Left Edge Aligned
      • 6: Below/Left/Left Edge Aligned
      • 7: Level/Left/Left Edge Aligned
      • 8: Above/Left/Left Edge Aligned
      • 9: Level/Center/Left Edge Aligned
      • 10: Above/Center/Right Edge Aligned
      • 11: Level/Center/Right Edge Aligned
      • 12: Below/Center/Right Edge Aligned

    Example:

    <ol class="menu" id="uniqueId1-uniqueId2-uniqueId2-1" data-horizontal="true" data-offsetleft="10" data-offsettop="-20" data-autoposition="3">
    ...
    </ol>
    

    JavaScript

    $A.setMenu( 'CSS-SelectorForTriggeringElement' , 'LocalePathOrContainerID' , 'TopLevelMenuID' ,
    callbackFunction(ev, dc){
    // Do something every time a menu item link node is clicked
    } , areMenusInTheSameDoc? , contextDOM-Node , {
    // Configure key / value mapping overrides
    });
    

    Parameters

    1. Parameter 1: The triggering element CSS Selector
      This points to the triggering element link or button that you want to use as the menu triggering element. For instance, the CSS Selector "a.button" points to the A tag with class="button" for this purpose. Multiple triggering elements that open the same menu may be specified using one CSS Selector.

    2. Parameter 2: The Locale Path or Container ID
      When menus are contained within an external HTML file, this string value is the relative file path, such as "files/menus.html".
      When menus are contained within the same page, this string value is the ID attribute of the container element where all of the menu tags are located, such as "hiddenDivId".

    3. Parameter 3: Top Level Menu ID
      This string is the top level menu ID attribute value, such as "uniqueId1", which is used to specify which menu will be opened first when the triggering element is activated.

    4. Parameter 4: The Callback Function
      This is where you can set specific functionality to occur whenever a menu item link is activated, whether this is to navigate to another page, or to perform another client side action.
      When declared, two arguments are passed to the function, first is the event object, and the second is the AccDC Object for the currently open menu object.
      Using this within the function will reference the DOM node for the activated element, which is useful if mapping the ID attribute to a particular action. dc.top.triggerObj (where dc is the AccDC Object) provides the DOM node for the original triggering element that first opened the menu.

    5. Parameter 5: Are Menus within the Same Doc
      A Boolean (true or false), that specifies whether the script should process the Locale parameter as an internal or external resource locator.
      If menu markup is contained within an external HTML file, set this to false, otherwise set to true.

    6. Parameter 6: The Context DOM Node
      This is the DOM node that will be used to confine the parsing query.
      Typically this is set to document, since all of the IDs are relative to this location.
      However, this parameter gives you the ability to reference iFrame documents instead if desired.

    7. Parameter 7: The Config Object
      This is a key / value mapping of overrides that can be used to customize the element types of menu container and menu item elements, the class names for each, the default keyboard interaction model, the default auto positioning if desired, plus additional AccDC API overrides if desired.

      Example:

      {
      
      // Enable right click functionality
      // Automatically configures keyboard support using Shift+F10 and the Applications key
      // When set to false, the Enter, Space, and Down arrow keys are supported in addition to onclick
      rightClick: true, // Default: false
      
      // Set the accessible help description that will be announced for screen reader users
      // Only applicable when rightClick is set to true
      // Will automatically clear on touch screen devices to prevent confusion
      rightClickText: 'Press Shift+F10 or the Applications key to open the popup menu',
      
      // Set the main container class, (which will surround the menu as a Div tag when rendered)
      containerClass: 'menu',
      
      // Specify the menu tag name in the markup
      menuTag: 'ol',
      // Specify the menu class name on the above tag in the markup
      menuClass: 'menu',
      
      // Specify the active element that will be used as each menu node
      // Important, if nesting A tags within LIs, only the A tag should be used for this purpose
      // Active elements should never be nested.
      // The following tag will receive keyboard focus within the menu structure when using the arrow keys to navigate
      // Event bindings are also tied to this tag
      itemTag: 'a',
      
      // Specify the class name that indicates when a menu item opens a submenu
      folderClass: 'submenu',
      // Specify the class name that indicates when a menu item is to be triggered directly
      // This should not be the same as the folderClass declaration
      linkClass: 'link',
      
      // Specify if the menu is a flyout menu
      // If true, the Left and Right arrow keys will scroll the open menu
      // If false, the Up and Down arrow keys will scroll the open menu instead
      horizontal: false,
      
      // Set a default autoPosition value between 0 (disabled) and 12
      autoPosition: 0,
      
      // Set custom offset values to adjust the positioning calculation
      // May return a positive or negative number
      offsetLeft: function(dc){
      return 0;
      },
      offsetTop: function(dc){
      return 0;
      },
      
      overrides: {
      // Additional AccDC API properties and methods can be applied here if desired.
      }
      
      }
      

    Programmatic Control

    Every menu instance is registered as an AccDC Object, the ID of which matches the ID attribute value on the menu container element.

    This means that you can programmatically control each menu using JavaScript if desired, like so:

    // Get a reference to the top level Menu AccDC Object for the menu container with id="uniqueId"
    var dc = $A.reg['uniqueId'];
    
    // Now invoke the object
    dc.open();
    
    // Or close it
    dc.close();
    
    // All other AccDC API properties and methods can be applied here as well.
    

    Additionally, when a menu is attached to a triggering element, the custom handler popupmenu is attached to that element.

    To support both standard and touch device usage as part of responsive design, a specially displayed icon (typically referred to as a Hamburger icon) is often displayed conditionally on touch screen devices to allow for context menus to be actionable [ Reference ]

    Such an icon can be programmatically configured to open the popup menu attached to the triggering element by manually triggering the popupmenu event on that element.

    // Detect if running on a touch device
    if ('ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0){
    
    // Unhide the hamburger icon and attach an onclick handler
    $A.bind($A.remClass(hamburgerIconElement, 'hidden'), 'click', function(ev){
    
    // Trigger the menu attached to the original triggering element
    $A.trigger(originalTriggeringElement, 'popupmenu');
    
    ev.stopPropagation(); // Important to prevent bubbling and auto closing
    ev.preventDefault();
    });
    
    }
    

    Similarly, a currently open menu can be programmatically closed by triggering the closepopupmenu event on the triggering element.

    // Close the menu attached to the original triggering element
    $A.trigger(originalTriggeringElement, 'closepopupmenu');
    

    When aria-disabled="true" is programmatically set on any menu item node after rendering, it will automatically be disabled within the menu, so that disabled submenus will not open when clicked or arrowed to, and custom handling for non-submenu links can then be processed individually within the click callback.

    Triggering Element Requirements

    When a custom menu is applied to the Body element, no triggering element is required.

    All other usages for custom popup menus require the use of a keyboard focusable active element that includes a valid active element role, which may consist of any native active element such as a standard link or form field, or a keyboard accessible interactive ARIA Widget type.

    Valid interactive ARIA Widget roles include:

    • button
    • checkbox
    • columnheader
    • combobox
    • grid
    • gridcell
    • link
    • listbox
    • option
    • radio
    • rowheader
    • slider
    • spinbutton
    • tab
    • textbox
    • tree
    • treegrid
    • treeitem

    [ Reference ]

    Styling

    The sample menus in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the menu. This is also useful as a practice template for trying out different styling designs with custom content.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled menu will be accessible.

    Bootstrapping

    Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.

    The menus within the Bootstrap folders are configured using HTML5 "data-" attributes within the HTML markup.

    When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class "accMenu", then configures the same module declaration as previously described using these HTML5 attributes.

    Available HTML5 attributes for the triggering element:

    • data-src : The resource path and pointer to the ID attribute of the top level menu list. If pointing to a menu list within the same document, only the ID attribute should be included here.
    • data-internal : The ID attribute of the container element for all menu lists within the same document. If data-src is set to an external source, data-internal should be blank or not included.
    • data-containerclass : The class name that will be added dynamically to the surrounding Div tag for each menu group when rendered. "menu" is set by default if no value is specified.
    • data-menutag : The tag name for the container element that contains all menu item tags. All menu item tags must be contained within this container element, even if they are not first level child nodes. "ol" is set by default if no value is specified.
    • data-menuclass : The shared class name that is contained within every menu container element. All menu tags specified by data-menutag must include this class name. "menu" is set by default if no value is specified.
    • data-menuitemtag : The shared tag name that specifies all menu item tags. All menu item tags must be contained within the container element specified by data-menutag, even if they are not first level child nodes. "a" is set by default if no value is specified.
    • data-menufolderclass : The shared class name that is contained within every menu tag that opens a submenu. "submenu" is set by default if no value is specified.
    • data-menulinkclass : The shared class name that is contained within every menu tag that does not open a submenu. "link" is set by default if no value is specified.
    • data-flyout="true" : Specifies a horizontal flyout menu where the Left and Right arrow keys will be used to navigate menu item nodes, and Up and Down will be used to close or open submenus. If data-flyout is not included within the markup, the default vertically oriented keyboard assignments will be applied automatically.

    Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".

    Required attributes for the triggering element:

    • class="accMenu" : The bootstrap class name that specifies an accessible menu triggering element.

    Implementation Notes

    The lists can be set to any tag, such as OL, UL, etc, as long as this is specified in the menuTag property within the JavaScript declaration statement or within the data-menutag attribute on the triggering element if Bootstrapped.

    The same is true for the menu item nodes, which is specified using the menuItemTag property in the JavaScript declaration statement, or within the data-menuitemtag attribute on the triggering element if Bootstrapped.

    Menus and submenus may be nested or broken out into separate lists within the markup if desired, as long as they are all contained within the same top level container element specified by ID within the JavaScript invocation statement, or within the data-internal attribute on the triggering element if Bootstrapped.

    All menu container elements and menu item nodes must include unique ID attributes.

    Submenus are mapped by combining the ID attribute of the top level menu container ID and the submenu pointer link ID, which, when combined, points to the ID of the referenced submenu container.

    All menu item nodes must include innerText to ensure accessibility for screen reader users.

    Don't include any ARIA attributes within the menu markup, since this is handled automatically by the Menu module.

    ARIA Radio buttons provide a means for rendering standard links as a radio button group.

    Expected behaviors: Only one radio button should receive focus in the tab order, regardless whether one or no radio button in the group is selected. If a radio button is selected, only the currently selected radio button should appear in the tab order. The arrow keys should move focus to the next or previous radio button in the group, and the act of moving to that radio button should automatically select it.

    The Radio Button Module automates these processes by adding all related event handlers and managing keyboard focus appropriately.

    HTML Syntax

    <ul id="radiogroupId" role="radiogroup">
    <li>
    <a href="#" role="radio" class="accRadio" id="rOpt1" aria-labelledby="rOpt1Lbl">
    <span id="rOpt1Lbl"> Radio One Label Text </span>
    </a>
    </li>
    <li>
    <a href="#" role="radio" class="accRadio" id="rOpt2" aria-labelledby="rOpt2Lbl">
    <span id="rOpt2Lbl"> Radio Two Label Text </span>
    </a>
    </li>
    <li>
    <a href="#" role="radio" class="accRadio" id="rOpt3" aria-labelledby="rOpt3Lbl">
    <span id="rOpt3Lbl"> Radio Three Label Text </span>
    </a>
    </li>
    </ul>
    
    Markup requirements
    • The Radio container element must include the attribute role="radiogroup".
    • All radio option nodes must include the attribute role="radio".
    • Both the Radio container element and all radio option nodes must include unique ID values. The current value for a Radio Control is the ID attribute of the currently selected radio button.
    • The innerHTML for each radio option node must contain a textual label, which may be positioned offscreen to hide it visually if desired.
      This textual label is critical so that screen reader users will be able to identify the purpose of the radio button.
      If the textual label is included within another tag (such as a Span tag) for formatting purposes, aria-labelledby must be used to explicitly associate the label text with the element that includes role="radio" by referencing its ID.
      Additionally, the textual label must be included within the opening and closing tags of the element with role="radio".
    • If using an A tag, an href attribute is required to ensure keyboard accessibility.
    • Images may also be used within radio option nodes if desired.
      If an image is present however, it should include the attribute alt="" to hide it from screen reader users.
      An image with a textual Alt value won't be reliably announced as the radio button label in all browsers, which is why alt="" is used to hide it from screen reader users.
      A textual label must be used instead to ensure the highest level of accessibility for the highest percentage of people.
      To add a tooltip for sighted mouse users, use the Title attribute on the IMG tag instead.
      The value within the Title attribute must match the text contained within the textual label however, especially when the textual label is positioned off screen to hide it visually. (This will ensure equal accessibility for all user types)

    The following attributes are handled automatically by the Radio Button Module:

    • tabindex
    • aria-owns
    • aria-setsize
    • aria-posinset
    • aria-selected
    • aria-checked

    JavaScript

    var myRadioGroup = new $A.RadioGroup( 'radiogroupId' , 'CSS Selector for All Radio Elements' , DefaultIndexValue , 'Optional Legend Text' ,
    callbackFunction(selectedRadioNode, radiosArray){
    // Do something whenever a radio is selected
    // this.value is the ID value of the newly selected radio element
    } );
    

    Parameters

    1. Parameter 1: The ID attribute of the radio group container. (This is the element with role="radiogroup")

    2. Parameter 2: The CSS Selector that identifies all elements with role="option" (all of which must be contained within the container specified in parameter 1)

    3. Parameter 3: The array index of the radio button that you want to be selected by default when instantiated.
      (Simply pass -1 to specify that no radio button should be selected by default)

    4. Parameter 4: The shared legend text that will be announced to screen reader users whenever a radio button group receives initial focus.
      The legend text will be announced in addition to the textual label for the radio button.
      To use a visually displayed legend instead (as demonstrated within the Coding Arena samples), use aria-labelledby on the element with role="radiogroup", and pass "" to this parameter to skip it.

    5. Parameter 5: The callback function that will be executed whenever a new radio button is activated.

    Programmatic Control

    When a radio button grouping is instantiated as a new Radio Group Control, all of the following public properties and methods are available:
    ('myRadiogroup' refers to the variable instance name)

    myRadiogroup.radios; // The array of all radio option DOM nodes
    
    myRadiogroup.index; // The array index of the currently selected radio option
    
    myRadiogroup.value; // The string ID attribute value of the currently selected radio option
    
    myRadiogroup.set('radioId'); // Sets the radio option with id="radioId"
    
    myRadiogroup.set(arrayIndex); // Sets the radio option at the specified array index (relative to myRadiogroup.radios)
    

    Styling

    The sample radios in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the radio group. This is also useful as a practice template for trying out different styling designs with custom content.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled radio group will be accessible.

    ARIA Sliders are used to present adjustable values for users, and can easily be made accessible.

    Expected behaviors: The slider should have only one tab stop in the tab order, the arrow keys should move the slider in single value increments, PageUp/PageDown should move the slider in 10% increments, Home/End should move the slider to the beginning or end, and the slider should be draggable using the mouse as usual.

    The Slider Module automates these processes by adding all related event handlers and managing keyboard focus appropriately.

    HTML Syntax

    <div class="slider">
    
    <div class="min" aria-hidden="true">
    <span>0%</span>
    </div>
    
    <div class="slideWrapper">
    
    <div class="slide clearfix">
    
    <div class="nub" id="handleId"><!--
    This is the slider thumb icon
    --></div>
    
    </div>
    
    </div>
    
    <div class="max" aria-hidden="true">
    <span>100%</span>
    </div>
    
    </div>
    

    Important: The first parentNode container of the draggable slide element must be relatively positioned to set this as the offsetParent. In the above markup, this is the Div tag with class="slide clearfix".

    Also, notice that aria-hidden="true" is used on the Min and Max container tags. Since these values will be provided to screen reader users as part of the ARIA Slider Control, having them announced during navigation would only repeat the same information twice, which is unnecessary. So aria-hidden is used to remove them from the Virtual Buffer for screen reader users.

    The next step is to use CSS to set the width and height of the slider, which you can see examples of in the Coding Arena samples. This is important, because when the Slider Control is instantiated, it will use these offsets to configure the positioning calculations and map them to related keyboard commands.

    The following attributes are handled automatically by the Slider Module:

    • tabindex
    • aria-label
    • role="slider"
    • aria-valuemin
    • aria-valuemax
    • aria-valuenow
    • aria-valuetext
    • aria-orientation

    JavaScript

    $A.setSlider('handleId', {
    // Configure key / value mappings
    });
    

    Parameters

    1. The first parameter is the ID of the element that will be made draggable, which will then be morphed into an AccDC Object. E.G "handleId" The markup structure will slightly change at this point, since an extra DIV will then surround the element with id="handleId".

    2. The second parameter is where all of the slider configuration is set.

      Example:

      {
      
      // Set the role text that is conveyed to screen reader users
      role: 'Slider',
      
      // Set a minimum value
      min: 0,
      
      // Set a maximum value
      max: 100,
      
      // Set the start value
      now: 50,
      
      // Is a vertical slider?
      vertical: false,
      
      // Set the hidden link text for graceful degradation
      // This should reflect the purpose of the slider
      degradeLbl: 'Manually choose a percentage',
      
      // Return the string that will act as the ARIA Slider label for screen reader users
      // This should reflect the purpose of the slider
      ariaLabel: function(dc){
      return 'Choose a percentage between 0 and 100';
      },
      
      // Return the string that will act as the textual notification for screen reader users
      // This is automatically announced every time the slider is moved
      valueText: function(dc, val){
      return val + '%';
      },
      
      // Set the action to occur whenever the value changes
      onDrag: function(ev, dd, dc, val){
      // ev is the standard event object
      // dd is the custom drag event object
      // dc is the AccDC Object for the Slider
      // val is the current value of the slider
      },
      
      // Set the class name for the surrounding Div, which automatically surrounds the drag handle element
      className: 'handleWrapper'
      
      }
      

    Programmatic Control

    After a Slider Control is instantiated, it can be controlled programmatically using its ID, which matches the ID attribute value of the drag handle (passed as the first parameter in the invocation statement).

    Example:

    // Get a reference to the Slider AccDC Object using its ID, which matches the handle elements ID attribute
    var dc = $A.reg['handleId'];
    
    // Get the current slider value
    var currentVal = dc.config.now;
    
    // Assign a new slider value
    dc.config.now = currentVal + 10;
    
    // Apply the change
    dc.set.apply(dc);
    

    Styling

    The sample sliders in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled sliders will be accessible.

    Implementation Notes

    Simply use CSS to set the size of the slider, and the height and width of the container element, and then the slider will configure itself using these offsets.

    Since repetitive labels are used, and the textual slider icon has no value for screen reader users, aria-hidden="true" is used to hide them from screen reader users.

    Don't include any other ARIA attributes however, the Slider module handles this automatically.

    The slide icon can be changed to anything, or an image or CSS background image can be used instead, and the styling can be configured for any layout, and it will still be accessible for screen reader and keyboard only users.

    VoiceOver instructions for use on iOS touch screen devices:

    When VoiceOver is used on iOS touch screen devices, VoiceOver instructs the user to swipe up and down with one finger to adjust the slider value, which is incorrect. (Last verified on 04/07/2013)

    Instead, do the following:

    1. Use one finger and double tap the slide icon, and keep your finger pressed down on the second tap.
    2. Wait until you hear a slight noise, then slide your finger in the direction that you wish to move the slider.
    3. Then lift your finger to release the slider.

    Credit goes to David Hilbert Poehlman for providing VoiceOver pass-through technique instructions.

    The Toggle Control is a multipurpose control type, that covers checkboxes, toggle buttons, switches, and even simulated links and buttons.

    Expected behaviors: The general behavior of a Toggle control is to receive keyboard focus in the tab order regardless of the active select state, to be toggleable or actionable by pressing the Spacebar or by pressing Enter on the control, and to be toggleable or actionable by clicking it as usual.

    The Toggle Module automates these processes by adding all related event handlers.

    HTML Syntax

    The HTML syntax varies depending on which type of implementation is desired, and each type has specific rules that must be observed in order to ensure the highest level of accessibility for screen reader users.

    IMG

    For IMG tags, the following attributes are required to ensure accessibility for the widest range of screen readers:

    1. aria-label : Specifies a textual label for screen reader users. (The Alt alone won't work for this purpose)
    2. alt="" : Hides the image from screen reader users when no tooltip is desired for mouse users.
      To add a tooltip for sighted mouse users, use both the Alt and Title attributes. The text for both must match the text contained within the aria-label attribute, so that all three are the same. This will also maximize accessibility in iOS devices using VoiceOver.
    3. role="button" must be added for toggles, role="checkbox" must be added for checkboxes, or role="switch" must be added for switches.
    4. A unique ID must be added for proper event binding.

    Examples:

    <img role="button"
    aria-label="Toggle Button Label"
    alt="Toggle Button Label"
    title="Toggle Button Label"
    id="uniqueId1"
    src="icon.png"
    />
    
    <img role="checkbox"
    aria-label="Checkbox Label"
    alt="Checkbox Label"
    title="Checkbox Label"
    id="uniqueId2"
    src="icon.png"
    />
    
    <img role="switch"
    aria-label="Switch Label"
    alt="Switch Label"
    title="Switch Label"
    id="uniqueId2"
    src="icon.png"
    />
    
    INPUT

    For INPUT tags with type="image", the following attributes are required to ensure accessibility for the widest range of screen readers:

    1. aria-label : Specifies a textual label for screen reader users. (The Alt alone won't work for this purpose)
    2. Title : Specifies a textual label for screen reader users. This must match the text contained within the aria-label attribute.
      (Both the Title and aria-label attributes are required to correct differing screen reader feedback when tabbing versus arrowing down the page using JAWS.)
    3. To add a tooltip for sighted mouse users, use both the Alt and Title attributes. The text for both must match the text contained within the aria-label attribute, so that all three are the same.
    4. role="button" must be added for toggles, role="checkbox" must be added for checkboxes, or role="switch" must be added for switches.
    5. A unique ID must be added for proper event binding.

    Examples:

    <input type="image"
    role="button"
    aria-label="Toggle Button Label"
    alt="Toggle Button Label"
    title="Toggle Button Label"
    id="uniqueId3"
    src="icon.png"
    />
    
    <input type="image"
    role="checkbox"
    aria-label="Checkbox Label"
    alt="Checkbox Label"
    title="Checkbox Label"
    id="uniqueId4"
    src="icon.png"
    />
    
    <input type="image"
    role="switch"
    aria-label="Switch Label"
    alt="Switch Label"
    title="Switch Label"
    id="uniqueId4"
    src="icon.png"
    />
    
    Container Elements

    For all other container elements that support innerHTML such as DIVs and SPANs, the following attributes and rules are required to ensure accessibility for the widest range of screen readers:

    1. Inner Text : Specifies a textual label for screen reader users. This may be visible or positioned using offscreenText.
    2. No Embedded Active Elements : Don't embed any other active elements, including mouse clickable images, links, or anything else that needs to be activated separately. (The only actionable element should be the element with role="button" or role="checkbox".)
    3. To add a tooltip for sighted mouse users, use the Title attribute. This must match the text contained within the innerText label.
    4. role="button" must be added for toggles, role="checkbox" must be added for checkboxes, or role="switch" must be added for switches.
    5. A unique ID must be added for proper event binding.

    Examples:

    <div role="button"
    title="Toggle Button Label"
    id="uniqueId5">
    <span class="lbl">
    Toggle Button Label
    </span>
    </div>
    
    <div role="checkbox"
    title="Checkbox Label"
    id="uniqueId6">
    <span class="lbl">
    Checkbox Label
    </span>
    </div>
    
    <div role="switch"
    title="Switch Label"
    aria-label="Switch Label"
    id="uniqueId6"></div>
    

    (The element with the valid role will automatically be made focusable.)

    The following attributes are handled automatically by the Toggle Module:

    • tabindex
    • aria-checked (if applicable)
    • aria-pressed (if applicable)

    JavaScript

    var myToggle = new $A.Toggle('uniqueId', {
    // Configure key / value mappings
    });
    

    Parameters

    1. The first parameter is the ID attribute value of the element that will become actionable.
    2. The second parameter is the key / value map that configures specific functionality.

    Example:

    {
    
    // Disable ARIA
    // (only for simulated Checkboxes and Toggle Buttons, leave out otherwise)
    noARIA: true,
    
    // Disable toggling
    // (only for ARIA Links and Buttons, leave out otherwise)
    noToggle: true,
    
    // Set the initial state
    // (only for simulated Checkboxes and Toggle Buttons, leave out otherwise)
    state: false,
    
    // Declare a callback to run every time the state changes
    callback: function(state){
    // 'state' is the proposed state change, true or false
    // 'this' is the triggering element
    // Return true to accept the ARIA state change, or false to prevent
    return true;
    }
    
    }
    

    Programmatic Control

    After a Toggle control is instantiated, the following public properties and methods are available:

    myToggle.state; // Reflects the current select state of the toggle (true or false)
    
    myToggle.set(Boolean); // Set the Toggle with the specified state (true or false)
    

    Styling

    The samples in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled checkbox, button, or switch will be accessible.

    An ARIA Tree is a complex control type that requires a lot of synchronizing to make accessible.

    The reasons why: If the right ARIA attributes are not applied to the correct DOM nodes that receive keyboard focus, and if the parent child ID associations are not properly mapped and maintained, and if tree nodes are not labeled properly using the correct ARIA attributes, and if the tree contains any other active elements that are not part of the ARIA Tree structure, then the ARIA Tree and its contents will not be accessible for screen reader users.

    Currently, a large part of this is the result of unequal support by screen reader manufacturers. For example, even though the ARIA specification states that role="document" can be used to embed additional content panels within specific widgets such as this, doing so will result in content panels that are inaccessible using JAWS in both IE and Firefox. (Verified in JAWS 12, 13, and 14)

    Nevertheless, the Tree Module automates these processes accessibly by adding all related event handlers and managing all related rendering procedures using an external XML file for configuration.

    HTML Syntax

    <div id="myTreeId"></div>
    

    XML Syntax

    <?xml version="1.0" encoding="UTF-8" ?>
    <tree>
    <branch id="uniqueId0-1" name="Branch Link Name for id=uniqueId0-1">
    <leaf id="uniqueId0-1-1" name="Leaf Link Name for id=uniqueId0-1-1"></leaf>
    </branch>
    <leaf id="uniqueId0-2" name="Leaf Link Name for id=uniqueId0-2"></leaf>
    </tree>
    

    The above XML markup results in the following HTML structure when rendered:

    <div class="TreeView">
    <div>
    <ul role="tree" aria-owns="uniqueId0-1 uniqueId0-2" aria-label="Informative Field Name">
    <li>
    <a class="branch" aria-expanded="true" id="uniqueId0-1" aria-level="1" role="treeitem" aria-posinset="1" tabIndex="0" aria-selected="true" aria-owns="aria1363672754457" aria-setsize="2" href="#" aria-label="Branch Link Name for id=uniqueId0-1">
    <SPAN>Branch Link Name for id=uniqueId0-1</SPAN>
    </a>
    <div class="TreeView">
    <div>
    <ul id="aria1363672754457" role="group" aria-owns="uniqueId0-1-1">
    <li>
    <a class="leaf" id="uniqueId0-1-1" aria-level="2" role="treeitem" aria-posinset="1" tabIndex="-1" aria-selected="false" aria-setsize="1" href="#" aria-label="Leaf Link Name for id=uniqueId0-1-1">
    <SPAN>Leaf Link Name for id=uniqueId0-1-1</SPAN>
    </a>
    </li>
    </ul>
    </div>
    </div>
    </li>
    <li>
    <a class="leaf" id="uniqueId0-2" aria-level="1" role="treeitem" aria-posinset="2" tabIndex="-1" aria-selected="false" aria-setsize="2" href="#" aria-label="Leaf Link Name for id=uniqueId0-2">
    <SPAN>Leaf Link Name for id=uniqueId0-2</SPAN>
    </a>
    </li>
    </ul>
    </div>
    </div>
    
    Required XML attributes
    • id : The unique ID of the node. This will automatically be converted into the ID attribute of the relevant tree item link when rendered. (All IDs must be unique)
    • name : The textual name of the node, which will automatically be converted into the textual label for the tree item link when rendered.
      (All name attribute values at the same logical node level must be unique to ensure accessibility for screen reader users)

    The following attributes are handled automatically by the ARIA Tree Module:

    • aria-label
    • role="tree"
    • role="group"
    • aria-owns
    • tabindex
    • role="treeitem"
    • aria-setsize
    • aria-posinset
    • aria-selected
    • aria-expanded

    JavaScript

    var treeId = $A.setTree({
    // Configuration key / value map
    });
    

    Parameters

    1. The first parameter is used to configure ARIA Tree functionality using a key / value map.

      Example:

      {
      
      // Set the XML file to parse
      path: 'files/tree.xml',
      
      // Set the label that will be announced to screen reader users
      title: 'Informative Field Name',
      
      // Specify the container element where the tree nodes will be inserted
      container: 'div#myTree',
      
      // Set the class name shared by all tree AccDC Objects when rendered
      topClass: 'TreeView',
      
      // Set the container tree node type
      treeTag: 'ul',
      
      // Set the divider node type that will be appended to the treeTag node
      dividerTag: 'li',
      
      // Set the focusable tree item node type that will be inserted within dividerTag node
      treeItemTag: 'a',
      
      // Set the shared class name for all tree items that expand into subfolders
      treeClass: 'branch',
      
      // Set the shared class name for all tree items that do not expand into subfolders
      treeItemClass: 'leaf',
      
      // Set the class name that is only set on the tree item node that has focus
      selectClass: 'selected',
      
      // Set the handler type that will trigger the callback
      bind: 'click',
      
      // Declare a callback function
      callback: function(ev, dc){
      
      // Get the XML node that matches the ID attribute of the currently triggered element
      var xmlNode = $A.query('#' + this.id, dc.top.xmlDocument)[0];
      
      // To learn more about the XML DOM and supported properties and methods,
      // and how to access custom attributes on each node, visit
      // http://www.w3schools.com/dom/default.asp
      
      },
      
      overrides: {
      // Set optional AccDC API overrides for every AccDC Object that is rendered in the tree
      }
      
      }
      

    Programmatic Control

    The invocation statement returns the top level ID of the newly instantiated ARIA Tree control, which is now registered as an AccDC Object.

    You can use this ID to programmatically change or invoke AccDC API properties and methods within the ARIA Tree structure, and to traverse the parent / child relationship of tree node objects.

    Example:

    // Get the Tree AccDC Object using the ID stored in the variable treeId
    var dc = $A.reg[treeId];
    

    Now, you can traverse the expandable branches in the tree using dc.siblings, dc.children, dc.parent, and dc.top, and apply changes, store and retrieve data, or invoke AccDC API commands as desired.

    Example:

    // Close the Tree AccDC Object and remove it from the DOM.
    dc.top.close();
    
    // All other AccDC API properties and methods are similarly available.
    

    Styling

    The sample trees in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the tree. This is also useful as a practice template for trying out different styling designs with custom content.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled tree will be accessible.

    A Banner is a simple control type, which can easily be made accessible.

    Expected behaviors: Ensure that the content of the banner appears at the top of the page, ensure that the beginning and ending boundaries are conveyed to screen reader users, and make sure the banner can be closed from the keyboard (if applicable).

    The Banner Module automates these processes by instantiating banner content as an AccDC Object.

    HTML Syntax

    <div id="bannerContainerElementId">
    Banner content goes here.
    </div>
    

    JavaScript

    var bannerId = $A.setBanner({
    // Configure functionality key / value map
    });
    

    Parameters

    1. The first parameter configures banner functionality using a key / value map.

      Example:

      {
      
      // Set a unique ID for the Banner AccDC Object
      id: 'myBannerId',
      
      // Set the boundary text for screen reader users
      role: 'Banner',
      
      // Set the Banner AccDC Object to render literal content
      // (Only if pulling content from within the same page, remove otherwise)
      mode: 0,
      
      // Set the content to be rendered by pulling it from within the same page
      // 'removeChild' is important here, so no duplicate ID conflicts can occur when the object is opened and closed
      // (Only if pulling content from within the same page, remove otherwise)
      source: $A.getEl('bannerContainerElementId').parentNode.removeChild($A.getEl('bannerContainerElementId')),
      
      // Specify the path and ID of the banner content to be loaded
      // (Only if pulling content from an external page, remove otherwise)
      source: 'files/overlays.html #bannerContainerElementId',
      
      // Disable automatic positioning if wishing to use a Style Sheet instead
      autoFix: 0,
      
      // Specify that the banner should open as soon as the page loads
      autoStart: true,
      
      // Set a class name for the banner top level container element
      className: 'banner',
      
      // Specify that the textual content of the banner should automatically be announced to screen reader users when opened
      announce: true,
      
      // Choose the container element where the banner will be inserted
      isStatic: 'body',
      // Choose to prepend the banner instead of replacing the content within the container element
      // (This places the banner content at the top of the page in the reading order for screen readers)
      prepend: true,
      
      // Set a hidden close link to appear for screen reader users
      showHiddenClose: true,
      
      // Remove the hidden close link from the tab order so it doesn't appear when tabbing
      displayHiddenClose: false,
      
      // Set the heading level that will be accessible for screen reader users
      ariaLevel: 2,
      
      // Run a script after the banner finishes loading
      runAfter: function(dc){
      // Optionally do stuff
      // 'dc' is the Banner AccDC Object
      // dc.containerDiv is the DOM node where all banner content is rendered
      }
      
      // Other AccDC API properties and methods can go here as well if desired.
      
      }
      

    Programmatic Control

    The invocation statement returns the ID of the newly instantiated Banner AccDC Object, which can be used to programmatically control each banner using JavaScript if desired.

    Example:

    // Get a reference to the Banner AccDC Object
    var dc = $A.reg[bannerId];
    
    // Which you can then open
    
    dc.open();
    
    // Or close
    
    dc.close();
    
    // All other AccDC API properties and methods can be applied here as well.
    

    Styling

    The sample banners in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the banner. This is also useful as a practice template for trying out different styling designs with custom content.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled banner will be accessible.

    Bootstrapping

    Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.

    The banners within the Bootstrap folders are configured using HTML5 "data-" attributes within the HTML markup.

    When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class "accBanner", then configures the same module declaration as previously described using these HTML5 attributes.

    Available HTML5 attributes:

    • data-src : The resource path and pointer to the ID attribute of the banner container element.
    • data-role : The role name that is conveyed to screen reader users as beginning and ending boundary text for the new content. "Banner" is set by default if no value is specified.

    Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".

    Required attributes:

    • class="accBanner" : The bootstrap class name that specifies a banner insertion point container.
    • id : The unique ID of the element. This value is also registered as the ID of the banner AccDC Object, making it possible to invoke the object programmatically.
      E.G $A.reg.uniqueID.open();
      // All other AccDC API properties and methods are similarly available.

    A Carousel is a complex control type that is easy to make accessible.

    Expected behaviors: The beginning and ending boundaries should be conveyed to screen reader users, content changes should be announced to screen reader users only when a navigation button is manually activated, all navigation buttons should be keyboard accessible and include unique accesskeys for screen reader users, auto cycling should pause when an element within the carousel receives focus or when the mouse is moved into the region, auto cycling should resume when focus moves out of the carousel or when the mouse moves out of the region, and auto cycling should be stoppable from anywhere on the page using the keyboard.

    The Carousel Module automates these processes by adding all related event handlers and managing all related rendering procedures using an external XML file for configuration.

    HTML Syntax

    <div id="myCarousel"></div>
    

    XML Syntax

    An external XML file is used to configure and populate each slide of the carousel.

    Flat:

    <?xml version="1.0" encoding="UTF-8" ?>
    <carousel
    role="Slideshow"
    height="auto" width="auto"
    className="carouselCls"
    prevTitle="Previous" nextTitle="Next" slideName="Slide" groupName=""
    showGroup="" groupPosTop=""
    btnPText="↑" btnNText="↓" btnPGText="" btnNGText=""
    isGrouped="no"
    btnPAccesskey="1" btnNAccesskey="2" btnPGAccesskey="" btnNGAccesskey=""
    direction="tb" cycle="yes" timer="0" animDelay="1250" forward="yes"
    hiddenMsg="" >
    <slide announce="Unique Slide Name" ><![CDATA[
    HTML content to render goes here
    ]]></slide>
    <slide announce="Unique Slide Name" ><![CDATA[
    HTML content to render goes here
    ]]></slide>
    </carousel>
    

    Grouped:

    <?xml version="1.0" encoding="UTF-8" ?>
    <carousel
    role="Carousel"
    height="auto" width="auto"
    className="carouselCls"
    prevTitle="Previous" nextTitle="Next" slideName="Slide" groupName="Group"
    showGroup="yes" groupPosTop="yes"
    btnPText="←" btnNText="→" btnPGText="⇐" btnNGText="⇒"
    isGrouped="yes"
    btnPAccesskey="1" btnNAccesskey="2" btnPGAccesskey="3" btnNGAccesskey="4"
    direction="lr" cycle="yes" timer="5000" animDelay="2000" forward="yes"
    hiddenMsg="Press Escape to stop automatic cycling" >
    <group name="Unique Group Name" >
    <slide announce="Unique Slide Name" ><![CDATA[
    HTML content to render goes here
    ]]></slide>
    <slide announce="Unique Slide Name" ><![CDATA[
    HTML content to render goes here
    ]]></slide>
    </group>
    <group name="Unique Group Name" >
    <slide announce="Unique Slide Name" ><![CDATA[
    HTML content to render goes here
    ]]></slide>
    <slide announce="Unique Slide Name" ><![CDATA[
    HTML content to render goes here
    ]]></slide>
    </group>
    </carousel>
    

    Important: All attributes must remain within the XML markup. Attributes that are not required may be set to null. E.G. attributeName="".

    Carousel attribute definitions
    • role : Hidden text role for screen reader users
    • className : The class name for styling the top level AccDC Object container
    • prevTitle : Title and screen reader text for the previous button (Must be unique)
    • nextTitle : Title and screen reader text for the next button (Must be unique)
    • slideName : Shared name for a slide, appended to prevTitle and nextTitle for Next Slide and Previous Slide button labeling
    • isGrouped : Must be 'yes' or 'no': Must match the syntax of the XML markup (whether or not the group tag is present)
    • groupName : Shared name for a group, appended to prevTitle and nextTitle for Next Group and Previous Group button labeling
    • showGroup : If 'yes', group names will be displayed above or below the carousel (depending on the value of groupPosTop)
    • groupPosTop : If 'yes', group names are displayed above the carousel, if not, then they are displayed below (only if showGroup='yes')
    • btnPText : Visible textual label for the Previous Slide button; uses innerHTML to insert
    • btnNText : Visible textual label for the Next Slide button; uses innerHTML to insert
    • btnPGText : Visible textual label for the Previous Group button; uses innerHTML to insert
    • btnNGText : Visible textual label for the Next Group button; uses innerHTML to insert
    • btnPAccesskey : AccessKey for the Previous Slide button (for screen reader users)
    • btnNAccesskey : AccessKey for the Next Slide button (for screen reader users)
    • btnPGAccesskey : AccessKey for the Previous Group button (for screen reader users)
    • btnNGAccesskey : AccessKey for the Next Group button (for screen reader users)
    • direction : Must be either 'lr' (left to right), or 'tb' (top to bottom)
    • cycle : Must be either 'yes' or 'no' to set the behavior of infinite looping
    • timer : Set to '0' to disable auto rotation, or set a positive integer for N milliseconds
    • animDelay : Slide animation length in N milliseconds; set to '0' for instant rendering
    • forward : Set to 'yes' or 'no' to configure auto rotation to move backwards or forwards (relative to direction)
    • hiddenMsg : Hidden text message for screen reader users to convey supplementary information

    Group attribute definitions:

    • name : The shared name of the group, which will be displayed visually if showGroup='yes'

    Slide attribute definitions:

    • announce : The text that will be announced to screen reader users when a slide is manually changed using the navigation buttons.
      If the group tag 'name' attribute value matches the slide tag 'announce' attribute value, then set announce to "" to prevent redundancy for screen reader users.

    JavaScript

    $A.setCarousel( $A.getEl('myCarousel') , 'path/file.xml' , defaultIndexValue , {
    // Configure optional key / value mapping overrides
    });
    

    Parameters

    1. The first parameter is the DOM node container element where the carousel will be inserted.

    2. The second parameter is the file path for the associated XML file.

    3. The third parameter is the default slide index value when the carousel is rendered.

      When using a flat carousel, this should be of type 'number', such as 0; when using a grouped carousel, this should be of type 'string', such as '0,0'

    4. The fourth parameter is a key / value map of optional overrides to customize functionality.

      Example:

      {
      
      // Pause rotation automatically when carousel is first loaded. (Added in R2.9 for use with a Play/Pause button)
      pauseRotation: false,
      
      // Set the classes for the three floating Div panels that comprise the carousel
      
      // The left Div where the Prev Slide and Prev Group buttons are rendered
      lNavCls: 'lNav',
      // The center Div where the slides are cycled within a relatively positioned container
      contentCls: 'centerContent',
      // The right Div where the Next Slide and Next Group buttons are rendered
      rNavCls: 'rNav',
      
      // Set the nav button element type
      // ('button' is recommended so that the action is automatically triggered when accesskeys are pressed, which doesn't happen for other element types
      btnTag: 'button',
      
      // Override the default inner span tag inserted within the nav button element, which is inserted using innerHTML
      prevBtnInsertedTag: '',
      nextBtnInsertedTag: '',
      prevGroupBtnInsertedTag: '',
      nextGroupBtnInsertedTag: '',
      
      // Set the shared class name for all nav buttons
      btnCls: 'navButton',
      
      // Set the class name for the Next and Previous Slide buttons
      btnSlideCls: 'navSlideButton',
      
      // Set the class name for the Next and Previous Group buttons (if applicable)
      btnGroupCls: 'navGroupButton',
      
      // Set the class name for the Group Name container element (Div tag), which is optionally rendered above or below the center slide container
      groupNameCls: 'groupName',
      
      // Set the hidden heading level for screen reader users (defaults to 3 if omitted)
      ariaLevel: 2,
      
      // Set optional callbacks for the slide rendering action
      handlers: {
      
      // Runs every time a new slide completes rendering
      complete: function(dc){
      
      // 'this' is the Carousel AccDC Object, and is the same as the 'dc' argument
      // The content of the new slide is contained within the DOM node dc.containerDiv
      // E.G alert(dc.containerDiv.innerHTML);
      // dc.top is the top level AccDC Object for the carousel, which can be used to share data between handler functions.
      
      // Other DOM node properties that are available here
      // dc.top.btn.P : The Prev Button DOM node
      // dc.top.btn.N : The Next Button DOM node
      // dc.top.btn.PG : The Prev Group Button DOM node
      // dc.top.btn.NG : The Next Group Button DOM node
      
      // Available state and index values
      // dc.groupVal : the current index value of the currently active Group (if applicable)
      // dc.groupMax : the maximum number of Groups within the carousel
      // dc.slideVal : the current index value of the newly loaded slide (relative to siblings if contained within a Group)
      // dc.slideMax : the maximum number of Slides within the Group or carousel (if contained within a flat list)
      
      },
      
      // Runs every time the auto rotation of a carousel stops or resumes rotating
      
      stopStateChange: function(isStopped, dc){
      // isStopped or paused = true or false
      // Or for granular detection
      // dc.isStopped = true or false
      // dc.isPaused = true or false
      },
      
      // Runs every time the Previous Slide button is clicked
      btnPrev: function(ev, dc){
      
      // 'this' is the button element DOM node
      // 'dc' is the Carousel AccDC Object
      // dc.top is the top level AccDC Object for the carousel, which can be used to share data between handler functions.
      
      // Other DOM node properties that are available here
      // dc.btn.P : The Prev Button DOM node
      // dc.btn.N : The Next Button DOM node
      // dc.btn.PG : The Prev Group Button DOM node
      // dc.btn.NG : The Next Group Button DOM node
      
      // Available state and index values
      // dc.groupVal : the current index value of the currently active Group (if applicable)
      // dc.slideVal : the current index value of the newly loaded slide (relative to siblings if contained within a Group)
      
      // Return false to prevent the previous slide from rendering
      },
      
      // Runs every time the Next Slide button is clicked
      btnNext: function(ev, dc){
      
      // 'this' is the button element DOM node
      // 'dc' is the Carousel AccDC Object
      // dc.top is the top level AccDC Object for the carousel, which can be used to share data between handler functions.
      
      // Other DOM node properties that are available here
      // dc.btn.P : The Prev Button DOM node
      // dc.btn.N : The Next Button DOM node
      // dc.btn.PG : The Prev Group Button DOM node
      // dc.btn.NG : The Next Group Button DOM node
      
      // Available state and index values
      // dc.groupVal : the current index value of the currently active Group (if applicable)
      // dc.slideVal : the current index value of the newly loaded slide (relative to siblings if contained within a Group)
      
      // Return false to prevent the next slide from rendering
      },
      
      // Runs every time the Previous Group button is clicked
      btnPrevG: function(ev, dc){
      
      // 'this' is the button element DOM node
      // 'dc' is the Carousel AccDC Object
      // dc.top is the top level AccDC Object for the carousel, which can be used to share data between handler functions.
      
      // Other DOM node properties that are available here
      // dc.btn.P : The Prev Button DOM node
      // dc.btn.N : The Next Button DOM node
      // dc.btn.PG : The Prev Group Button DOM node
      // dc.btn.NG : The Next Group Button DOM node
      
      // Available state and index values
      // dc.groupVal : the current index value of the currently active Group (if applicable)
      // dc.slideVal : the current index value of the newly loaded slide (relative to siblings if contained within a Group)
      
      // Return false to prevent the previous group from rendering
      },
      
      // Runs every time the Next Group button is clicked
      btnNextG: function(ev, dc){
      
      // 'this' is the button element DOM node
      // 'dc' is the Carousel AccDC Object
      // dc.top is the top level AccDC Object for the carousel, which can be used to share data between handler functions.
      
      // Other DOM node properties that are available here
      // dc.btn.P : The Prev Button DOM node
      // dc.btn.N : The Next Button DOM node
      // dc.btn.PG : The Prev Group Button DOM node
      // dc.btn.NG : The Next Group Button DOM node
      
      // Available state and index values
      // dc.groupVal : the current index value of the currently active Group (if applicable)
      // dc.slideVal : the current index value of the newly loaded slide (relative to siblings if contained within a Group)
      
      // Return false to prevent the next group from rendering
      }
      
      },
      
      // Customize the DOM rendering order or add additional controls to the DOM when rendered within the carousel
      renderFn: function(parentDiv, leftDiv, centerDiv, bufferDiv, rightDiv, btnPrev, btnNext, isGrouped, btnPrevGroup, btnNextGroup){
      parentDiv.appendChild(leftDiv);
      parentDiv.appendChild(centerDiv);
      centerDiv.appendChild(bufferDiv);
      parentDiv.appendChild(rightDiv);
      leftDiv.appendChild(btnPrev);
      rightDiv.appendChild(btnNext);
      
      if (isGrouped){
      leftDiv.appendChild(btnPrevGroup);
      rightDiv.appendChild(btnNextGroup);
      }
      
      }
      
      }
      

    Programmatic Control

    When the carousel is instantiated, it includes many nested AccDC Objects that are bound using parent / child relationships.

    The top level ID for the carousel matches the ID attribute value of the insertion point container element, making it possible to control the carousel programmatically if desired.

    Example:

    // If the insertion point DIV tag includes id="myCarousel":
    // Get a reference to the Carousel AccDC Object
    var dc = $A.reg['myCarousel'];
    
    // Which you can then use to access stored data
    var data = serialize(dc.form);
    
    // Or close the carousel and remove it from the DOM
    dc.close();
    
    // All other AccDC API properties and methods are similarly available if desired.
    
    // Also, the following Carousel specific properties and methods are available here too
    
    // Set the carousel to a specific slide number, which must be equal to or greater than 0 to match the array index value
    
    dc.setSlide(slideNumber);
    
    // Or the same when using a grouped carousel
    
    dc.setSlide(slideNumber, groupNumber);
    
    // Programmatically stop auto cycling of a carousel
    
    dc.enableAuto(false);
    
    // Programmatically restart auto cycling of a carousel
    
    dc.enableAuto(true);
    
    // Return the current stopped state of an auto rotating carousel
    
    var isStopped = dc.isStopped();
    

    Important: The Carousel AccDC Object consists of many nested AccDC Objects which act as moving parts, similar to cogwheels within the construct. So when dc.close() is used to close the carousel, it, including all of its nested objects, are destroyed completely (This means that stored data will no longer be available programmatically after a carousel is closed).
    This is done to ensure that duplication and scheduling conflicts don't arise when dynamic content panels are swapped, causing the same carousel structure to be reloaded.

    Styling

    The sample carousels in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled carousel will be accessible.

    Drag and Drop isn't called for much as part of a general feature set, but it's good to know how to make this functionality accessible for both screen reader and keyboard only users.

    Expected behaviors: All draggable objects must be accessible from the keyboard with or without a screen reader running, and hidden links should be used to identify draggable objects and the location of drop zones.

    The Drag and Drop Module automates these processes by adding all related event handlers and managing all related rendering procedures.

    JavaScript

    $A.setDragAndDrop({
    // Configure functionality using a key / value map
    });
    

    Parameters

    1. The first parameter configures drag and drop functionality using a key / value map.

      Example:

      {
      
      // Specify the draggable objects using a CSS Selector
      setDrag: 'ul#options li > img',
      
      // Specify the initial drop zone
      setDrop: 'div.chosenBooks',
      
      // CSS Selector or DOM node that specifies an optional strategic focus point where programmatic focus will return after a drop action completes
      returnFocusTo: 'div.chosenBooks h3',
      
      // Set the context node
      root: document,
      
      // Now, since the hidden links need custom link text for each draggable item,
      // we're going to recursively query the data-label attribute for every image and return it
      setName: function(obj){
      // 'obj' is the object that matches the CSS Selector above in 'setDrag'
      return $A.getAttr(obj, 'data-label');
      },
      
      // Set the initial styles for the morphed AccDC Object, which will need absolute positioning
      cssObj:
      {
      position: 'absolute',
      zIndex: 1
      },
      
      // Prevent block formatting when surrounding divs are added
      displayInline: true,
      
      // Run script before the AccDC Object opens
      runBefore: function(dc){
      
      // Do stuff
      
      },
      
      // Run script after the AccDC Object opens
      runAfter: function(dc){
      
      // Do stuff
      
      },
      
      // Configure drag and drop event handlers
      on: {
      
      // Fire when the mouse moves a minimum distance.        
      dragStart: function(ev, dd, dc){
      // 'ev' is the event object
      // 'dd' is the Drag and Drop custom event object
      // 'dc' is the AccDC Object for the draggable object
      },
      
      // Fire every time the mouse moves when dragging.  
      drag: function(ev, dd, dc){
      // 'ev' is the event object
      // 'dd' is the Drag and Drop custom event object
      // 'dc' is the AccDC Object for the draggable object
      },
      
      // Fire when the dragged element moves within the tolerance of a drop target element.  
      dropStart: function(ev, dd, dc){
      // 'ev' is the event object
      // 'dd' is the Drag and Drop custom event object
      // 'dc' is the AccDC Object for the draggable object
      },
      
      // Fire when the dragged element is dropped within the tolerance of a drop target element.  
      drop: function(ev, dd, dc){
      // 'ev' is the event object
      // 'dd' is the Drag and Drop custom event object
      // 'dc' is the AccDC Object for the draggable object
      },
      
      // Fire when the dragged element moves out of the tolerance of a drop target element.  
      dropEnd: function(ev, dd, dc){
      // 'ev' is the event object
      // 'dd' is the Drag and Drop custom event object
      // 'dc' is the AccDC Object for the draggable object
      },
      
      // Fire after all other drag and drop handlers have fired.  
      dragEnd: function(ev, dd, dc){
      // 'ev' is the event object
      // 'dd' is the Drag and Drop custom event object
      // 'dc' is the AccDC Object for the draggable object
      }
      
      },
      
      // Restrict draggability, since there's no point in having stuff wiz around everywhere...
      confineTo: 'div.booksWrapper',
      
      // Set the drop animation time length for keyboard users in milliseconds
      duration: 2000,
      
      // Set keywords for screen reader and keyboard only users
      dragText: 'Move',
      toText: 'to',
      
      // IMPORTANT: All dropTarget elements must include a data-label attribute to specify a unique name for the drop region for screen reader and keyboard only users.
      // View the Coding Arena HTML markup for examples.
      
      actionText: 'Dragging',
      
      // Override default relative positioning to use absolute instead
      // Effects only the hidden drag links when they receive focus
      ddCSS:
      {
      position: 'absolute',
      zIndex: 10
      },
      
      // Set class names for the drag links
      dragClassName: 'ddLink'
      
      }
      

    DD Object Properties

    The properties and methods of the 'dd' drag and drop custom event object are as follows:

    For drag events:

    • target (DOM Node) : The drag element to which the event handler has been bound. (Always the same as "this" within a drag event handler)
    • drag (DOM Node) : The dragged element to which the drag event has been bound.
    • proxy (DOM Node) : The dragged element which determines the drop target tolerance.
    • drop (Array) : An array of all active drop targets for the current drag instance.
    • available (Array) : An array of all available drop targets for the current instance.
    • update (Method) : Helper function that updates the locations of all available drop targets in the current drag instance.
    • startX (Number) : The horizontal location of the "mousedown" event.
    • startY (Number) : The vertical location of the "mousedown" event.
    • deltaX (Number) : The horizontal distance moved from "startX".
    • deltaY (Number) : The vertical distance moved from "startX".
    • originalX (Number) : The starting horizontal position of the dragged element.
    • originalY (Number) : The starting vertical position of the dragged element.
    • offsetX (Number) : The moved horizontal position of the dragged element.
    • offsetY (Number) : The moved vertical position of the dragged element.

    For drop events:

    • target (DOM Node) : The drop element to which the event handler has been bound. (Always the same as "this" within an event handler)
    • drag (DOM Node) : The dragged element to which the drag event has been bound.
    • proxy (DOM Node) : The dragged element, which determines the drop target tolerance.
    • drop (Array) : Array of all active drop targets for the current drag instance.
    • available (Array) : Array of all available drop targets for the current drag instance.
    • update (Method) : Helper function that updates the locations of all available drop targets in the current drag instance.
    • startX (Number) : The horizontal location of the "mousedown" event.
    • startY (Number) : The vertical location of the "mousedown" event.
    • deltaX (Number) : The horizontal distance moved from "startX".
    • deltaY (Number) : The vertical distance moved from "startX".
    • originalX (Number) : The starting horizontal position of the dragged element.
    • originalY (Number) : The starting vertical position of the dragged element.
    • offsetX (Number) : The moved horizontal position of the dragged element.
    • offsetY (Number) : The moved vertical position of the dragged element.

    Footnotes are simple control types that are easy to make accessible.

    Expected behaviors: Provide a link as the footnote that jumps to the footnote text, provide a link at the footnote text that returns focus back to the triggering element (and account for multiple footnote links that lead to the same footnote text), and provide meaningful textual equivalents for screen reader users.

    The Footnotes Module automates these processes by creating all necessary anchor elements, adding all related event handlers, and managing keyboard focus appropriately.

    HTML Syntax

    Footnote text in the body:

    <span class="accFootnote" data-footnote="footnotePointer1">My body text</span>
    

    A SPAN tag should be used to surround the word or phrase that you want to designate as a footnote within the body content.

    Required attributes for Footnote SPANs in the body:

    • class="accFootnote" : The class name that specifies a footnote link section to be bound. (All footnote tags should share the same class name.)
    • data-footnote : Contains the ID attribute value that points to the specified footnote text at the bottom of the page. (More than one footnote may point to the same footnote text by using the same ID value if multiple footnotes reference the same text)

    Important: When the footnotes are parsed using the class name, a numerical index link is generated and appended to the footnote SPAN tag.

    Footnote Text nodes in the footer:

    <span id="footnotePointer1"></span>
    

    An empty SPAN tag should be used to set the focus point of the Footnote Text node in the footer, which is where focus will be moved to when the footnote link in the body is activated.

    The Footnote Text SPAN tag must be placed just before the footnote text in the source code order, since this is where the Footnote Back Link will be inserted.
    (This is also where focus is moved to when a footnote link in the body is activated, which must be before the relevant footnote text, and not after.)

    The Footnote Text SPAN tag must be empty, and must not surround the footnote text. Doing so will cause the inserted Back Link to appear after the footnote text, instead of before it, as expected.

    Required attributes for Footnote Text SPANs in the footer:

    • id="uniqueId" : The unique ID of the Footnote Text node.
      (This must match the value of data-footnote so that each associated footnote link in the body will be properly bound to this focusable node in the footer.)

    The following attributes are handled automatically by the Footnotes Module:

    • aria-label

    JavaScript

    $A.setFootnotes('.accFootnote', document, {
    // Configure functionality key / value mappings
    });
    

    Parameters

    1. The first parameter is a CSS Selector that specifies all footnote SPAN tags in the body.

    2. The second parameter is the context DOM node where footnote SPANs will be queried using the CSS Selector declared in parameter one. (This makes it possible to query footnotes contained within iFrame documents)

    3. The third parameter configures footnote functionality using a key / value map.

      Example:

      {
      
      // Set the tooltip text for the footnote (this will also be the accessible name for screen reader users)
      fnText: 'Footnote',
      
      // Set the footnote character or text that will comprise the visual link text for returning footnotes
      fnChar: '†',
      
      // Set the tooltip text for the footnote back links (this will also be the accessible name for screen reader users)
      backText: 'Back to Footnote'
      
      }
      

    Styling

    The sample footnotes in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled footnotes will be accessible.

    Bootstrapping

    Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.

    The footnotes within the Bootstrap folders are configured using HTML5 "data-" attributes within the HTML markup.

    When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class "accFootnote", then configures the same module declaration as previously described using these HTML5 attributes.

    Available HTML5 attributes for footnote SPANs in the body:

    • data-footnote : The ID attribute value of the matching footnote text anchor tag elsewhere in the document (Focus will be moved to this anchor tag when the footnote link is activated)
    • data-fntext : The tooltip text for the footnote (this will also be the accessible name for screen reader users)
    • data-fnchar : The footnote character or text that will comprise the visual link text for returning footnotes
    • data-backtext : The tooltip text for the footnote back links (this will also be the accessible name for screen reader users)

    Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".

    Required attributes:

    • class="accFootnote" : The bootstrap class name that specifies a footnote link to be bound. (Must only be on footnote links in the body, and not upon footnote text anchors in the footer)
    • id : The unique ID of the footnote text anchor tag. (Must only be on footnote text anchors, and must match the data-footnote attribute values for associated footnote links within the body)

    Error Tooltips provide a simple way to validate user input prior to server side interaction.

    Dynamic Help Tooltips work in a similar fashion, by suggesting responses that must also pass validation.

    Both fulfill the same role, but on opposite spectrums.

    Error Tooltips occur after a form field loses focus, which is when validation occurs.

    Dynamic Help Tooltips validate user input as the interaction occurs, so that responses can be adjusted before focus is moved to the next field.

    The Form Field Validation Module automates these processes by adding all related event handlers and managing all related rendering procedures.

    HTML Syntax

    Any standard form field.

    Examples:

    <label for="field1"> My Text Field: </label>
    <input type="text" id="field1" name="whatever1" />
    
    <label for="field2"> My Select : </label>
    <select id="field2" name="whatever2">
    <option value="v0"> Option One </option>
    <option value="v1"> Option Two </option>
    </select>
    
    <input type="checkbox" id="field3" name="whatever3" />
    <label for="field3"> My Checkbox </label>
    
    <input type="radio" id="field4" name="whatever4" />
    <label for="field4"> My Radio Button </label>
    

    The following attributes are handled automatically by the Form Field Validation Module:

    • aria-required

    JavaScript

    $A.setFormFields( FormElementDOM-Node , {
    
    'formFieldId1': {
    // Configure error handling for the form field with id="formFieldId1"
    },
    
    'formFieldId2': {
    // Configure error handling for the form field with id="formFieldId2"
    }
    
    }, function(ev){
    // 'ev' is the onSubmit event object for the form element passed in parameter one
    // 'this' is the form element
    // Optionally do stuff before the form is submitted
    // use ev.preventDefault() to cancel if desired
    });
    

    Parameters

    1. The first parameter is the form element where the onSubmit event is attached.

    2. The second parameter configures form field bindings using a key / value map.

      Example:

      {
      
      // Configure an error handling tooltip for a form field with a specific ID attribute value
      'formFieldId1': {
      
      errorText: 'Initial error text to be displayed',
      
      // Fire every time the field loses focus
      validate: function(ev, dc){
      // 'this' is the form field to be validated
      // 'dc' is the Tooltip AccDC Object
      // All other AccDC API properties and methods apply to the 'dc' object as well
      // return true to pass validation, or false to fail
      },
      
      // Optionally choose to hide or show the tooltip visually
      // false is set by default if omitted
      hideError: false,
      
      // Set a class to be toggled when an error is detected
      // This will be bound to the dc.triggerObj DOM node, or optionally to the dc.targetObj or dc.classObj DOM node instead if declared.
      // 'validateError' is set by default if omitted
      toggleClass: 'validateError',
      
      overrides: {
      
      // Change the beginning and ending boundary role text for screen reader users
      role: 'error',
      
      // Set a class for the tooltip container
      className: 'errorTooltip',
      
      // Change the DOM insertion point to another DOM node by setting targetObj.
      // The triggering Input field is used by default if omitted
      targetObj: DOM-Node,
      
      // Set a node where the toggleClass property value will be toggled when validation fails
      // The triggering Input field or targetObj element is used by default if omitted
      classObj: DOM-Node,
      
      // Optionally set the element where visual positioning calculations will be bound to
      posAnchor: DOM-Node
      
      // Additional AccDC API properties and methods to set as functionality and behavior overrides go here as well
      
      }
      
      },
      
      // Configure a dynamic help tooltip for a form field with a specific ID attribute value
      'formFieldId2': {
      
      helpText: 'Initial help text to be displayed',
      
      // Fire every time the value changes
      validate: function(ev, dc){
      // 'this' is the form field to be validated
      // 'dc' is the Tooltip AccDC Object
      // dc.source can be used to dynamically change the tooltip content (HTML markup is accepted)
      // dc.open() will reopen the tooltip and display the updated content
      // dc.close() will close the tooltip if desired
      // All other AccDC API properties and methods apply to the 'dc' object as well
      // return true to pass validation, or false to fail
      },
      
      // Assign a class to be toggled
      toggleClass: 'passedValidation',
      
      // Set the above class to be toggled only when validation is true, and not when false
      togglePassed: true,
      
      overrides: {
      
      // Change the beginning and ending boundary role text for screen reader users
      role: 'help',
      
      // Set a class for the tooltip container
      className: 'helpTooltip',
      
      // Change the DOM insertion point to another DOM node by setting targetObj.
      // The triggering Input field is used by default if omitted
      targetObj: DOM-Node,
      
      // Set a node where the toggleClass property value will be toggled when validation passes or fails
      // (Depends whether 'togglePassed' is set to true or false)
      // The triggering Input field or targetObj element is used by default if omitted
      classObj: DOM-Node,
      
      // Optionally set the element where visual positioning calculations will be bound to
      posAnchor: DOM-Node
      
      // Additional AccDC API properties and methods to set as functionality and behavior overrides go here as well
      
      }
      
      }
      
      }
      
    3. The third parameter is an optional onSubmit handler that will run just before the form is submitted after validation passes.

    Styling

    The sample tooltips in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled tooltips will be accessible.

    Implementation Notes

    All form fields must be explicitly labeled to ensure accessibility for the highest percentage of people.

    Explicit labelling can be achieved using the LABEL and INPUT elements, by matching the LABEL tag's For attribute with the INPUT tag's Id attribute,
    or by setting the Title attribute on the INPUT tag with an informative label,
    or by setting the aria-label attribute on the INPUT tag with an informative label,
    or by setting the aria-labelledby attribute on the INPUT tag that references the ID of an informative label.

    The advantage of using an explicitly associated LABEL element and INPUT tag, is that mouse users can click the label text and automatically activate the form field that it applies to. Voice navigation software also uses explicit LABEL/INPUT tag associations to aid navigation.

    This type of functionality does not occur when using the Title attribute or ARIA to explicitly associate a label.

    When an INPUT element has an explicitly associated LABEL tag, a Title attribute should not be included. Screen readers often use an order of precedence when reading form field labels, and will often announce one or the other, but not both.

    When a form field has an explicit LABEL, additional information can also be associated with the form field using aria-describedby, which will automatically be announced to screen reader users when focus is set to that field.

    Example:

    <label for="field1"> My Text Field: </label>
    <input type="text" id="field1" aria-describedby="additional1" name="whatever" />
    <span id="additional1"> Supplementary Text </span>
    

    Important: When implementing supplementary text to be announced for screen reader users, never use "display:none" or "visibility:hidden" to hide the text that is being announced. Doing so will make it impossible for screen reader users to browse the supplementary text using the arrow keys if clarification is needed. If you wish to hide the supplementary text from sighted users, use offscreenText instead.

    A Modal is a relatively simple control type, and can easily be made accessible.

    Expected behaviors: Ensure that the background content is hidden from screen reader users, ensure that the beginning and ending boundaries are conveyed to screen reader users, make sure the modal can be closed from the keyboard, and ensure that circular tabbing confines keyboard focus within the modal content.

    The Modal Module automates these processes by instantiating the content as a Modal AccDC Object, which can be configured and controlled programmatically if desired to enhance functionality.

    HTML Syntax

    For the triggering element:

    <a href="#" id="modalTrigger"> Triggering Element </a>
    

    (A triggering element is not actually required)

    For the modal container element:

    <div id="modalContainerId">
    Modal content goes here.
    </div>
    

    Required HTML5 attributes for the modal container element:

    • data-first="true" : Must be added to the first focusable active element within the modal to control circular tabbing and shift+tabbing.
    • data-last="true" : Must be added to the last focusable active element within the modal to control circular tabbing and shift+tabbing.

    Also, when Implementing a Close link or button, the className must match the "closeClassName" property within the JavaScript invocation statement. (If not explicitly set, the default value "lbClose" will be set by default, and should be used for all Close links or buttons) Doing so will automatically bind the AccDC Close Methods with this element, and return keyboard focus properly when the AccDC Object is closed.

    The following attributes are handled automatically by the Modal Module:

    • aria-hidden

    JavaScript

    var modalId = $A.setModal({
    // Configure functionality key / value mappings
    });
    

    Parameters

    1. The first parameter configures modal functionality using a key / value map.

      Example:

      {
      
      // Set a unique ID for the modal AccDC Object, which can be referenced through $A.reg['uniqueId']
      id: 'uniqueId',
      
      // Set the screen reader accessible boundary text values
      role: 'Modal',
      
      // Set a triggering element using either the DOM node or a CSS Selector
      // (Only if a triggering element is present, remove otherwise)
      trigger: '#modalTrigger',
      
      // Prevent focus from returning to a triggering element
      // (Only if a triggering element is not present, remove otherwise)
      returnFocus: false,
      
      // Specify that literal content is to be rendered
      // (Only if pulling content from within the same page, remove otherwise)
      mode: 0,
      
      // Use removeChild to grab the desired modal content from within the document
      // This is important to prevent ID attribute conflicts later
      // (Only if pulling content from within the same page, remove otherwise)
      source: $A.getEl('modalContainerId').parentNode.removeChild($A.getEl('modalContainerId')),
      
      // Specify the file path and ID attribute of the modal container element
      // (Only if pulling content from an external page, remove otherwise)
      source: 'files/modal.html #modalContainerId',
      
      // Set the class name for the top level container element
      className: 'modal',
      
      // Set the class name for the screen reader accessible close link
      // This must match the class name for any close links or buttons within the modal content, which will cause Close Method Binding to automatically occur when the content is rendered.
      closeClassName: 'lbClose',
      
      // Enable the ARIA modal dialog design pattern as documented at
      // http://whatsock.com/training/matrices/#dialog
      ariaDialog: false,
      
      // Enable role=alert to announce the Dialog content no matter which window is currently active.
      alertDialog: false,
      
      // Run script after the Modal AccDC Object finishes loading
      runAfter: function(dc){
      
      // 'dc' is the Modal AccDC Object
      
      // Set a background Div for the modal, so it will appear as a lightbox
      dc.backdrop = $A.createEl('div', null, null, 'modalBackdrop', document.createTextNode(' '));
      // Now insert the backdrop Div before the Modal AccDC Object top level container
      dc.accDCObj.parentNode.insertBefore(dc.backdrop, dc.accDCObj);
      
      // Now configure content bindings within the modal
      // dc.containerDiv is the DOM node where the newly rendered modal content is contained
      
      // All other AccDC API properties and methods are similarly available for the 'dc' object
      
      },
      
      // Run script after the Modal AccDC Object finishes closing
      runAfterClose: function(dc){
      // Remove the backdrop Div
      if (dc.backdrop)
      dc.backdrop.parentNode.removeChild(dc.backdrop);
      }
      
      // (Other AccDC API properties and methods can be declared here also to customize functionality and behavior)
      
      }
      

    Programmatic Control

    Every modal is registered as an AccDC Object, the ID of which is returned by the JavaScript invocation statement.

    This means that you can programmatically control each modal using JavaScript.

    Example:

    // Get a reference to the Modal AccDC Object using the ID  stored in the modalId variable
    var dc = $A.reg[modalId];
    
    // Now invoke the modal
    dc.open();
    
    // Or close the modal
    dc.close();
    
    // All other AccDC API properties and methods can be applied here as well.
    

    Triggering Element Requirements

    A triggering element for a modal is not required, but when one is present, you should always use an active element for this purpose to ensure accessibility for both screen reader and keyboard only users.

    Within the Coding Arena samples, these are standard links (A tags with an Href attribute). However, you can use whatever type of triggering element you wish, a standard link, button, or image link, with any type of styling.

    Styling

    The sample modals in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the modal. This is also useful as a practice template for trying out different styling designs with custom content.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled modal will be accessible.

    Bootstrapping

    Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.

    The modals within the Bootstrap folders are configured using HTML5 "data-" attributes within the HTML markup.

    When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class "accModal", then configures the same module declaration as previously described using these HTML5 attributes.

    Available HTML5 attributes for the triggering element:

    • data-src : The resource path and pointer to the ID attribute of the modal container element. If set, data-internal should be blank or not included.
    • data-internal : The ID attribute of the modal container element within the same document. If data-internal is set, data-src should be blank or not included.
    • data-role : The role name that is conveyed to screen reader users as beginning and ending boundary text for the new content. "Modal" is set by default if no value is specified.

    Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".

    Required attributes for the triggering element:

    • class="accModal" : The bootstrap class name that specifies an accessible modal.
    • id : The unique ID of the element. This value is also registered as the ID of the modal AccDC Object, making it possible to invoke the object programmatically.
      E.G $A.reg.uniqueID.open();
      // All other AccDC API properties and methods are similarly available.

    Implementation Notes

    Do not use aria-haspopup. It might sound like a good idea to notify screen reader users that a 'Popup' is attached by adding the attribute aria-haspopup="true" to the triggering element, but this is not a good idea.

    Screen readers announce different feedback based on the various combinations of element types and ARIA roles in the markup, which can lead to confusion and misrepresent the purpose of the feature altogether.

    Examples:

    <!-- Triggering Element One
    JAWS 13 and 14 announces as "Has Popup"
    NVDA2013 announces as "SubMenu"
    -->
    
    <a href="#" aria-haspopup="true"> Triggering Element One </a>
    
    <!-- Triggering Element Two
    JAWS 13 and 14 announces as "Menu"
    NVDA2013 announces as "Menu Button SubMenu"
    -->
    
    <a href="#" role="button" aria-haspopup="true"> Triggering Element Two </a>
    
    <!-- Triggering Element Three
    JAWS 13 and 14 announces as "Menu"
    NVDA2013 announces as "Menu Button SubMenu"
    -->
    
    <button aria-haspopup="true"> Triggering Element Three </button>
    

    In short, don't use aria-haspopup unless you are triggering a menu.

    A Popup is a relatively simple control type, and can easily be made accessible.

    Expected behaviors: Ensure that the beginning and ending boundaries are conveyed to screen reader users, make sure the popup can be closed from the keyboard, and ensure that focus moves appropriately when the popup opens and closes.

    The Popup Module automates these processes by instantiating the content as a Popup AccDC Object, which can be configured and controlled programmatically if desired to enhance functionality.

    HTML Syntax

    For the triggering element:

    <a href="#" id="popupTrigger"> Triggering Element </a>
    

    For the popup container element:

    <div id="popupContainerId">
    Popup content goes here.
    </div>
    

    When Implementing a Close link or button, the className must match the "closeClassName" property within the JavaScript invocation statement. (If not explicitly set, the default value "popupClose" will be set by default, and should be used for all Close links or buttons) Doing so will automatically bind the AccDC Close Methods with this element, and return keyboard focus properly when the AccDC Object is closed.

    JavaScript

    var popupId = $A.setPopup({
    // Configure functionality key / value mappings
    });
    

    Parameters

    1. The first parameter configures popup functionality using a key / value map.

    Example:

    {
    
    // Set a unique ID for the Popup AccDC Object, which can be referenced through $A.reg['uniqueId']
    id: 'uniqueId',
    
    // Set the screen reader accessible boundary text values
    role: 'Popup',
    
    // Set a triggering element using either the DOM node or a CSS Selector
    trigger: '#popupTrigger',
    
    // Specify that literal content is to be rendered
    // (Only if pulling content from within the same page, remove otherwise)
    mode: 0,
    
    // Use removeChild to grab the desired popup content from within the document
    // This is important to prevent ID attribute conflicts later
    // (Only if pulling content from within the same page, remove otherwise)
    source: $A.getEl('popupContainerId').parentNode.removeChild($A.getEl('popupContainerId')),
    
    // Specify the file path and ID attribute of the popup container element
    // (Only if pulling content from an external page, remove otherwise)
    source: 'files/popup.html #popupContainerId',
    
    // Position the popup on the right of the triggering element
    autoPosition: 3,
    
    // Move the Popup AccDC Object 10px to the right, and 20px up when opened
    offsetLeft: 10,
    offsetTop: -20,
    
    // Set the class name for the top level container element
    className: 'popup',
    
    // Set the class name for the screen reader accessible close link
    // This must match the class name for any close links or buttons within the popup content, which will cause Close Method Binding to automatically occur when the content is rendered.
    closeClassName: 'popupClose',
    
    // Set a visually hidden close link for screen reader users to appear at the end of the popup content
    showHiddenClose: true,
    
    // Set the visually hidden close link to appear onFocus (required for 508 compliance if no other keyboard accessible close method is available)
    displayHiddenClose: true,
    
    // Set the heading level that will be accessible for screen reader users
    ariaLevel: 2,
    
    // Run script after the Popup AccDC Object finishes loading
    runAfter: function(dc){
    // 'dc' is the Popup AccDC Object
    // dc.containerDiv is the DOM node where the newly rendered popup content is contained
    // All other AccDC API properties and methods are similarly available for the 'dc' object
    },
    
    // Run script after the Popup AccDC Object finishes closing
    runAfterClose: function(dc){
    // Optionally do stuff
    }
    
    // (Other AccDC API properties and methods can be declared here also to customize functionality and behavior)
    
    }
    

    Programmatic Control

    Every popup is registered as an AccDC Object, the ID of which is returned by the JavaScript invocation statement.

    This means that you can programmatically control each popup using JavaScript.

    Example:

    // Get a reference to the Popup AccDC Object using the ID  stored in the popupId variable
    var dc = $A.reg[popupId];
    
    // Now invoke the popup
    dc.open();
    
    // Or close the popup
    dc.close();
    
    // All other AccDC API properties and methods can be applied here as well.
    

    Triggering Element Requirements

    Regarding the triggering element, you should always use an active element for this purpose to ensure accessibility for both screen reader and keyboard only users.

    Within the samples, these are standard links (A tags with an Href attribute). However, you can use whatever type of triggering element you wish, a standard link, button, or image link, with any type of styling. There must be an active element as a triggering element though, to ensure accessibility.

    Styling

    The sample popups in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the popup. This is also useful as a practice template for trying out different styling designs with custom content.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled popup will be accessible.

    Bootstrapping

    Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.

    The popups within the Bootstrap folders are configured using HTML5 "data-" attributes within the HTML markup.

    When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class "accPopup", then configures the same module declaration as previously described using these HTML5 attributes.

    Available HTML5 attributes for the triggering element:

    • data-src : The resource path and pointer to the ID attribute of the popup container element. If set, data-internal should be blank or not included.
    • data-internal : The ID attribute of the popup container element within the same document. If data-internal is set, data-src should be blank or not included.
    • data-role : The role name that is conveyed to screen reader users as beginning and ending boundary text for the new content. "Popup" is set by default if no value is specified.
    • data-autoposition : The autoPosition override, which dynamically positions the new content relative to the triggering element. This reflects the autoPosition property documented within AccDC, and may be a value between 0 and 12. The default is 3 if left blank or not included.
    • data-offsetleft : The offsetLeft override, which dynamically positions the new content relative to the triggering element. The default is 10 if left blank or not included.
    • data-offsettop : The offsetTop override, which dynamically positions the new content relative to the triggering element. The default is -20 if left blank or not included.

    Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".

    Required attributes for the triggering element:

    • class="accPopup" : The bootstrap class name that specifies an accessible popup.
    • id : The unique ID of the element. This value is also registered as the ID of the Popup AccDC Object, making it possible to invoke the object programmatically.
      E.G $A.reg.uniqueID.open();
      // All other AccDC API properties and methods are similarly available.

    Implementation Notes

    Do not use aria-haspopup.

    It might sound like a good idea to notify screen reader users that a 'Popup' is attached by adding the attribute aria-haspopup="true" to the triggering element, but this is not a good idea.

    Screen readers announce different feedback based on the various combinations of element types and ARIA roles in the markup, which can lead to confusion and misrepresent the purpose of the feature altogether.

    Examples:

    <!-- Triggering Element One
    JAWS 13 and 14 announces as "Has Popup"
    NVDA2013 announces as "SubMenu"
    -->
    
    <a href="#" aria-haspopup="true"> Triggering Element One </a>
    
    <!-- Triggering Element Two
    JAWS 13 and 14 announces as "Menu"
    NVDA2013 announces as "Menu Button SubMenu"
    -->
    
    <a href="#" role="button" aria-haspopup="true"> Triggering Element Two </a>
    
    <!-- Triggering Element Three
    JAWS 13 and 14 announces as "Menu"
    NVDA2013 announces as "Menu Button SubMenu"
    -->
    
    <button aria-haspopup="true"> Triggering Element Three </button>
    

    In short, don't use aria-haspopup unless you are triggering a menu.

    A Progress Bar control is a relatively simple HTML5 control that, nevertheless, does require a specific implementation in order to work correctly in a backwards compatible manner with Internet Explorer 8.

    The Progress Bar module automates this process by instantiating a Progress Bar control that can be programmatically set at runtime as values change.

    HTML Syntax

    Unobtrusive:

    (No HTML markup is needed)

    Inline:

    <div id="pbTargetZone"></div>
    

    The following attributes are handled automatically by the Progress Bar Module:

    • value
    • aria-valuetext

    JavaScript

    var myProgressBar = $A.setProgressBar({
    // Configure functionality using a key / value map
    });
    

    Parameters

    1. The first parameter configures Progress Bar functionality using a key / value map.

      Example:

      {
      
      // Set a unique ID, which will also be the ID attribute value for the 'progress' element when rendered
      id: 'progressbar1',
      
      // Set the boundary text for screen reader users
      role: 'Download',
      
      // Set initial values for the progress bar, values may be of type Int or Float
      config: {
      value: 0,
      max: 100
      },
      
      // Specify the container element where the Progress Bar AccDC Object will be inserted
      // (Only if pointing to the ID of a target zone container element, remove otherwise)
      isStatic: '#pbTargetZone',
      
      // Specify the container element where the unobtrusive Progress Bar AccDC Object will be inserted
      // (Only if no target zone container tag is present, remove otherwise)
      isStatic: 'body',
      // Also, prepend the progress bar content to the content already contained within the body element
      // This also places it at the top of the page for screen reader users
      prepend: true,
      
      // Set the class name for the top level container Div that surrounds the 'progress' element
      className: 'progressBar',
      
      // Load the Progress Polyfill script after the progress bar is rendered for cross-browser compatibility
      // (The accompanying CSS file must also be included in the header of the page)
      runJSAfter: ['js/progress-polyfill.min.js'],
      
      // Run script after the progress bar finishes rendering
      runAfter: function(dc){
      // Optionally do something
      // dc.source is the DOM node for the rendered 'progress' element
      },
      
      // Run script after the progress bar finishes closing
      runAfterClose: function(dc){
      // Optionally do something
      }
      
      // Other AccDC API properties and methods can be applied here as well if desired
      
      }
      

    Programmatic Control

    The function "$A.setProgressBar" returns the instantiated AccDC Object for the progress bar, which can then be controlled as follows:

    // Render the Progress Bar
    myProgressBar.open();
    
    // Update the Progress Bar with a new value
    myProgressBar.set(50);
    
    // Then close the Progress Bar after the process has completed
    myProgressBar.close();
    

    Styling

    The sample Progress Bars in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.

    Instructions for changing the visual appearance of the 'progress' element are discussed in the article "Cross Browser HTML5 Progress Bars In Depth".

    Implementation Notes

    To ensure proper rendering across various browsers, the Progress Bar Module requires the following dependencies:

    A Scrollable Div is a very simple control type, which can easily be made accessible.

    Expected behaviors: Ensure that the scrollable container element receives keyboard focus, and ensure that the Up/Down/Left/Right arrow keys and the PageUp/PageDown and the Home/End keys scroll content appropriately.

    The Scrollable Div Module automates these processes by making the scrollable container keyboard accessible.

    HTML Syntax

    <div id="scrollableDivId">
    <div>
    Scrollable content goes here.
    </div>
    </div>
    

    The following attributes are handled automatically by the Scrollable Div Module:

    • tabindex

    JavaScript

    $A.makeScrollable(scrollableDivDOM_Node, 'textMessageForScreenReaderUsers');
    

    Parameters

    1. The first parameter is the DOM node of the scrollable div container (with 'overflow:auto' in the CSS).

    2. The second parameter is the text string that will be announced to screen reader users the first time that focus moves into the Scrollable Div. (This message alerts VoiceOver users that the region is scrollable.) Scrollable Region is set by default if no value is specified.

    Styling

    The sample Scrollable Divs in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled Scrollable Div will be accessible.

    Bootstrapping

    Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.

    The Scrollable Divs within the Bootstrap folders are configured using HTML5 "data-" attributes within the HTML markup.

    When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class "accScrollable", then configures the same module declaration as previously described using these HTML5 attributes.

    Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".

    Required attributes:

    • class="accScrollable" : The bootstrap class name that specifies an accessible Scrollable Div.

    Implementation Notes

    Do not use aria-haspopup.

    It might sound like a good idea to notify screen reader users that a 'popup' is attached by adding the attribute aria-haspopup="true" to the triggering element (if applicable), but this is not a good idea.

    Screen readers announce different feedback based on the various combinations of element types and ARIA roles in the markup, which can lead to confusion and misrepresent the purpose of the feature altogether.

    Examples:

    <!-- Triggering Element One
    JAWS 13 and 14 announces as "Has Popup"
    NVDA2013 announces as "SubMenu"
    -->
    
    <a href="#" aria-haspopup="true"> Triggering Element One </a>
    
    <!-- Triggering Element Two
    JAWS 13 and 14 announces as "Menu"
    NVDA2013 announces as "Menu Button SubMenu"
    -->
    
    <a href="#" role="button" aria-haspopup="true"> Triggering Element Two </a>
    
    <!-- Triggering Element Three
    JAWS 13 and 14 announces as "Menu"
    NVDA2013 announces as "Menu Button SubMenu"
    -->
    
    <button aria-haspopup="true"> Triggering Element Three </button>
    

    In short, don't use aria-haspopup unless you are triggering a menu.

    Additionally, no ARIA attributes are necessary to make a Scrollable Div accessible for screen reader users.

    VoiceOver instructions for use on iOS touch screen devices:

    To navigate the content of a Scrollable Div using VoiceOver, use the Rotator (turn three fingers like turning a knob) to select Line Mode, then use one finger to swipe up and down within the scrollable content to navigate.

    Credit goes to David Hilbert Poehlman for providing VoiceOver rotator navigation technique instructions.

    A Tooltip is a relatively simple control type, which can easily be made accessible.

    Expected behaviors: Ensure that the beginning and ending boundaries are conveyed to screen reader users, and make sure the Tooltip is accessible from the keyboard.

    The Tooltip Module automates these processes by instantiating the content as a Tooltip AccDC Object, which can be configured and controlled programmatically if desired to enhance functionality.

    HTML Syntax

    For the triggering element:

    <a href="#" id="tooltipTrigger1"> Triggering Element </a>
    

    Or

    <input type="..." id="tooltipTrigger2" title="Field name if no Label tag is associated" />
    

    Or

    <select id="tooltipTrigger3" title="Field name if no Label tag is associated">
    <option value="0"> Option One </option>
    <option value="1"> Option Two </option>
    </select>
    

    For the tooltip container element:

    <div id="tooltipContainerId">
    Tooltip content goes here.
    </div>
    

    JavaScript

    var tooltipId = $A.setTooltip({
    // Configure functionality key / value mappings
    });
    

    Parameters

    1. The first parameter configures tooltip functionality using a key / value map.

      Example:

      {
      
      // Set a unique ID for the Tooltip AccDC Object, which can be referenced through $A.reg['uniqueId']
      id: 'uniqueId',
      
      // Set the role name for the container
      role: 'tooltip',
      
      // Set the triggering element using a DOM node or a CSS Selector
      trigger: '#tooltipTrigger1',
      
      // Set an optional time delay in milliseconds
      wait: 1500,
      
      // Specify that literal content is to be rendered
      // (Only if pulling content from within the same page, remove otherwise)
      mode: 0,
      
      // Use removeChild to grab the desired Tooltip content from within the document
      // This is important to prevent ID attribute conflicts later
      // (Only if pulling content from within the same page, remove otherwise)
      source: $A.getEl('tooltipContainerId').parentNode.removeChild($A.getEl('tooltipContainerId')),
      
      // Set a file path to pull the Tooltip content from and reference the container element ID
      // (Only if pulling content from an external page, remove otherwise)
      source: 'files/tooltip.html #tooltipContainerId',
      
      // Position the Tooltip on the right of the triggering element
      autoPosition: 3,
      
      // Move the Tooltip AccDC Object 10px to the right when opened
      offsetLeft: 10,
      
      // Set the class name for the top level container element
      className: 'tooltip'
      
      // (Other AccDC API properties and methods can be declared here also to customize functionality and behavior)
      
      }
      

    Programmatic Control

    Every tooltip is registered as an AccDC Object, the ID of which is returned by the JavaScript invocation statement.

    This means that you can programmatically control each tooltip using JavaScript.

    Example:

    // Get a reference to the Tooltip AccDC Object using the ID  stored in the tooltipId variable
    var dc = $A.reg[tooltipId];
    
    // Now change the content of the tooltip
    dc.source = 'Hello World';
    
    // All other AccDC API properties and methods can be applied here as well.
    

    Styling

    The sample tooltips in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.

    When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled tooltip will be accessible.

    Bootstrapping

    Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.

    The tooltips within the Bootstrap folders are configured using HTML5 "data-" attributes within the HTML markup.

    When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class "accTooltip", then configures the same module declaration as previously described using these HTML5 attributes.

    Available HTML5 attributes:

    • data-src : The resource path and pointer to the ID attribute of the tooltip container element. If set, data-internal should be blank or not included.
    • data-internal : The ID attribute of the tooltip container element within the same document. If data-internal is set, data-src should be blank or not included.
    • data-role : The role name that is conveyed to screen reader users as beginning and ending boundary text for the new content. "Tooltip" is set by default if no value is specified.
    • data-autoposition : The autoPosition override, which dynamically positions the new content relative to the triggering element. This reflects the autoPosition property documented within AccDC, and may be a value between 0 and 12. The default is 3 if left blank or not included.
    • data-offsetleft : The offsetLeft override, which dynamically positions the new content relative to the triggering element. The default is 10 if left blank or not included.
    • data-offsettop : The offsetTop override, which dynamically positions the new content relative to the triggering element. The default is 0 if left blank or not included.

    Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".

    Required attributes:

    • class="accTooltip" : The bootstrap class name that specifies an accessible tooltip.
    • id : The unique ID of the element. This value is also registered as the ID of the Tooltip AccDC Object, making it possible to invoke the object programmatically.
      E.G $A.reg.uniqueID.open();
      // All other AccDC API properties and methods are similarly available.

    Implementation Notes

    When an A tag is used as the triggering element, it must adhere to the following:

    1. If the element contains no link text and no Img element, then the link should include an informative Title attribute. (This is only valid if there is no link text at all)
    2. If the element contains an Img tag and no link text, then the Img tag should include an informative Alt attribute and Title attribute, both of which should match.
    3. The A tag must include an href attribute, to ensure keyboard accessibility.

    Do not use aria-haspopup.

    It might sound like a good idea to notify screen reader users that a 'Popup' is attached by adding the attribute aria-haspopup="true" to the triggering element, but this is not a good idea.

    Screen readers announce different feedback based on the various combinations of element types and ARIA roles in the markup, which can lead to confusion and misrepresent the purpose of the feature altogether.

    Examples:

    <!-- Triggering Element One
    JAWS 13 and 14 announces as "Has Popup"
    NVDA2013 announces as "SubMenu"
    -->
    
    <a href="#" aria-haspopup="true"> Triggering Element One </a>
    
    <!-- Triggering Element Two
    JAWS 13 and 14 announces as "Menu"
    NVDA2013 announces as "Menu Button SubMenu"
    -->
    
    <a href="#" role="button" aria-haspopup="true"> Triggering Element Two </a>
    
    <!-- Triggering Element Three
    JAWS 13 and 14 announces as "Menu"
    NVDA2013 announces as "Menu Button SubMenu"
    -->
    
    <button aria-haspopup="true"> Triggering Element Three </button>
    

    In short, don't use aria-haspopup unless you are triggering a menu.

    The concept of Web Chat seems complicated, but it's actually quite easy to make accessible for screen reader and keyboard only users.

    This may not be readily apparent by reading the JavaScript code for the chat demo in the Coding Arena however, so I'll outline the concepts that make it accessible here, to simplify things.

    1. When the chat popup loads in the DOM, the content is appended to the 'BODY' element, so that it appears at the bottom of the page for screen reader users. This is important, because as new messages are received, the Virtual Buffer line numbers within the body content won't change. This is often what causes focus reading issues when trying to navigate within body content if nodes higher up in the DOM tree continually update themselves, which quickly becomes an accessibility issue.
    2. After the chat popup is rendered, focus is automatically moved into the message field. To aid with this, the surrounding DIV tag for the message field, includes the ARIA attribute role="application". This forces JAWS 14 to automatically enter Applications Mode when the field receives focus in both IE and Firefox.
    3. The message field consists of a Textarea element. This is important, since this allows screen reader users to press Enter to submit new messages without automatically exiting Forms Mode, which would occur if an Input element was used instead.
    4. The scrollable chat window is keyboard accessible, so that keyboard only users can simply Shift+Tab into the message field and use the Up/Down arrow keys and the PageUp/PageDown/Home/End keys to read through previously posted messages.
    5. The Close icon is keyboard accessible, and pressing Escape will alternately close the Chat Popup.
    6. Now, here is where the magic is for screen reader users. Whenever new messages arrive, they are automatically announced. This is accomplished using the $A.announce() method, which automatically queues incoming messages using Unobtrusive Announcement to prevent speech interruption. It also can be set to ignore repetitive messages by passing true as the second parameter.

      Example:

      $A.announce(LastMSG-DOM-Node, true);
      

    The $A.announce() method is also prototyped to the String object, so it can be invoked by returning strings as well for storage if desired.

    Example:

    var msgHistory = [],
    msgTextString = 'Howdy!';
    
    msgHistory.push( msgTextString.announce() );
    

    Which will both store the string contained in the variable msgTextString and announce it to screen reader users at the same time.

    When a chat dialog is closed, the following method may be invoked:

    String.announce.clear();
    

    This will clear the queue so that message announcement does not continue to occur after the chat dialog is closed.

    Announce Method Details

    The AccDC Announce method has been tested successfully using JAWS 11-14, NVDA, and VoiceOver, in Internet Explorer 8-9, Firefox, Chrome, and Safari with applicable screen readers.

    JavaScript

    $A.announce( StringOrDOMNode , SuppressRepeat?<true/false> , isAggressive?<true/false> );
    

    Or

    var myString = anotherString.announce();
    

    $A.announce() Parameters

    1. The first parameter is a DOM node or text string to be announced. (Repetitive messages will automatically be queued for announcement.)

    2. The second parameter is a Boolean value that specifies whether the announcement of repeat message text is automatically suppressed. If set to true, repetitive text will not be announced to screen reader users. False is set by default if no value is specified.

    3. The third parameter is a Boolean value that specifies whether aggressive announcement will be used to announce text. If set to true, prior speech output will be interrupted and the latest text message will be forcibly announced. This will occur regardless which window currently has focus, and is not desirable in most cases. False is set by default if no value is specified.

    Programmatic Control

    Manually clear the message queue

    String.announce.clear();
    

    Access the last message that was announced

    var last = String.announce.lastMsg;
    

    Adjust the initial delay in milliseconds when the $A.announce() method queues messages to be announced sequentially

    String.announce.baseDelay = 2000;
    

    Adjust the delay in milliseconds when a message using $A.announce() contains two or more words including punctuation.

    String.announce.charMultiplier = 160;
    

    Implementation Notes

    Important: Unobtrusive Announcement should only be used sparingly, and not for everything.

    When too many things are announced on the same page, it is difficult for screen reader users to differentiate between what is being announced, and what is being navigated using the arrow keys. This is because the same voice is used for both, with no distinction.

    ARIA Warnings

    Even though ARIA stands for Accessible Rich Internet Applications, the improper use of ARIA will actually cause accessibility issues for screen reader users.

    Important things to be aware of:

    • Strict care and comprehensive screen reader testing must always be applied whenever implementing ARIA within HTML markup.
    • Don't ever assume, just because it's documented in the ARIA specification, that it will be accessible.
    • If the component or feature is not accessible to screen reader users, it is not accessible, no matter what the specification says.
    • Adherence to the ARIA specification cannot be used as an excuse for components and features that are not accessible to screen reader users.
    Improper use of ARIA examples

    Example 1: Phantom form fields

    <form>
    <div id="lgnd">
    Contact Details
    </div>
    <div role="textbox" aria-label="Your full name" aria-required="true" aria-describedby="lgnd">
    <input type="text" name="full_name" />
    </div>
    <div role="textbox" aria-label="Your email address" aria-required="true" aria-describedby="lgnd">
    <input type="text" name="email_address" />
    </div>
    </form>
    

    Since the use of role="textbox" is used to surround a native form field, JAWS sees two form fields when using the Arrow keys to navigate up and down the page, causing confusion for screen reader users.

    Similarly, since all supporting attributes such as aria-label, aria-describedby, and aria-required are applied to the wrong elements, they are not accessible as a result.

    Example 2: Unreadable content

    <table role="tree">
    <tr role="treeitem">
    <td>
    Name:
    </td>
    <td>
    Bryan Garaventa
    </td>
    </tr>
    <tr role="treeitem">
    <td>
    Title:
    </td>
    <td>
    Bryan Garaventa - Resume
    </td>
    </tr>
    <tr role="treeitem">
    <td>
    File Type:
    </td>
    <td>
    PDF
    </td>
    </tr>
    </table>
    

    The use of role="tree" and role="treeitem" on this table, literally makes it impossible to read the table content using JAWS.

    Example 3: Mixing roles

    <div role="tablist">
    <div role="tab">
    <h2>
    <a href="#"> Link One </a>
    </h2>
    </div>
    <div role="tab">
    <h2>
    <a href="#"> Link Two </a>
    </h2>
    </div>
    <div role="tab">
    <h2>
    <a href="#"> Link Three </a>
    </h2>
    </div>
    </div>
    

    Since screen readers convey certain role types (such as Tabs) as form controls, the nesting of additional active elements confuses screen reader output.

    Example 4: Confusing feedback

    <textarea title="Status" aria-haspopup="true"></textarea>
    
    <textarea title="Comment" aria-expanded="true"></textarea>
    

    In the case of aria-haspopup on the edit field, only "Has Popup" is announced by JAWS, which is confusing. "Has Popup" does not convey what the purpose of the popup is, nor does it indicate how to invoke it. NVDA announces "Edit SubMenu", which is even more confusing.

    In the case of aria-expanded on the edit field, "Edit Expanded" is announced by screen readers, which is superfluous. The content of all edit fields, even when scrolled off screen visually, is always visible to screen reader users, so announcing expanded means nothing to screen reader users.

    Care must be taken with incorrect assumptions, such as the assumption that applying aria-disabled="true" to an element will remove it from the focus order or that doing so will prevent JavaScript events such as onFocus or onClick from firing on that element. These are incorrect assumptions, because ARIA does not change the behavior in the browser, only what type of information is conveyed to assistive technologies.

    Also great care must be taken when applying global attributes, such as aria-hidden. The aria-hidden attribute when set to 'true' will hide that element and all child elements from assistive technology users, regardless that the content is still visible. Moreover, if the container also includes focusable elements, these will remain in the tab order regardless. When aria-hidden is set to "false", even on an element that is hidden using the HTML5 'hidden' attribute or CSS display:none, it will be exposed to assistive technology users regardless, which can be extremely problematic if misapplied on elements that are meant to be hidden from all users.

    For a comprehensive guide of how ARIA works from beginning to end, please read the Accessibility Tree Training Guide.

    Also, use the Visual ARIA Bookmarklet to examine ARIA usage within live web technologies to better understand which ARIA attributes are present and when they are being applied incorrectly.

    Conclusion

    Whenever ARIA is applied, it must be thoroughly tested using JAWS in Internet Explorer and using NVDA in Firefox. These are the two most widely used Windows based screen readers in the world. JAWS is hard coded to work best in Internet Explorer, and NVDA is hard coded to work best in Firefox.

    If mobile support is needed, VoiceOver on iOS devices is the most widely used screen reader that should be used for testing. TalkBack on the Android is the second most widely used.

    Important: Even when ARIA is implemented correctly and precisely according to the specification, if adding certain ARIA attributes causes accessibility issues for screen reader users to occur, then they should not be used.

    The attribute aria-haspopup should only be used on triggering elements that open menus. Otherwise, the presence of the attribute will only misrepresent the popup type to screen reader users.

    Examples:

    <!-- Triggering Element One
    JAWS 13 and 14 announces as "Has Popup"
    NVDA2013 announces as "SubMenu"
    -->
    
    <a href="#" aria-haspopup="true"> Triggering Element One </a>
    
    <!-- Triggering Element Two
    JAWS 13 and 14 announces as "Menu"
    NVDA2013 announces as "Menu Button SubMenu"
    -->
    
    <a href="#" role="button" aria-haspopup="true"> Triggering Element Two </a>
    
    <!-- Triggering Element Three
    JAWS 13 and 14 announces as "Menu"
    NVDA2013 announces as "Menu Button SubMenu"
    -->
    
    <button aria-haspopup="true"> Triggering Element Three </button>
    

    The attribute role="presentation" should only be used in very limited circumstances, and only when it is desirable to suppress the role of an element for screen reader users.

    Many element types have particular roles that are automatically conveyed to screen reader users.

    Examples include headings, links, buttons, images, lists, frames, tables, form fields, and many others. All of which have specific relevance for screen reader users, who depend on the identification of these roles to navigate reliably within web pages.

    When role="presentation" is added to the markup of such an element, it manually overrides this role mapping in the browser, and prevents the screen reader from identifying or even interacting with the element in the expected manner.

    Example 1: Headings

    <h2 role="presentation"> Key Section Heading </h2>
    

    It is now impossible for screen reader users to navigate to the heading using the H and Shift+H key commands, nor is the text identified as a heading while browsing down the page using the arrow keys.

    Example 2: Links and Buttons

    <a href="#" role="presentation"> Triggering Element </a>
    
    <button role="presentation"> Triggering Element </button>
    

    It is now impossible for screen reader users to identify these elements as actionable elements during navigation.

    Example 3: Tables

    <table role="presentation">
    <tr>
    <th scope="col">
    Product
    </th>
    <th scope="col">
    Quantity
    </th>
    </tr>
    <tr>
    <td>
    Doorknob
    </td>
    <td>
    2000
    </td>
    </tr>
    </table>
    

    It is now impossible for screen reader users to navigate the data table using table navigation commands.

    Whenever role="presentation" is added to HTML markup, it must always be tested using JAWS, NVDA, and VoiceOver (if applicable) to ensure that the element type remains accessible for screen reader users.

    Event Model Differences

    When JAWS interacts with the Virtual Buffer, making it possible for screen reader users to navigate from the top of the page to the bottom using the Down arrow key, it will not automatically trigger the onFocus handler.

    When you do the same using NVDA however, it will automatically trigger the onFocus handler.

    This means that, any elements that cause specific actions to occur, such as simulated Tab controls, simulated Radio Button controls, or any other control type that uses onFocus to invoke selection, will automatically be triggered by NVDA in both IE and Firefox when using the arrow keys to navigate page content.

    Example 1: Tabs

    <div role="tablist">
    <div role="tab" tabindex="0" onfocus="alert('Switch content 1');"> Label One </div>
    <div role="tab" tabindex="-1" onfocus="alert('Switch content 2');"> Label Two </div>
    <div role="tab" tabindex="-1" onfocus="alert('Switch content 3');"> Label Three </div>
    </div>
    

    In JAWS, you can use the arrow keys to navigate between tabs and press Enter on the announced tab to activate it.

    In NVDA however, using the arrow keys to announce each tab will automatically activate it.

    Example 2: Implied form field labels

    <input type="text" value="Street Address 1" onfocus="this.value=''" /><br />
    <input type="text" value="Street Address 2" onfocus="this.value=''" /><br />
    <input type="text" value="City" onfocus="this.value=''" /><br />
    <input type="text" value="State" onfocus="this.value=''" />
    

    In JAWS, setting focus to the Input field will cause the value to be cleared.

    In NVDA however, using the arrow keys to navigate down the page will cause the form fields to be cleared.

    Important: This method of form field labeling should never be used.

    The events that are triggered for certain elements depend on the type of element that is being activated.

    For example, adding an onClick handler to a natively active element such as an A tag with an href attribute, or a BUTTON element, will be accessible for both mouse and keyboard users, regardless whether a screen reader is running or not.

    However, if you do the same for a natively non-active element, such as a DIV or SPAN tag, it will not be accessible from the keyboard without a screen reader running.

    Example 1: Standard link

    <a href="#" onclick="alert('Clicked');" > Triggering Element </a>
    

    This link is actionable from the keyboard with or without a screen reader running, and can be activated using the mouse.

    Example 2: Simulated link with no onKeypress

    <span role="link" tabindex="0" onclick="alert('Clicked');" > Triggering Element </span>
    

    This simulated link is actionable from the mouse, and for screen reader users in Virtual Buffer Mode. However, it is not actionable for keyboard only users that have no screen reader running, nor is it actionable for screen reader users in Applications Mode.

    Example 3: Simulated link with both onClick and onKeypress

    <span role="link" tabindex="0" onkeypress="kpHandler(this, event);"
    onclick="alert('Clicked');" > Triggering Element </span>
    <script type="text/javascript">
    function kpHandler(obj, ev){var k = ev.which || ev.keyCode; if (k == 13)alert('Pressed');}
    </script>
    

    This simulated link is actionable from the mouse and from the keyboard with or without a screen reader running. However, the onKeypress is only activated for screen reader users in Applications Mode, and for keyboard only users, and the onClick is only activated for mouse users, and for screen reader users in Virtual Buffer Mode.

    Many accessibility issues arise when nesting active elements, which directly effects event propagation.

    Example: Nested active elements

    <div role="link" tabindex="0" onkeypress="kpHandler(this, event);"
    onclick="alert('DIV clicked');" >
    <img
    alt="Triggering element"
    src="icon.png"
    onclick="alert('IMG clicked');"
    />
    </div>
    <script type="text/javascript">
    function kpHandler(obj, ev){var k = ev.which || ev.keyCode; if (k == 13)alert('DIV pressed');}
    </script>
    

    This simulated image link performs different actions depending on the action mode (mouse or keyboard), and also depending on the browse mode for screen reader users.

    • Mouse users will trigger the onClick for both the IMG and DIV, but not the onKeypress.
    • Keyboard only users without a screen reader will trigger the DIV onKeypress, but neither of the onClicks.
    • Screen reader users in Virtual Buffer Mode will trigger the onClick for both the IMG and DIV, but not the onKeypress.
    • Screen reader users in Applications Mode will trigger the DIV onKeypress, but neither of the onClicks.

    It is, therefore, very important to ensure that nested active elements are not used to perform different actions.