
Keypress: A Javascript library for capturing input - nsmalch
http://dmauro.github.io/Keypress/
======
pyalot2
Note that you should avoid using this (or anything else with JS) to emulate
shortcuts.

The reason is because what this usually looks like "oh nice I can define
shortcuts people can press". What it actually means is: "Ohcrap, that shortcut
only works for US-US 104 keyboard layouts, and about 80% of people can't press
that shortcut".

For example: suppose you want a shortcut for shift+/, which is for the US
keyboard under the small right finger. But that shortcut can't be defined for
SG (swiss-german) because there the / is on the numeric bar where 7 is. So if
you assume (for whatever reason) that left+right small finger is a convenient
shortcut, and left small finger + right index finger top isn't, then you're
totally screwed. Instead, to reach the right small finger low on swiss german,
you'd have to define shift + "-". Except that if you define that, it'll be one
of the most uncomfortable keyboard shortcuts imaginable for US users, which
find - on the numeric row top --> bottom left small finger + top right small
finger = ugh.

The truth is that you cannot do reasonable shortcut definition the way that
everybody would like to with JS... yet.

But wait, can't you like, define some reasonable presets and let people choose
their own? The answer is no, because you don't have a reliable way to
translate a keydown/keyup to a unicode char, and the unicode char is related
to the modifier keys, not the key cap, so though you can do that shortcut
definition, you can't show to the user what that shortcut definition actually
is, because it'd be either undefined or completely wrong.

I've written at length about this here:
[http://codeflow.org/entries/2013/jan/30/keyboard-events-
in-j...](http://codeflow.org/entries/2013/jan/30/keyboard-events-in-
javascript-are-broken/)

~~~
ville
> But wait, can't you like, define some reasonable presets and let people >
> choose their own? The answer is no, because you don't have a reliable way to
> > translate a keydown/keyup to a unicode char, and the unicode char is
> related > to the modifier keys, not the key cap, so though you can do that
> shortcut > definition, you can't show to the user what that shortcut
> definition actually > is, because it'd be either undefined or completely
> wrong.

But couldn't you let the user write the shortcut in a text field, capture the
keycodes from the keydown/keyup events and the char from the text field?

Edit: This obviously doesn't work for shortcuts that do not produce any text,
such as F-keys. But couldn't you at least get normal keys right most of the
time?

~~~
Groxx
That's kind of what I was thinking. Add to that a 20-questions thing to check
which keyboard layout they're using, and you can probably uniquely detect
almost every keyboard layout (minus custom, of course) in a couple keypresses.

But if you're going this far, you're probably significantly better off just
letting people remap their shortcuts if it doesn't match what 95% of your
users are using. The ones that care will love you for it, the ones that don't
probably wouldn't have used it or been interested in 20-questions anyway.

------
Stratoscope
This is such nice work that I hesitate to bring up a minor point of coding
style... But the use of names_with_underscores looks out of place in
JavaScript.

JavaScript code traditionally uses PascalCaseNames for constructors and
camelCaseNames for variables, properties, and methods. You do see
UPPERCASE_NAMES_WITH_UNDERSCORES used sometimes for "constants", but that's
about it.

Of course, names_with_underscores work just as well as any other names, and
some people use them in their own JavaScript code, but I think libraries
should follow the traditional native conventions of their language.

It would be like releasing a Ruby library that used camelCaseNames for its
method names. It would work, but many Ruby developers would feel that those
names were a bit out of place in a language where method names customarily use
underscores.

Mentioning it here basically just as a reminder for other library developers:
"When in Rome..."

~~~
ars
I don't think the language gets to decide the coding style. Only the
programmer gets to do that.

Especially if you program in multiple language it can be jarring to switch
styles for each language.

~~~
rtpg
I change keyboard layouts depending on (natural) language, though that's just
personal preference.

I think that flexibility of style has been getting less and less favor
recently : a lot of languages are starting to "force" some elements (such as
indentation) , and go has done the most intelligent thing ever and ships with
a formatter so that there's only 1 "right" way to write things.

Formatting issues is the source of so much bike-shedding, despite that it
really shouldn't be much of a productivity sink in 99.9% of situations.

------
stephen
Tangentially, can someone on the W3C please fix the sorry state of key
bindings across UAs?

Cross-browser idiosyncrasies are finally improving...except for webapp key
bindings. Alt-F is taken in IE, Ctrl-whatever is taken in other UAs. Or an
extension like (the awesome) vimium conflicts with some key bindings, so you
have to disable it all together.

To the point where Asana uses _tab_ as their short cut key. Tab! Wtf! "tab-p"
for project. Bizarre!

But I guess I can't blame them, as I wouldn't be surprised if it's the only
shortcut modifier that wasn't taken yet across all UAs.

I admittedly have no solutions to propose, so am just ranting about an
understandably hard problem...but it would be nice if someone came along and
fixed this. Please. :-)

~~~
Groxx
I think that Asana's aren't actually tab _and_ p, they're tab _then_ p. Or at
least that's true for all the ones I use. Given that, tab just takes focus out
of whatever default / current text field the cursor is in, so 'p' is
unambiguously a command and not a letter.

------
dpham
This looks like
[https://github.com/ccampbell/mousetrap](https://github.com/ccampbell/mousetrap)
I'm much more fond of the implicit syntax of mousetrap though.

~~~
dmauro
I have referred people to Mousetrap in the past that don't have need of some
of the more advanced features that Keypress offers. I wrote Keypress because
there was nothing to support some of the more complex, game-specific things I
wanted to do with keyboard combos.

------
paulirish
Obligatory link to the fantastic
[http://unixpapa.com/js/key.html](http://unixpapa.com/js/key.html)

~~~
gprasanth
Also this: [http://craig.is/killing/mice](http://craig.is/killing/mice)

------
aroman
Looks great. I was impressed that the keyboard visualization handled up to 7
simultaneous button pressed on my physical keyboard. Honestly, I wasn't aware
my keyboard's wiring (MacBook Air) was capable of handling that.

~~~
dpham
It doesn't have to do with hardware, it's just client-side implementation. I
had to write code for multiple key presses before. The browser will normally
trigger a keydown and keyup event whenever something is pressed and released.
The trick is to keep an array of keyCodes representing current keydowns;
during keydowns add to array and during keyups, remove from array.

~~~
anonova
It is hardware related. USB has a maximum rollover limitation of 6 keys + 4
modifiers. Though keyboards can have n-key rollovers (i.e., greater than 10
keys simultaneously), you have to use PS/2.

See
[https://en.wikipedia.org/wiki/Rollover_(key)](https://en.wikipedia.org/wiki/Rollover_\(key\))

~~~
ekns
I don't know the details, but it is possible for a USB keyboard to support
N-key rollovers. As an example:
[http://www.corsair.com/en/support/faq/vengeance-
gaming/](http://www.corsair.com/en/support/faq/vengeance-gaming/)

~~~
Groxx
Do they require custom drivers? I see no reason you can't have all-key
rollover with that, unless the OS refuses to do so.

Not that I'm saying you're _wrong_ , I really don't know if normal driverless
keyboard input is capable of this. I certainly hope so. I just see essentially
all 10-key rollover (or more) keyboards using PS/2 and citing that it doesn't
work through USB.

------
rcfox
Looks neat, but how do you write a keyboard input library with sequence combos
and then _not_ have the Konami code as a secret demo?

~~~
dmauro
Ha, fair point. I should get on that :)

------
whisk3rs
Nice. This seems to solve a common problem for developers building rich UIs.

On a similar topic, does anybody have any pointers for implementing keystroke-
by-keystroke character replacement in an INPUT box that doesn't suck? I'd like
users to be able to enter "townhall" but have the input value be "TOWNHALL"
and there doesn't seem to be a simple way to do this that doesn't fail when
the user uses the arrow key or wants to insert more than one character in the
middle of an input box.

~~~
redler
It's a bit of a workaround, but one approach is to split the problem into two
pieces: display and transmission. For display, you can avoid the cursor
problems by using:

    
    
      text-transform: uppercase;
    

It's simple, the user experience remains natural, and there are no JavaScript
dependencies. For the transmission phase, simply munge the actual entered
content (which will not be all uppercase unless the user enters it as such)
during the submit event. Of course you'll want to validate input on the server
side as well.

Edit: clarity.

------
Too
If you use this for hotkeys in your application make sure to return false or
set e.handled to true or something like that. I don't remember the exact
details right now.

Otherwise features from the browser like "incremental search" in firefox will
get priority over the key captures in your app. In fact _both_ your key
capture and the incremental search will trigger which is very frustrating as
the page starts scrolling to the first match of the letter you just typed.

But be very careful while doing this. Only do it for for your own hotkeys and
make sure they are not used for other hotkeys in most common browsers! If you
always swallow the keypress, normal hotkeys like ctrl+t for new tab will stop
working for the user also.

------
arnehormann
I built a demo with some similarities 7 month ago ( _EDIT_ \- that's not a
plagiarism charge, the OPs submission predates mine and was created a year
ago).
[https://gist.github.com/arnehormann/4163916](https://gist.github.com/arnehormann/4163916)
for the source and
[http://bl.ocks.org/arnehormann/raw/4163916/keycodes.html](http://bl.ocks.org/arnehormann/raw/4163916/keycodes.html)
for the demo. The code is documented and includes a konami code and a mode
switching example. It's set to a German Windows keyboard layout, but the code
includes comments on how to change that.

------
gren
I know the mess is in the OS-side but is there any chance we will have some
day a DOM API independent of the keyboard layout?

For instance you want to make a game using WSAD keys, well in a french
keyboard it's ZSQD... Also in a French keyboard, there some keys which trigger
the same keycode so you cannot differenciate them! (I think it was the comma
with something else)

If you want to make a software like Blender on the web which have a lot of key
shortcuts you are a bit screwed!

------
meemoo
My biggest issue is wanting to bind ctrl/meta-x/c/v to do what you think they
would do in my UI (a graph editor), but not do anything in input fields. I can
stopPropagation, but it is a pain to keep track of.

~~~
renekooi
You can attach an event to the window or some other higher-level element and
check if event.target is an input field... something along the lines of:

    
    
        document.body.addEventListener('keydown', function(e) {
          if (e.target.tagName !== 'INPUT') doKeyBindings();
        }, false);

------
ChristianBundy
This just looks like a development implementation of
[http://keycodes.atjayjo.com/](http://keycodes.atjayjo.com/)

------
osipovas
I see the potential for reading key presses when people are entering data into
a form. I look forwarding to investigating this. Thank you!

~~~
thenerdfiles
iPad keyboard data entry firm that farms keypresses via HTTP to solve newly
discovered cancer systems or other genetic puzzles.

At least give data enterers feedback, WPM, errors. Elderly can do data entry
while on a walk to the park, and afford their peppermints.

------
taspeotis
Is it meant to work with all the keys? Chrome 29:

> Open page

> Don't touch anything

> Type
    
    
        this is a test
    

> Now you've moved down three times.

~~~
guru1206
the spacebar makes the page scroll down

~~~
taspeotis
Yes, I have used a web browser before today.

It doesn't work unless you interact with elements on the page first, in which
case the library catches space.

Hence my instruction not to touch anything on the page.

~~~
dmauro
That doesn't seem to be the case for me. OS 10.8/Chrome 29.

------
agumonkey
pressing as many keys as possible makes me wonder how is wired my keyboard, I
can get all 8 'asdf' and 'uiop' in down state, but not 'asdf' 'hjkl' nor
'qwer' 'hjkl' .. funny

~~~
tydok
That's keyboard ghosting.

[http://en.wikipedia.org/wiki/Rollover_%28key%29#Key_jamming_...](http://en.wikipedia.org/wiki/Rollover_%28key%29#Key_jamming_and_ghosting)

[http://www.microsoft.com/appliedsciences/antighostingexplain...](http://www.microsoft.com/appliedsciences/antighostingexplained.mspx)

------
tommaxwell
Ooh, I could use this in a project I'm working on. Thanks!

------
frozenport
Pause/break not working in Firefox 24.0 on Windows x64 8.

------
dancecodes
suggestion: add to console echo when pressed something in your demo

------
RachelF
Looks great.

------
thenerdfiles
This will do to onscreen keyboards what Wordpress did to onscreen journals.

