Search code examples
angularjskeypress

AngularJS - Multiple keypress at the same time


I have the following $broadcast to catch keypresses in Angular:

$document.bind('keypress', function(event) {
    var key = event.which;
    $rootScope.$broadcast('keypress', event);
    $rootScope.$broadcast('keypress:' + key, event);
});

and I listen with $on

However, I want to detect when two keys are pressed at the same time, say enter and s are pressed at the same time (not a combination one one followed by another).

What is the best way of doing this?

EDIT

What I was thinking was to have:

var keys = [];
$document.bind('keydown', function(event) {
    keys[event.which] = true;
});
$document.bind('keyup', function(event) {
    delete keys[event.which];
});

$document.bind('keypress', function(event) {
    var key = event.which;
    var keysPressed = [];
    angular.forEach(keys, function(value, key) {
        keysPressed += 'keypress:' + key;
    });
    $rootScope.$broadcast('keypress', event);
    $rootScope.$broadcast(keysPressed, event);
});

So if I have multiple keypresses, then I create the correct $broadcast. The problem, however, becomes that the order matters now (i.e., if I press a then enter, then the $broadcast is keypress:58keypress:13 and if I press the other way, I get keypress:13keypress:58)


Solution

  • Broadcast is used way too much in my opinion. Instead, maybe use a custom directive? This is an example of user pressing down Shift+Tab and it fires an event like so:

    <input on-shift-tab="prevStep($event,'email')" />
    
    app.directive('onShiftTab', function() {
    return function(scope, element, attrs) {
        var map = {9: false, 16: false};
    
        element.on("keydown", function(event) {
            if (event.which in map) {
                map[event.which] = true;
                if (map[9] && map[16]) {
                    scope.$apply(function(){
                        scope.$eval(attrs.onShiftTab, {'$event': event});
                    });
                    event.preventDefault();
                }
            }
        });
        element.on("keyup", function(event) {
            if (event.which in map) {
                map[event.keyCode] = false;
            }
        });
    };
    })