Skip to content

Instantly share code, notes, and snippets.

@federicofazzeri
Last active February 21, 2017 14:58
Show Gist options
  • Save federicofazzeri/68fcb13be7b4d9cdb9e998386556bd58 to your computer and use it in GitHub Desktop.
Save federicofazzeri/68fcb13be7b4d9cdb9e998386556bd58 to your computer and use it in GitHub Desktop.
aria-live-announcements an angular service for running aria live announcements Take a look at example.html for an example of how to use it in a directive
(function(window, angular) {
'use strict';
/**
*
* The `ariaLive` module provides a service for running aria live announcements.
* It creates an empty paragraph only "visible" to screen readers.
*
*/
var ariaLive = angular.module('ariaLive', []);
var jqLite = angular.element;
ariaLive.service('AriaLiveSrv', AriaLiveSrv);
AriaLiveSrv.$inject = ['$timeout', '$document'];
function AriaLiveSrv($timeout, $document) {
this.init = function (msgs, ele, msgContainerClass, politeness, hideElement) {
this.msgs = stingToObj(msgs);
this.element = $document;
if (ele) {
if(ele.nodeName){
this.element = jqLite(ele);
}else if(ele[0] && ele[0].nodeName){
this.element = ele;
}
}
this.element.append('<p aria-live="'+(politeness || 'polite')+'"></p>');
this.mgsContainer = jqLite(this.element[0].lastChild);
if (msgContainerClass) {
this.mgsContainer.addClass(msgContainerClass);
}
if (hideElement) {
/*visually hides the element (still available for screen readers)*/
this.mgsContainer.css({
'position': 'absolute',
'margin-left': '-10000px',
'top': '-999999px',
'left': '-999999px'
});
}
};
this.announce = function(msg){
if(this.msgs[msg]){
$timeout().then(function(){
jqLite(this.mgsContainer).text(this.msgs[msg]);
}.bind(this));
}
};
}
function stingToObj(msgs) {
if ( !msgs || msgs.indexOf(':') < 0 ) {
throw 'supply at least one valid message';
}
return msgs.split(',').reduce(function(prev, cur){
var msg = cur.split(':');
if(msg.length < 2) {
return prev;
}
prev[msg[0]] = msg[1];
return prev;
}, {});
}
})(window, window.angular);
<!DOCTYPE html>
<html>
<head>
<script src="angular.min.js"></script>
<script src="angular.aria-live.js"></script>
<script>
angular.module('myApp', ['ariaLive'])
.directive('ariaLiveMsg', function ariaLiveMsg(AriaLiveSrv) {
return {
link: function (scope, element, attr) {
var ariaSrv = Object.create(AriaLiveSrv);
var buttons = element.find('button');
ariaSrv.init(
attr.msgs,
element,
attr.msgContainerClass,
attr.politeness,
attr.hideElement
);
Array.prototype.forEach.call(buttons, function(button){
angular.element(button).on('click', function (ev) {
ariaSrv.announce(button.id);
});
});
}
};
});
</script>
<style>div { outline: 1px solid red; padding: 10px; }</style>
<meta charset="utf-8">
<title>aria live</title>
</head>
<body ng-app="myApp">
<div data-aria-live-msg
data-msgs="firstMsg:first message announced,secondMsg:second message announced"
msg-container-class="aria-live",
politeness="assertive",
hide-element="true">
<button id="firstMsg">first message</button>
<button id="secondMsg">second message</button>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment