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
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.
LikeLike
The repo has been updated since this post came out. Be sure to check out the tagged commit specifically for this blog post at https://github.com/adamweeks/angular-blackjack/tree/blog-post-13
LikeLike