Angular Project Blackjack: 13 – External Module, Keyboard

Keyboard support has been requested MULTIPLE TIMES from my friend @mhmazur during the development process. I figured it was finally time to fill his feature request.

The Search

Since I’ve never done any sort of keyboard support in angular, I set out to see how everyone else is doing it. The first thing I came across was the ngKeyup directive. This would do what I needed. It allows you to watch for keyboard presses and react to them.

I set about implementing it by adding the directive to game.directive.html. Unfortunately, while it worked the way we would want it, there was one major issue, it required a click. Yes, having the app loaded in the browser, when you start typing, ngKeyup does not register. The directive that we put keyup on must be selected. I imagine because ngKeyup was meant for more input type elements. On to the next plan of attack.

The Search Continues

One of the big external modules I came across was Angular Hotkeys. Diving into the source code I find that it utilizes Mousetrap, a popular js library for keyboard handling. At this point I was considering two options: write Mousetrap functionality into my app or just use Angular Hotkeys. I went with option two, knowing that if things didn’t work I could fall back to Mousetrap.

Bringing In the New

Up until now, all of our angular modules were of our own creation. We didn’t have any other real dependencies. Let’s change that now! First things first, install the package via bower:

$ bower install chieffancypants/angular-hotkeys --save

Next, we’ll require the lib as a dependency in our blackjack.module.js file:

angular.module('blackjack', [
'blackjack.card',
'blackjack.game',
'blackjack.player',
'blackjack.dealer',
'cfp.hotkeys'
]);

Now that we have our dependencies defined, we can inject hotkeys into any controller we need it. That controller for us is game.controller.js. As per the documentation, we setup the hot keys to do the functions that our game buttons do:

game.setupHotKeys = function(){
hotkeys.add({
combo: 's',
description: 'Press to Stay',
callback: function() {
if(game.buttonStayEnabled){
game.end();
}
}
});

hotkeys.add({
combo: 'h',
description: 'Press to Hit',
callback: function() {
if(game.buttonHitEnabled){
game.hit(true);
}
}
});

hotkeys.add({
combo: 'b',
description: 'Press to Bet',
callback: function() {
if(game.buttonBetEnabled){
game.deal();
}
}
});
};

One thing to notice is that we’re checking the button enabled status when the hot keys are pressed. We could probably do some double checking within the functions as well (but I haven’t yet).

Finishing Up

If you run the code now, you will see the hotkeys as being enabled! One thing that you will see is that our unit tests are now failing. We need to tell them to inject the hotkeys service in order to run. This is fairly trivial, but it will allow us to do complex things in the future like mocking hot keys.
game.controller.spec.js:

var gameController, CardService, PlayerService, DealerService, hotkeys;
beforeEach(function () {
module('blackjack.game');
module('blackjack.player');
module('blackjack.card');
module('blackjack.dealer');
module('cfp.hotkeys');
inject(function ($controller, _CardService_, _PlayerService_, _DealerService_, _hotkeys_) {
CardService = _CardService_;
PlayerService = _PlayerService_;
DealerService = _DealerService_;
hotkeys = _hotkeys_;
gameController = $controller('GameController', {
CardService: CardService,
PlayerService: PlayerService,
DealerService: DealerService,
hotkeys: hotkeys
});
});
});

Hot keys should now be enabled on our live site if you’d like to try them out!

Code for this post is available here.

Feel free to follow me/ask questions on twitter, @AdamWeeks

2 thoughts on “Angular Project Blackjack: 13 – External Module, Keyboard

  1. do you have the latest final code? I run on my laptop, have error ‘bundle.js not found’ and the game section doesn’t display. only nav bar show up.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s