how to handle non english key presses - javascript

When I switch my keyboard layout to hebrew and press a character, it is received in the kepress event as is. For example, clicking ה (the v key), then e.which is 1492. However, when I do a combination the key is the english key. So for alt+ה e.which is 86. So the event looks like alt+v
This is a pain if I want to create a function that accepts key combinations and callbacks and registers the callbacks but also shows a documentation of the callbacks, since if I register alt+ה, then when I press the combination it will look like alt+v and it wouldn't match the registered combinations. But if I register alt+v, then the documentation will be awkward.
So my question boils down to whether one of the following is possible:
knowing which key actually was pressed (meaning, knowing that ה was pressed together with alt and not v)
mapping between the hebrew characters (or any non-english) to their physical english counterparts, so when my function receives alt+ה it will convert it to alt+v for the callback lookup.
Of course I want something generic, that will work for any language, not list just the hebrew alphabet.

You should not care if it is alt-ה or alt-v, you want to perform the same operation on both cases.
If it is not identified, it is not identified anywhere, so your function will get alt-v as well.
if your function gets something ("Alt", "ה") you should create an object for conversion.
var conv= { 'ה': 'v'; 'ש': 'a',...}

Related

KeyboardEvent: how to get numeric key code while 'Shift' is pressed?

In my application, I need to identify if the user pressed any of the number keys (either main keyboard or numpad) as well as if shift/ctrl/alt keys are pressed at the same time.
I need this because the pressed key represents the number in the array (from 0 to 9) which should trigger an action with this number. So my logic is simple:
#HostListener('document:keydown', ['$event'])
handleKeydownEvent(event: KeyboardEvent) {
let index = Number(event.key);
if (isNaN(index)) {
// skip, for now
}else{
doAction(index);
}
}
I like this because of its readability and transparency.
It seems that things are simple when I additionally need to handle 'Alt' or 'Ctrl'. In these cases, event.key still represents a numeric key value of the key pressed (like '1' or '2') (and I can check event.ctrlKey/event.altKey.
But things are getting more complicated when I need to consider the 'Shift' key. In this case, event.key does not represent a numeric key. Instead, it represents other characters such as '!' or '#'.
I guess I could convert this into key code by building a map, but I'd need to handle keyboard layouts as in some cases Shift+2 will end up to be a '#', in other - '"' (Russian layout vs English).
What is the proper and simple way to detect the code of the key pressed when the 'Shift' button is pressed?
Thanks!
Options:
Uisng event.which: It returns numeric value but it is deprecated.
Your idea of creating map is cool. To create the map, instead of using "event.key", use "event.code".
EVENT.CODE is your life saver.

What should I use instead of the deprecated KeyboardEvent.which and KeyboardEvent.keyCode?

I'm trying to strip jQuery out of an existing codebase as part of a modernization/optimization initiative. There are a few places where something needs to happen when a user hits the enter key while in a text input. Previously, we accomplished this with the following:
$("#loginInput").on("keypress", e => {
if (e.which == 13) {
// if key pressed was enter...
login();
}
});
However, reading through the keyboard event APIs here I've found that most of the commonly used APIs are deprecated, such as KeyboardEvent.which and KeyboardEvent.keyCode.
Even though these properties are still available in most browsers, I feel uncomfortable using deprecated APIs. What should I use instead?
I think you want event.key. It seems to be widely supported.
The "key" property gives the character reflected by the user interaction with the keyboard, taking into account all the meta keys involved (shift, ctrl, etc).
So to check for the carriage return character (13), you'd use
if (event.key === "Enter") {
// enter key was pressed
}
edit updated to reflect the somewhat astonishing fact that the "key" property is set to the string "Enter" when that key triggers the event.

In Intern.js Leadfoot, how do I preform a CTRL Click

I'm just wondering what the preferred way to preform a ctrl + click action in leadfoot is. In java I would have used the Actions class and used keyDown, but since we have moved to a JS based framework I'm a complete fish out of water!
I've seen in the api that there is a pressKeys function but it doesn't seem to do what we need. I've thought about using jQuery to do this but I would really rather keep it in the current framework.
Any help greatly appreciated.
Peter
You can use pressKeys, for example:
command.moveMouseTo(myBtn)
.pressKeys(keys.CONTROL)
.clickMouseButton()
.pressKeys(keys.CONTROL)
A good thing to remember about pressKeys (https://theintern.github.io/leadfoot/Command.html#pressKeys)
keys: The text to type in the remote environment. It is possible to type keys that do not have normal character representations (modifier keys, function keys, etc.) as well as keys that have two different representations on a typical US-ASCII keyboard (numpad keys); use the values from leadfoot/keys to type these special characters. Any modifier keys that are activated by this call will persist until they are deactivated. To deactivate a modifier key, type the same modifier key a second time, or send \uE000 ('NULL') to deactivate all currently active modifier keys.
TheIntern/LeadFoot provides you a function execute. You can trigger any event from this function using JS.
.execute(function() {
//You can even access window from here
$("#someId").click() //example
//or try something like this
e = jQuery.Event("keydown");
e.which = 50;
e.ctrlKey = true;
$("input").trigger(e);
})
To trigger keyevent follow these links:
jquery trigger ctrl + click
How to trigger key combo with jQuery

Caret position not keeping track?

What I'm trying to do is put key codes in an array, to do some interesting stuff with later on. So, I capture the keystrokes, get the caret position and put the key code in the array (with some help from MooTools):
var keyArray = [];
$('form').addEvent('keyup', function(event) {
var pos = document.activeElement.getCaretPosition();
keyArray[pos] = event.code;
});
Generally speaking, this works great. However, I noticed some undefined values in my array when showing the complete array in my console. Exploring this further, I found out that when typing quickly, the caret position seems to lose track, or being quick/slow to respond. I've made a jsfiddle to demonstrate this: http://jsfiddle.net/HQVR8/1/
If you type quickly in this example, you'll see a caret position sequence like
- 1 - 2 - 3 - 5 - 6 - 6.
But when typing slowly, it's
- 1 - 2 - 3 - 4 - 5 - 6.
Of course, the trouble now when typing quickly is that I have a undefined value in my array and I overwrite one array item. So the result is different.
My question is if I can somehow let the caret position keep track. I've tried using the 'native' selectionStart instead, but results are the same. I also tried capturing the caret position in a keydown event and putting it in an array in the keyup event. No difference. I'm wondering if using little pauses (ie. forcing the user to type slower) might solve it, but this feels like a hack and I would prefer a 'proper' solution. Hopefully, there is one.
you are basically making a mess by using an array instead of an object.
array indexes are dodgy and can create sparse arrays if you are not careful. for instance:
var foo = [];
foo[0] = "one!"; // foo.length = 1;
foo[2] = "two!"; // foo.length = 3, foo[1] = undefined
so if you type too fast and skip the return value, it is probably doing just that. also, pasting etc can push caret further down...
you can probably use an object though there are no guarantees on the order of keys in vs keys out in all browsers - particularly webkit, who tend to reorder and put numeric keys at top of object key loops... but if you prefix the key like "pos" + caretIndex, you ought to get FIFO
one way to solve your need to extract the actual codes w/o the undefined is via Array.filter.
eg.
retArray = Array.filter(retArray, function(el) {
return el !== undefined;
});
With an object, you can just do:
console.log(Object.values(foo));
After some more tests, it appears to be a behavior specific to keyup. When I use keydown I do get a consistent sequence: http://jsfiddle.net/HQVR8/3/
One disadvantage is that keydown is a step behind keyup when you're doing the 'value collecting' I'm doing, but in my setting, this is only a minor issue.
The difference in behavior appears odd to me: when you press four keys at a time, the keyup displays the same caret position for all of them, while keydown is showing four separate caret positions. This seems odd because you press them at once, but also depress them at once, so the caret 'readings' should be the same.
go to the JSfiddle and fiddle with this:
a) depress 'q', then depress 'w', then release 'q', then release 'w' (fast enough to avoid autorepeat). That kind of sequence happens quite often when you type 'quickly' with more than one finger :).
b) leave any key depressed long enough for the autorepeat to kick in.
The differences are in plain view
Basically, keyUp fires when the physical key is released, but
another key can be depressed before the previous one is released
keyDown is called in case of autorepeat, while keyUp isn't
Since carret position and whatever text area updates are kept in sync with keyDown, you will simply miss the intermediate steps when monitoring keyUp.
In case (a), the keyUp handler sees carret pos jump from 0 to 2 as 'q' is released because two characters have been typed before the first key was released. The release of 'w' does not change carret position, so the handler ends up storing both q and w at position 2.
In case (b), the handler misses the repeats completely, and stores only the last instance of the key.
As a conclusion, using KeyUp will never achieve the intended meaning.
keyDown could, but personnally I would rather hook the changed event.
I reckon it is no less reliable to detect a bot filling the field (after all, a legit user could want to paste the password too), and you won't have to bother with control keys like backspace or whatever other non-keyboard means of clearing the input.
You could use keyUp as an extra paranoid check, as long as you don't expect to reconstruct the exact input. For instance, you could simply check that the released key matches the character at current cursor position. But frankly I'm not sure it is worth the bother.

transform pressed key values to english values

I have an input like this
<input id="guestCard" name="guestCard" onkeypress="transform(event)" type="text" value="" />
and I want to transform the key pressed on a keyboard regardless of which language settings to english character. E.g. when I press on czech keyboard + (with keycode 43) , I want to get 1 (with keycode 49).
Is there some standard way to do this? How would the function transform look like?
Alternatively I want the same functionality but using ajax (on asp.net mvc). Any ideas there?
Thanks in advance.
As far as I am aware, JavaScript is not locale aware - so you would need to somehow detect or have the user pick the appropriate transform mapping (in this case, perhaps a radio button for czech as the source and U.S. ASCII as the destination). Once that is taken care of, your function could be something like:
function transform(event) {
var code = (event.charCode) ? event.charCode : event.keyCode; // cross-browser happy
switch (code) {
case 43 : return "1";
}
}
There is a great test page to see how keyCode/charCode properties and the onKeyDown/Press/Up events behave in different browsers. http://asquare.net/javascript/tests/KeyCode.html
I doubt there is one but to create it, create an associative array, add some JS to a text field which saves the two values in the array and then press every key on the keyboard. After that, you can dump the array somewhere and use this as a constant in your code.
But be warned: Almost all users will have problems when they don't get the character on the screen which they've typed on the keyboard.
Trimack -
I think you are using the wrong event. You need onkeydown, and use the keyCode property of event.

Categories

Resources