From d0458ca22c815e8bd158df4edf07eb83141439ed Mon Sep 17 00:00:00 2001 From: Allan Jardine Date: Sat, 10 Dec 2011 11:34:30 +0000 Subject: [PATCH] First effort at ARIA support - the table control widgets link themselves to the table now ('controls') and the column headers say what they do. The table is also described by the information control. Note that an ID on the table is needed for most of this, since ARIA can reiference elements. --- media/js/jquery.dataTables.js | 44 +++++++++++++++++++++++++++--- media/src/core/core.constructor.js | 2 ++ media/src/core/core.draw.js | 10 ++++++- media/src/core/core.filter.js | 7 ++++- media/src/core/core.info.js | 1 + media/src/core/core.length.js | 6 ++++ media/src/core/core.sort.js | 11 ++++++++ media/src/ext/ext.paging.js | 7 +++-- 8 files changed, 80 insertions(+), 8 deletions(-) diff --git a/media/js/jquery.dataTables.js b/media/js/jquery.dataTables.js index c8d07e51..bb8efbc2 100644 --- a/media/js/jquery.dataTables.js +++ b/media/js/jquery.dataTables.js @@ -1070,7 +1070,14 @@ { nTh = oSettings.aoColumns[i].nTh; nTh.setAttribute('tabindex', '0'); - + nTh.setAttribute('role', 'columnheader'); + + nTh.setAttribute('aria-label', 'Activate to sort column'); + if ( oSettings.sTableId ) + { + nTh.setAttribute('aria-controls', oSettings.sTableId); + } + if ( oSettings.aoColumns[i].sClass !== null ) { $(nTh).addClass( oSettings.aoColumns[i].sClass ); @@ -1720,6 +1727,7 @@ */ oSettings.nTableWrapper = document.createElement( 'div' ); oSettings.nTableWrapper.className = oSettings.oClasses.sWrapper; + oSettings.nTableWrapper.setAttribute('role', 'grid'); if ( oSettings.sTableId !== '' ) { oSettings.nTableWrapper.setAttribute( 'id', oSettings.sTableId+'_wrapper' ); @@ -2018,7 +2026,12 @@ } ); } } ); - + + if ( oSettings.sTableId ) + { + jqFilter.attr('aria-controls', oSettings.sTableId); + } + jqFilter.bind( 'keypress.DT', function(e) { /* Prevent default */ if ( e.keyCode == 13 ) @@ -2372,6 +2385,7 @@ if ( oSettings.sTableId !== '' ) { nInfo.setAttribute( 'id', oSettings.sTableId+'_info' ); + oSettings.nTable.setAttribute( 'aria-describedby', oSettings.sTableId+'_info' ); } } @@ -2699,6 +2713,12 @@ _fnDraw( oSettings ); } ); + + + if ( oSettings.sTableId ) + { + $('select', nLength).attr('aria-controls', oSettings.sTableId); + } return nLength; } @@ -3890,6 +3910,17 @@ { _fnSortingClasses( oSettings ); } + + for ( i=0, iLen=oSettings.aoColumns.length ; i 0 ) + { + var aAriaSort = aaSort[0] + oSettings.aoColumns[aAriaSort[0]].nTh.setAttribute('aria-sort', + aAriaSort[1]=="asc" ? "ascending" : "descending" ); + } /* Tell the draw function that we have sorted the data */ oSettings.bSorted = true; @@ -6325,6 +6356,8 @@ this.appendChild( tbody[0] ); } oSettings.nTBody = tbody[0]; + oSettings.nTBody.setAttribute( "aria-live", "polite" ); + oSettings.nTBody.setAttribute( "aria-relevant", "all" ); var tfoot = $(this).children('tfoot'); if ( tfoot.length > 0 ) @@ -9918,8 +9951,8 @@ }; var sAppend = (!oSettings.bJUI) ? - '
'+oLang.sPrevious+'
'+ - '
'+oLang.sNext+'
' + '
'+oLang.sPrevious+'
'+ + '
'+oLang.sNext+'
' : '
'+ '
'; @@ -9950,6 +9983,9 @@ nPaging.id = oSettings.sTableId+'_paginate'; nPrevious.id = oSettings.sTableId+'_previous'; nNext.id = oSettings.sTableId+'_next'; + + nPrevious.setAttribute('aria-controls', oSettings.sTableId); + nNext.setAttribute('aria-controls', oSettings.sTableId); } }, diff --git a/media/src/core/core.constructor.js b/media/src/core/core.constructor.js index 9be9c8d5..daae1af2 100644 --- a/media/src/core/core.constructor.js +++ b/media/src/core/core.constructor.js @@ -402,6 +402,8 @@ if ( tbody.length === 0 ) this.appendChild( tbody[0] ); } oSettings.nTBody = tbody[0]; +oSettings.nTBody.setAttribute( "aria-live", "polite" ); +oSettings.nTBody.setAttribute( "aria-relevant", "all" ); var tfoot = $(this).children('tfoot'); if ( tfoot.length > 0 ) diff --git a/media/src/core/core.draw.js b/media/src/core/core.draw.js index a8a7358d..f83678db 100644 --- a/media/src/core/core.draw.js +++ b/media/src/core/core.draw.js @@ -97,7 +97,14 @@ function _fnBuildHead( oSettings ) { nTh = oSettings.aoColumns[i].nTh; nTh.setAttribute('tabindex', '0'); - + nTh.setAttribute('role', 'columnheader'); + + nTh.setAttribute('aria-label', 'Activate to sort column'); + if ( oSettings.sTableId ) + { + nTh.setAttribute('aria-controls', oSettings.sTableId); + } + if ( oSettings.aoColumns[i].sClass !== null ) { $(nTh).addClass( oSettings.aoColumns[i].sClass ); @@ -747,6 +754,7 @@ function _fnAddOptionsHtml ( oSettings ) */ oSettings.nTableWrapper = document.createElement( 'div' ); oSettings.nTableWrapper.className = oSettings.oClasses.sWrapper; + oSettings.nTableWrapper.setAttribute('role', 'grid'); if ( oSettings.sTableId !== '' ) { oSettings.nTableWrapper.setAttribute( 'id', oSettings.sTableId+'_wrapper' ); diff --git a/media/src/core/core.filter.js b/media/src/core/core.filter.js index 73ea6102..b22cef55 100644 --- a/media/src/core/core.filter.js +++ b/media/src/core/core.filter.js @@ -44,7 +44,12 @@ function _fnFeatureHtmlFilter ( oSettings ) } ); } } ); - + + if ( oSettings.sTableId ) + { + jqFilter.attr('aria-controls', oSettings.sTableId); + } + jqFilter.bind( 'keypress.DT', function(e) { /* Prevent default */ if ( e.keyCode == 13 ) diff --git a/media/src/core/core.info.js b/media/src/core/core.info.js index 16951bb0..cbe67af8 100644 --- a/media/src/core/core.info.js +++ b/media/src/core/core.info.js @@ -24,6 +24,7 @@ function _fnFeatureHtmlInfo ( oSettings ) if ( oSettings.sTableId !== '' ) { nInfo.setAttribute( 'id', oSettings.sTableId+'_info' ); + oSettings.nTable.setAttribute( 'aria-describedby', oSettings.sTableId+'_info' ); } } diff --git a/media/src/core/core.length.js b/media/src/core/core.length.js index 45670456..b2d17d06 100644 --- a/media/src/core/core.length.js +++ b/media/src/core/core.length.js @@ -85,6 +85,12 @@ function _fnFeatureHtmlLength ( oSettings ) _fnDraw( oSettings ); } ); + + + if ( oSettings.sTableId ) + { + $('select', nLength).attr('aria-controls', oSettings.sTableId); + } return nLength; } diff --git a/media/src/core/core.sort.js b/media/src/core/core.sort.js index c9b36e52..0b92a984 100644 --- a/media/src/core/core.sort.js +++ b/media/src/core/core.sort.js @@ -127,6 +127,17 @@ function _fnSort ( oSettings, bApplyClasses ) { _fnSortingClasses( oSettings ); } + + for ( i=0, iLen=oSettings.aoColumns.length ; i 0 ) + { + var aAriaSort = aaSort[0] + oSettings.aoColumns[aAriaSort[0]].nTh.setAttribute('aria-sort', + aAriaSort[1]=="asc" ? "ascending" : "descending" ); + } /* Tell the draw function that we have sorted the data */ oSettings.bSorted = true; diff --git a/media/src/ext/ext.paging.js b/media/src/ext/ext.paging.js index 0f93a0f0..b371ef86 100644 --- a/media/src/ext/ext.paging.js +++ b/media/src/ext/ext.paging.js @@ -31,8 +31,8 @@ $.extend( DataTable.ext.oPagination, { }; var sAppend = (!oSettings.bJUI) ? - '
'+oLang.sPrevious+'
'+ - '
'+oLang.sNext+'
' + '
'+oLang.sPrevious+'
'+ + '
'+oLang.sNext+'
' : '
'+ '
'; @@ -63,6 +63,9 @@ $.extend( DataTable.ext.oPagination, { nPaging.id = oSettings.sTableId+'_paginate'; nPrevious.id = oSettings.sTableId+'_previous'; nNext.id = oSettings.sTableId+'_next'; + + nPrevious.setAttribute('aria-controls', oSettings.sTableId); + nNext.setAttribute('aria-controls', oSettings.sTableId); } },