Detecting mouse + keyboard events in Angular for ng-repeat

I have an application in which I generate a set of intervals using ng-repeat, and each range has a unique identifier (say span-{{$index}} ). Now I want to do the following:

  • If I click on a range, I want the space id to be copied. I managed to do this with ng-click.
  • I want to extend this functionality to detect multiple clicks in order to get an array of selected identifiers, but only if the CTRL key is held during clicks.

For example, if I had ctrl pressed when I selected span with id 1,3,5,7, then my array should have [1,3,5,7], but if I hadn’t had a key pressed CTRL, I should have only had [7] since this was the last selected range.

Also, can relative events be linked? For example. if I select span with id from 1, if I press CTRL + DOWN_ARROW , id 2 is also selected ... and then id 3 and so on until I press DOWN_ARROW .

I assume that the closest I saw in this type of UX is the selection of contacts in Gmail when creating new mail. I can select contacts using all kinds of keyboard and mouse combinations. I'm looking for something very similar

gmail screenshot

I play with various UX methods, but I am fixated on how exactly I could do this with angular.

+7
javascript angularjs angularjs-ng-repeat angularjs-directive
source share
2 answers

For your first question, see plunkr below.

If you pass $ event through the ng-click function, you can access the event in your controller. In my example, I checked if altKey was true, which checks if the Alt key was pressed at the same time as the button was pressed. You can also access ctrlKey, shiftKey and the mouse button pressed. See here the MouseEvent object - http://www.w3schools.com/jsref/dom_obj_event.asp

Controller:

 angular.module('exampleApp', []) .controller("ItemCtrl", function($scope){ $scope.items = [ {text: "Bob", id: 1}, {text: "Alice", id: 2}, {text: "Frank", id: 3}, {text: "Lisa", id: 4} ]; $scope.itemList = []; $scope.addItemIdToList = function(event, item){ if(event.altKey){ if(isItemInList(item)){ removeItemIdFromList(item); } else { addItemIdToList(item); } } else { addItemIdAsSingleSelection(item); } }; var isItemInList = function(item){ var indexOfItem = $scope.itemList.indexOf(item.id); return indexOfItem > -1; } var removeItemIdFromList = function(item){ var indexOfItem = $scope.itemList.indexOf(item.id); $scope.itemList.splice(indexOfItem, 1); }; var addItemIdToList = function(item){ $scope.itemList.push(item.id); }; var addItemIdAsSingleSelection = function(item){ $scope.itemList = [item.id]; }; }) 

http://plnkr.co/edit/RAX5oxkTomXxryp0sNNc

When logic starts to get a little more complicated, it would be best to do this in a directive.

In the second question, the main parts can be seen in the following example:

 angular.module('exampleApp', []) .directive('keypressEvents', function ($document, $rootScope) { return { restrict: 'E', link: function () { console.log('linked'); $document.on('keypress', function(e) { if(e.altKey){ var s = 223; var a = 229; if(e.which == s){ $rootScope.$broadcast("add_next_id"); } else if(e.which == a){ $rootScope.$broadcast("remove_last_id"); } } }) } } }) .controller("ItemCtrl", function($scope, $rootScope){ $scope.items = [ {text: "Bob", id: 1}, {text: "Alice", id: 2}, {text: "Frank", id: 3}, {text: "Lisa", id: 4} ]; $scope.itemList = [1]; $rootScope.$on('add_next_id', function (evt, obj, key) { $scope.$apply(function () { addNextId(); }); }); $rootScope.$on('remove_last_id', function (evt, obj, key) { $scope.$apply(function () { removeLastId(); }); }); var addNextId = function(){ var lastId = $scope.itemList[$scope.itemList.length - 1]; if(lastId < $scope.items.length){ $scope.itemList.push(lastId+1); } }; var removeLastId = function(){ if($scope.itemList.length > 1){ $scope.itemList.pop(); } }; $scope.isItemInList = function(item){ var indexOfItem = $scope.itemList.indexOf(item.id); return indexOfItem > -1; } }) 

http://plnkr.co/edit/PyyjfRMovygeq9qNbzWo

We listen to the document for keystrokes and again check for altKey. Then, if keyCode is one of our hotkeys, we send a message to $ rootScope using $ rootScope. $ Broadcast (), which the controller listens using the $ rootScope method. $ On ().

In the above example, alt + s will add more identifiers, and alt + a will remove them to the originally selected one.

+3
source share

Perhaps the Angular directive would be recommended. Here is an example of how you can capture meta-information using the Angular directive and access information inside the Angular controller ( Plnkr ):

 <!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> </head> <body ng-app="myapp" ng-controller="main"> <h1>Hello {{person}}</h1> <p>Ctrl: |{{info.ctrl}}|</p> <keyboard info="info"></keyboard> <script> var app = angular.module('myapp', []); app.controller('main', function($scope){ $scope.info = { ctrl: false }; $scope.person = "Me"; }); app.directive('keyboard', function($timeout){ return { scope: { info: '=' }, link: function(scope, element, attr){ console.dir(scope.info); $(document).on('keydown', function(e){ $timeout(function(){ scope.info.ctrl = e.ctrlKey; }); }); $(document).on('keyup', function(e){ $timeout(function(){ scope.info.ctrl = e.ctrlKey; }); }); } } }); </script> </body> </html> 
+2
source share

All Articles