Created
February 9, 2015 16:32
-
-
Save vadimpopa/b712f904449410acb123 to your computer and use it in GitHub Desktop.
angular keyboard select
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Usage: | |
* <div kb-select ng-model="items.selectedItem"> | |
* <div class="just-a-tag-with-a-class"></div> | |
* <my-data-row ng-repeat="item in items" entity="item"></my-data-row> | |
* </div> | |
*/ | |
function kbSelect() { | |
return { | |
restrict: 'EA', | |
controller: kbSelectController, | |
require: ['ngModel'], | |
link: kbSelectLink | |
}; | |
function kbSelectLink($scope, $element, $attributes, ctrls) { | |
var ngModelCtrl = ctrls[0]; | |
// Not needed, it's here in case will be needed | |
//$timeout(function () { | |
// if($scope.$$childTail.$last === true) { | |
// //ng repeat is ready we have access to items here | |
// } | |
//}); | |
// You can use ng-model to store the selected item, | |
// but from performance and utility point of view it's preferable a callback | |
// defined in controller where is your ITEMS model defined | |
$scope.setSelectionModel = function (value) { | |
ngModelCtrl.$setViewValue(value); | |
}; | |
} | |
} | |
kbSelectController.$inject = ['$scope', '$element', '$attrs', '$animate']; | |
function kbSelectController($scope, $element, $attrs, $animate) { | |
var selectedElement = $element, | |
selectedCls = $attrs.kbSelectedCls || 'kb-selected'; | |
$element.delegate('[entity]','click', onClick); | |
$element.delegate('[entity]','keydown', onKeyDown); | |
function onClick() { | |
var element = $(this); | |
//Clicked on child element | |
if(!element.attr('entity')) { | |
element = element.closest( "[entity]"); | |
} | |
select(element); | |
selectEntity(element); | |
$scope.$digest(); | |
} | |
function onKeyDown(e) { | |
// Up | |
if(e.which === 38) { | |
select(selectedElement.prev()); | |
} | |
// Down | |
else if (e.which === 40) { | |
select(selectedElement.next()); | |
} | |
// Enter or Space | |
else if(e.which === 32 || e.which === 13) { | |
select(selectedElement); | |
selectEntity(selectedElement); | |
} | |
$scope.$digest(); | |
} | |
function selectEntity(element) { | |
var localScope = element.scope(); | |
$scope.setSelectionModel(localScope[element.attr('entity')]); | |
} | |
function select(element) { | |
if(!element.attr('entity')) { | |
return; | |
} | |
// Remove previous element | |
if(selectedElement) { | |
$animate.removeClass(selectedElement, selectedCls); | |
} | |
// Update new selection | |
$animate.addClass(element, selectedCls); | |
selectedElement = element; | |
} | |
} | |
angular | |
.module('myapp.directives') | |
.directive('kbSelect', kbSelect); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment