Skip to content

Instantly share code, notes, and snippets.

@mkhatib
Created June 18, 2013 04:41
Show Gist options
  • Save mkhatib/5802718 to your computer and use it in GitHub Desktop.
Save mkhatib/5802718 to your computer and use it in GitHub Desktop.
Adds an AngularJS directive to add keyboard shortcuts for elements with ng-click directive.
var app = angular.module('app');
app.directive('mkShortcut', function($document) {
// Ref: http://goo.gl/7XDys
function fireEvent(element, event) {
if (document.createEvent) {
// dispatch for firefox + others
var evt = document.createEvent("HTMLEvents");
evt.initEvent(event, true, true ); // event type,bubbling,cancelable
return !element.dispatchEvent(evt);
} else {
// dispatch for IE
var evt = document.createEventObject();
return element.fireEvent('on'+event,evt)
}
}
function zeroIfNegative(num) { if (num < 0) return 0; return num; }
function isVisible(element) {
// Trying to determine if the element is currently visible on the screen.
// This is to allow the user assign the same shortcut for elements in
// different views. There's probably a better way to do this. But. Meh.
var elBound = element.getBoundingClientRect();
var docAtTopLeftBound = document.elementFromPoint(zeroIfNegative(elBound.left), zeroIfNegative(elBound.top));
var docAtBottomRightBound = document.elementFromPoint(zeroIfNegative(elBound.right), zeroIfNegative(elBound.bottom));
if (elBound.left == 0 && elBound.width == 0 && elBound.top == 0 && elBound.height == 0) return false;
return ((docAtTopLeftBound && (docAtTopLeftBound == element || docAtTopLeftBound.parentElement == element)) ||
(docAtBottomRightBound && (docAtBottomRightBound == element || docAtBottomRightBound.parentElement == element)));
}
return function(scope, element, attr) {
var shortcut = String(scope.$eval(attr.agShortcut));
var func = attr.ngClick;
// Adding a hiddlen span element inside that element. User can then decide what they want to do with it.
var span = document.createElement('span');
span.innerText = shortcut;
span.className = 'ag-shortcut';
span.style.display = 'none';
element[0].appendChild(span);
$document.bind("keyup", function(e) {
if(e.which === shortcut.charCodeAt(0) && isVisible(element[0])) {
fireEvent(element[0], 'click');
}
});
};
});
<!--
Usage: The following example adds shortcuts for each li element on the list.
-->
<ul class="items">
<li ng-repeat="item in items" ng-click="clickItem(item)" ag-shortcut="$index+1">
{{item}}
</li>
</ul>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment