7

I'm trying to create an interaction similar to the konami code "up,up,down,down,a,b,a,b, enter" -> something happens.

Is it possible to listen for arrow keyspress using ng-keypress? it seems to not work?

html:

input( ng-keypress='changed($event)'  )

Js

$scope.changed = (evt) ->
    console.log(evt)

this will not log out arrow key events?

Do I have to roll out my own listeners on the window? if so how can I achieve this in angular?

Armeen Moon
  • 18,061
  • 35
  • 120
  • 233

2 Answers2

22

DEMO

$scope.key = function($event){
    console.log($event.keyCode);
    if ($event.keyCode == 38)
        alert("up arrow");
    else if ($event.keyCode == 39)
        alert("right arrow");
    else if ($event.keyCode == 40)
        alert("down arrow");
    else if ($event.keyCode == 37)
        alert("left arrow");
}

EDIT

Change it from ng-keypress to ng-keydown. DEMO

<input ng-keydown="key($event)" />
Darshan P
  • 2,241
  • 18
  • 16
1

You could use a custom directive to listen for keydown and keypressed events. A possible implementation that i have tested is the following:

var app = angular.module('app', []);

// a helper service to detect the arrow keys from the key codes
app.factory('keys', function() {
    var keysEnum = { left: 37, up: 38, right: 39, down: 40 };
    var theKeys =  [ keysEnum.left, keysEnum.up, keysEnum.right, keysEnum.down ];
    function isIn(val) {
        var isin = false
        if (theKeys.indexOf(val) >= 0) {
            isin = true;
        }
        return isin;
    }
    function keyFromCode(code) {
        var key = 'unknown';
        switch (code) {
            case 37:
                key = 'left';
                break;
            case 38:
                key = 'up';
                break;
            case 39:
                key = 'right';
                break;
            case 40:
                key = 'down';
                break;
        }
        return key;
    }
    return {
        isIn: isIn,
        keyFromCode: keyFromCode
    };
});

// custom directive to detect the arrow key pressed
app.directive('keypressed', [ 'keys', function (keys) {
    return function (scope, element, attrs) {
        // listen for the events keydown, keypress
        element.bind("keydown keypress", function (event) {
            var code = event.which;
            // if an arrow key is pressed then do something
            if(keys.isIn(code)) {
                console.log(keys.keyFromCode(code));
            }
        });
    };
}]);

You could use the above directive like this:

<span ng-app="app">
    <input keypressed />
</span>

From the code that you posted it seems that you use an html template engine so in your case you could use the directive like this:

input( keypressed )