How can I capture altKey + i, u, e, n with jQuery? - javascript

I'm trying to set up a keyboard for a foreign language. I'm using jQuery to convert keys pressed into foreign characters. I am using:
A - Z
ALT + A - Z
SHIFT + A - Z
ALT + SHIFT + A - Z
My code works for all of these except these 4:
ALT + I
ALT + U
ALT + E
ALT + N
It works fine in Firefox, but in Chrome and Safari (I'm using a mac) I get these accent marks - ˆ, ¨, ´, ˜ - instead of the foreign character that is supposed to go into the textarea.
Here is some of the code:
function type(e, char, textArea) {
e.preventDefault();
var start = textArea[0].selectionStart;
var end = textArea[0].selectionEnd;
var len = textArea.val().length;
var newPos = start + char.length;
textArea.val(textArea.val().substring(0, start) + char + textArea.val().substring(end, len));
textArea[0].setSelectionRange(newPos, newPos);
}
$('textarea').keydown(function(e) {
var textArea = $(this);
if (e.which == 65 && e.altKey) {type(e, 'अ', textArea);return false;}
if (e.which == 68 && e.altKey) {type(e, 'ड', textArea);return false;}
if (e.which == 73 && e.altKey) {type(e, 'इ', textArea);return false;}
if (e.which == 74 && e.altKey) {type(e, 'ज्ञ', textArea);return false;}
});
This works when e.which is 65, 68, and 74, but not 73.
How can I get this to work right?

You know it's funny, I'm also constantly asking myself why something doesn't work in chrome even though it works just fine everywhere else. In this case, I'm assuming it has to do with the fact that both e.which and e.keyCode have been depreciated for e.key and e.code.
That being noted, I still use e.keyCode in production, so I know it still works with the latest version of chrome. Maybe do some console.log(e) and see what values are actually being returned?
I don't have chrome on my personal computer, so I can't test this, but I simplified your code and made a fiddle that works on my machine. Hopefully it helps point you in the right direction.
function InsertSymbol(symbol, $selector) {
let cursor = $selector[0].selectionStart,
text = $selector.val();
$selector.val(text.substr(0, cursor) + symbol + text.substr(cursor)).focus()[0].setSelectionRange(++cursor, cursor);
}
$('textarea').on('keydown', function(e) {
if (e.altKey) {
e.preventDefault();
switch (e.keyCode) {
case 69: InsertSymbol('इ', $(this)); break;
case 73: InsertSymbol('अ', $(this)); break;
case 78: InsertSymbol('ज्ञ', $(this)); break;
case 85: InsertSymbol('ड', $(this)); break;
}
}
});
https://jsfiddle.net/rvgj35kt/2/

I'm using Chrome on Mac and your jsFiddle example https://jsfiddle.net/s0fmpgaj/ is working. When I press ALT + SHIFT + i
It returns the special char you defined.

Related

Hotkey combinations don't work if done fast

I'm trying to make a hotkey for a web app, for example Ctrl + z performs the undo function.
It seems that when I press the keys fast (as I'm used to from using desktop apps a lot), it doesn't register. The single key press registers, but it misses the combination for some reason.
From what I understand, you have to keep track of which buttons are held down via keypress events, which is what I've done below.
Try the code below. Hitting Z outputs Z. Hitting CTRL then Z slowly outputs CTRL + Z. Hitting CTRL then Z quickly outputs Z. When I perform the action at the same speed in say Notepad for windows, it works flawlessly almost every time.
https://codepen.io/samkeddy/pen/YQjgdZ?editors=1010#0
var ctrlPressed=false, altPressed=false;
window.addEventListener("keydown", function (e) {
hotkey = e;
if (e.keyCode == 17) ctrlPressed = true;
if (e.keyCode == 18) altPressed = true;
e.preventDefault();
});
window.addEventListener("keyup", function (e) {
hotkey = window.event;
if (e.keyCode == 17) ctrlPressed = false;
if (e.keyCode == 18) altPressed = false;
if (e.keyCode == 90){
if (altPressed && ctrlPressed && e.keyCode == 90)
addText('ALT + CTRL + Z');
else if (ctrlPressed && e.keyCode == 90)
addText('CTRL + Z');
else
addText('Z');
}
});
//meaningless, just adds text to doc so you can see it
function addText(text) {
var theDiv = document.getElementById("output");
theDiv.appendChild(document.createElement("br"));
var content = document.createTextNode(text);
theDiv.appendChild(content);
}
Use e.ctrlKey to check if ctrl is down instead of variables, and just check for the hotkey combination on keydown, don't do anything on key up.
https://codepen.io/samkeddy/pen/gRdBpq
function KeyPress(e) {
var evtobj = window.event? event : e
if (evtobj.keyCode == 90 && evtobj.ctrlKey) addText("CTRL + Z");
else if (evtobj.keyCode == 90) addText("Z");
}
document.onkeydown = KeyPress;

Adding keypress Events that use an existing function

I have used a function which is activated on click events. I want to do the same using keypress events.
function addToText(target) {
var exp = target.target;
//alert(exp.value);
if (newExp) {
//clearText();
document.getElementById("expression").value = exp.value;
newExp=false;
}
else
document.getElementById("expression").value = document.getElementById("expression").value + exp.value;
}
This is the function used. How do I modify it to use for keypress events also. Currently, it does not work initially(for keypress events). But after clicking once, then any keypress returns the same number that was previously clicked.
Full code here:http://codepen.io/jpninanjohn/pen/JXVpYb?editors=1010
Here's is your final solution, I test if charcode is between 48 and 57, what it means, numbers between 0 and 9.
document.addEventListener('keypress', function(e){
if (e.which >= 48 && e.which <= 57)
document.getElementById("expression").value+= String.fromCharCode(e.which);
});
You can use this function-
window.onkeyup = function(e) {
var key = e.keyCode ? e.keyCode : e.which;
document.getElementById("expression").value += key-48; //for getting the number
alert(key);
if (key == 38) {
//whatever
}else if (key == 40) {
// whatever
}
}
source
And you need to add + to the =
document.getElementById("expression").value+=
instead of -
document.getElementById("expression").value=
You have to add a different function for keyPress event, because the keypress event get the value of pressed key differently, not target.target
function addToTextKeypress(event) {
var exp = String.fromCharCode(event.keyCode);
//alert(exp);
if (newExp) {
//clearText();
document.getElementById("expression").value = exp;
newExp=false;
}
else
document.getElementById("expression").value = document.getElementById("expression").value + exp;
}
Later you need to remove exp.value since it has the direct value

Firefox is not processing keyCode's. It displays the variables as a matrices in debugger

This code works perfectly on other browser such as Edge and Chrome, but for some reason Firefox does not want to detect the values from keyCode.
Notes: I used the debugger, and the when I pressed fore example '2', it keychar should have been 2 on the debugger watch list, but instead it gave me a wierd matrices symbol "[00]"
What it does: Prevents user from entering any characters that aren't numbers 0-9
Here's my code:
function keyHandlerForID(e)
{
var keycode = e.keyCode;
var keychar = String.fromCharCode(keycode);
if(keychar < '0' || keychar > '9')
{
e.preventDefault();
}
}
function start()
{
document.getElementById("studentID").addEventListener("keypress", keyHandlerForID, false);
}
window.addEventListener("load",start,false);
...
Like I said this is my script, but it works on all browsers but Firefox.
You need to use the which or charCode property:
function keyHandlerForID(e)
{
var keycode = e.which || e.charCode || e.keyCode;
var keychar = String.fromCharCode(keycode);
if(keychar < '0' || keychar > '9')
{
e.preventDefault();
}
console.info(e, keycode, keychar)
}

Handle tab in textarea

I need to insert a tab into a textarea when a tab is clicked rather than moving the focus to the next element.
I've done some research but found no solutions that actually use tab instead of a series of spaces.
How would I do this and how would I insert a true tab instead of 4 spaces?
jsFiddle example.
JavaScript:
function insertTab(o, e) {
var kC = e.keyCode ? e.keyCode : e.charCode ? e.charCode : e.which;
if (kC == 9 && !e.shiftKey && !e.ctrlKey && !e.altKey) {
var oS = o.scrollTop;
if (o.setSelectionRange) {
var sS = o.selectionStart;
var sE = o.selectionEnd;
o.value = o.value.substring(0, sS) + "\t" + o.value.substr(sE);
o.setSelectionRange(sS + 1, sS + 1);
o.focus();
}
else if (o.createTextRange) {
document.selection.createRange().text = "\t";
e.returnValue = false;
}
o.scrollTop = oS;
if (e.preventDefault) {
e.preventDefault();
}
return false;
}
return true;
}​
Ripped without shame from here.
Wherever the code says to add those four spaces, replace the four spaces either with a literal tab character, or with the escape sequence \t.

Optimizing jQuery Hotkeys

So I have a web app which uses all the hot keys from A to Z.
Each hot key is used for a tab. So for example:
I have 20 tabs:
#tab1, #tab2, #tab3, #tab4 etc. All tabs get a class of .tabs.
So for the hotkeys to work I made this:
if (e.keyCode == 65) {$('.tabs:not(#tab1)').hide();$("#tab1").fadeIn();}
if (e.keyCode == 66) {$('.tabs:not(#tab2)').hide();$("#tab2").fadeIn();}
if (e.keyCode == 67) {$('.tabs:not(#tab3)').hide();$("#tab3").fadeIn();}
if (e.keyCode == 68) {$('.tabs:not(#tab4)').hide();$("#tab4").fadeIn();}
if (e.keyCode == 69) {$('.tabs:not(#tab5)').hide();$("#tab5").fadeIn();}
if (e.keyCode == 70) {$('.tabs:not(#tab6)').hide();$("#tab6").fadeIn();}
if (e.keyCode == 71) {$('.tabs:not(#tab7)').hide();$("#tab7").fadeIn();}
//etc till keycode 81 and tab20.
So, is there a better optimizing way to make this so it will be written in less characters? Since on each line I'm using twice the the same ID.
Edit/Note: Sorry, the actual tab ID's are random names.
Thanks
Something like this perhaps:
if(e.keyCode >= 65 && e.keyCode <= 81) {
var tab = e.keyCode - 65 + 1;
$('.tabs:not(#tab' + tab + ')').hide();
$('#tab' + tab).fadeIn();
}
I don't see how keycode 81 is supposed to be tab20 though, wouldn't that be tab17?
Update: If your tab ids can be anything at all then just throw them in an array:
var tab_ids = [ 'where', 'is', 'pancakes', 'house', ... ];
if(e.keyCode >= 65 && e.keyCode <= 81) {
var tab = tab_ids[e.keyCode - 65];
$('.tabs:not(#' + tab + ')').hide();
$('#' + tab).fadeIn();
}
If you also have gaps in they keycodes then use an object instead of an array:
var tab_ids = { 65: 'where', 70: 'is', 72: 'pancakes', 73: 'house', ... };
var tab = tab_ids[e.keyCode];
if(tab) {
$('.tabs:not(#' + tab + ')').hide();
$('#' + tab).fadeIn();
}
$('.tabs:not(#tab' + (e.keyCode - 64) + ')').hide();
$("#tab" + (e.keyCode - 64)).fadeIn();
Just replace all these if statements with this code
$('.tabs:not(#tab'+(e.keyCode-64)+')').hide();
$("#tab"+(e.keyCode-64)).fadeIn();

Categories