I've written a text editor in JavaScript that draws directly to a Canvas element (for various reasons, but my primary reason is so I can slap that canvas onto a WebGL mesh as a texture). As a happy surprise, it's been easier to implement that any content-editable solutions I've found.
One thing I noticed early on were complaints from people with keyboard layouts other than en-US QWERTY that some keys were showing an incorrect letter. After some fiddling around with Windows' language settings and on-screen keyboard, I created a code-page based solution that maps keyCodes to character-strings for different locales directly, rather than just assuming "keyCode 51 with no modifier keys is the number 3". Because it's not, on some keyboards it's double-qoute.
But there are still some oddities. A few examples (note that all of these examples are based on using the Windows on-screen keyboard, so I'm only assuming this correlates with reality):
The first two problems are the biggest. I can figure out a solution to these if I just know what the behavior is supposed to be. The third issue will fit into my code-page system, though I'll have to change how I read modifier keys. The final issue, I could probably pay someone to cover.
And I'm fine with not being able to solve it for all users in all browsers 100% of the time. But most of the information I've ran across is basically "don't bother", which really only sounds more like "I don't know".
EDIT: selecting the layout isn't a concern. I provide it as an option to the user, if things aren't working for them. I think that's about the best thing one can do in this situation, but obviously I would auto-detect if I could. I'm really only concerned with getting the right behavior given that the right layout has already been chosen.
I would like to avoid anything involving the keyPress event, given that it isn't perfectly reliable. If I had a reliable source of data on keyboard layouts, it wouldn't be an issue.
There are three different keyboard events in JavaScript: keydown : Keydown happens when the key is pressed down, and auto repeats if the key is pressed down for long. keypress : This event is fired when an alphabetic, numeric, or punctuation key is pressed down. keyup : Keyup happens when the key is released.
The US-International keyboard uses the ', `, ~, ^, " as dead keys (highlighted in blue below), and uses Right-ALT plus !, ?, and a number of other keys to produce characters not normally available.
You can't get keyboard layout...
There's no way (with a pure JS solution) to detect the user's keyboard layout.
Note the "en-US" or "en-GB" doesn't map to any specific / agreed keyboard layout for those languages. The user's language is independent to how their keys map to a character.
You can make assumptions based on their locale / language code, but this doesn't offer any guarantee - it just increases the probability that you're catering for the appropriate layout.
Also see these questions:
Translate Javascript keyCode into charCode for non-U.S. keyboard layout (i.e. azerty)
Detect keyboard layout with javascript
...but you can get the character entered with it:
However, depending on your required browser support (which using canvas, should be quite good), you could try to use the charCode
property:
http://www.w3schools.com/jsref/event_key_charcode.asp
var unicodeCharCode = e.charCode;
Note that this will not return the actual character - you'll get the number representing it (NOT the key):
The Unicode character code is the number of a character (e.g. the number "97" represents the letter "a").
You can easily map these codes to characters as required or just use the built in function:
var userInput = String.fromCharCode(unicodeCharCode);
Alternative approach:
One suggestion to use as a workaround would be to use a hidden (or at least discrete) text input / text box, which your app sets focus on.
When your app detects a keypress / keydown etc. you can grab the value the user has entered and render it on your canvas.
As you're already capturing the keyboard events, handling combinations should be easy (if necessary). In some ways even that wouldn't be required as you only have to monitor the input length of the user input (your app doesn't have to care if the user needed a three-key combination to enter the character, you just grab the result).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With