How to detect brace stroke - javascript

I am looking for a general solution to detect braces: { or }.
I have an azety keyboard and I need to use the ALT GR stroke to type them, they are respectively located on the 4 and + keys.
As it is not the same on qwerty keyboard, and probably other dispositions,
I can not know if these characters are being typed just with the information given by the event returned by the keyup listener, I just know that the 4 has been pressed (Chrome does not event let me know that the alt gr is pushed).
Yet, if I use the keypress event, I get the correct code.
But keyup is preferable for me.
var element = document.getElementById('textbox');
element.onkeyup = function(evt){
console.log("keyup");
console.log(evt.which);
};
element.onkeypress = function(evt){
console.log("keypress");
console.log(evt.which);
};
<textarea id="textbox"></textarea>
with that code, I get this output when I type a {:
keypress
123 // { key code
keyup
52 // 4 key code
keyup
225 //alt gr key code
So, is there a solution, independant to the keyboard disposition to detect braces?

AltGr is the same as Ctrl-Alt you could ask for the modifiers while checking.
You must know that the same keyboard could change de configuration of the position of each, keys. I'm have a Spanish/English windows configuration and I change the layout several times in the same day (that changes the position of { and }).
You must use keypress

Related

javascript code prevents typing except special characters

I was putting together some simple javascript to prevent characters being input in my form. I got to this stage where I was able to prevent all typing, and noticed that it prevents all characters except special ones, like å´ˆø`¨
which I can enter on my mac using: [Option]+`+[Letter key]
How can I prevent these being entered?
HTML:
<form>
<input name="myinput"></input>
</form>
JS:
document.querySelector('input').addEventListener('keypress', function (e) {
e.preventDefault();
return false;
});
fiddle:
https://jsfiddle.net/6qty7dgr/
This is not working because these keystrokes actually start a composition event, i.e the full input has not yet been processed by the IME and you have "half-a-character". So calling preventDefault() on the keydown event here won't prevent the typing of this half character and the browser will insert it in the input anyway.
document.querySelector('input').addEventListener('keypress', function (e) {
e.preventDefault();
});
document.querySelector('input').addEventListener('compositionstart', function (e) {
console.log("composition start fired");
e.preventDefault(); // should have worked per specs, but doesn't...
});
<input name="myinput"></input>
By specs, you should have been able to prevent this by calling preventDefault() on the compositionstart event that does fire. However, no browser actually seems to support cancelling this event and it seems that for technical reasons they won't support it ever. However they should support cancelling the beforeinput event, but as of today only Safari does support cancelling it when it comes from a composition event...
"I was putting together some simple javascript to prevent characters being input in my form."
"How can I prevent these being entered?"
Emphasis added by me
Avoid keyboard events if you are using a form control. Form events usually work better since there is very little variation when interpreting the value of an input as opposed to keyboard events.
In the example below, the <input> listens for the "input" event. As the user types into the <input>, the .value property is being filtered by the following Regexp:
const rgx = new RegExp(/([å´ˆø`¨])*/, 'g');
(...)- Capture group: matched characters that are extracted.
*----- Quantifier: zero or more matches.
[...]- Class: a literal character. -, \, ], and ^ must be escaped by prefixing \ to it.
å´ˆø``¨ are instantly replaced with a zero-space "".
Details are commented in example below
// Bind input tag to the input event
document.forms[0].elements.filter.oninput = dataFilter;
// Pass the Event Object
function dataFilter(e) {
// Delegate to input tag only
if (this.name == 'filter') {
/*
This matches
å´ˆø`¨
*/
const rgx = new RegExp(/([å´ˆø`¨])*/, 'g');
// Replace everything in rgx
const filtered = this.value.replace(rgx, '');
// Assign filtered string as value
this.value = filtered;
}
// Prevent input from rendering everything
e.preventDefault();
};
<form>
<input name='filter'>
</form>
Note: The onkeypress event is not fired for all keys (e.g. ALT, CTRL, SHIFT, ESC) in all browsers. To detect only whether the user has pressed a key, use the onkeydown event instead, because it works for all keys.
https://www.w3schools.com/jsref/event_onkeypress.asp

Handling multiple keys pressed at once in JavaScript

For context: this is a JavaScript app running in the Xbox One. All of this is happening through the Xbox's virtual keyboard. Keep in mind that since I have figured out how the events are being fired, this shouldn't matter anymore, just how to deal with the two events at once.
It's not really multiple keys, what is happening is when I turn on CAPS for my app, I am getting two events keys at once: shift and whatever key I am actually pressing. The problem this is causing is that shift seems to be overriding whatever I am trying to spell, and no key is displayed in my input boxes.
I currently have a global function which takes care of all special events in the app, and I would like to handle this issue from over there but am not sure how to go about this issue.
Here is what I currently have:
// this is the global function where I would like to solve the issue
onStartup(function () {
var $html = $('html')
$html.on('keydown', function (evt) {
if (evt.isDefaultPrevented()) return
console.warn('key being pressed:', evt.keyCode)
if (evt.keyCode === 16) { // Note: 16 is shift's keycode
// do something to prevent shift from overriding the actual key I want to press.
return
}
})
})
When I press a key without CAPS being turned on, say a, which has the keyCode of 65, we have the following output:
key being pressed: 65
If however I try to do a capital a (or A), this is what happens:
key being pressed: 16
key being pressed: 65
What can I do to stop the shift from preventing me from actually typing the capital keys?
I figured it out! All I had to do was when shift was fired, to call evt.stopImmediatePropagation().
So basically, for my code:
// ...
if (keycodeControls.is('shift', evt)) {
evt.stopImmediatePropagation()
}

Binding the "onselect" event to a function, that handles the maximum chars. inside an input text field

I am working on a function to limit the number of chars. a user is allowed to type inside an input text field.
This is it:
$.fn.restringLength = function (id, maxLen) {
$(id).keypress(function(e){
var kCode = e.keyCode ? e.keyCode : e.which,
len = $(id).val().length;
if (kCode != 8 && kCode != 46) {
if (len > maxLen) e.preventDefault();
}
});
}
The function binds the keypress event and gets the code of the pushed key.
If the char. limit is reached, it allows only the delete and backspace keys to be pushed.
What it needs to work great, is a way to bind the "onselect" event in order to have the following behavior:
when the user selects the whole text with the mouse, and types a letter or a number, the whole text gets deleted and that letter appears.
This is something that most of us do when we want to replace some text with another, and I'd like my function to enable this.
Any ideas how?
If i may add something,
Your solution use keypress event, so the event is triggered before the new value of input is computed. That's why you have to check for special key like backspace , enter ... theses do not just add a character to the string so they require special treatment.
For this kind of processing, it's more convinient to have the handler triggered after the string computation. In that way, you can access the input value and modify it if it's not correct.
Unfortunately jquery does not support this event but you can use it with vanilla javascript method.
$(id)[0] // get the vanilla js element
.oninput = function(e){
this.value = this.value.substr( 0 , 10 ) // this.value contain the string after the key press processing
}

How to know if a key is pressed having no charcode value

I want to know if ctrl,space,alt,capslock,shift like keys are pressed in my keyboard.
When i do
String.fromCharCode(e.keyCode)
,it returns blank value for these keys but when I do
alert($.trim(String.fromCharCode(e.keyCode))=='')
Then it return false for all keys except space bar.So it would be great if someone may tell me to get the keydown event of these keys
Vanilla JavaScript:
For other constants, see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent
window.onkeydown = function (e) {
switch (e.keyCode) {
case KeyboardEvent.DOM_VK_SPACE:
alert('space bar!');
break;
case KeyboardEvent.DOM_VK_CAPS_LOCK:
alert('CAPS LOCK!');
break;
case KeyboardEvent.DOM_VK_CONTROL:
alert('control!');
break;
case KeyboardEvent.DOM_VK_SHIFT:
alert('shift!');
break;
case KeyboardEvent.DOM_VK_ALT:
alert('alt!');
break;
}
};
UPDATED FOR REQUIREMENT TO AVOID CASES:
Per the following test, the only numeric values that will, after trimming (and not including numbers not corresponding to the average keyboard), be reduced to an empty string are 9,10,11,12,13,32. Looking at https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Virtual_key_codes , the only ones that correspond are tab, clear, return, and space .
// Run in Firefox where trim() is supported (without need for jQuery):
var arr = [];
for (var i=0; i < 0xFFFF; i++) {
if (String.fromCharCode(i).trim() == '') {
arr.push(i);
}
}
In other words, your own test is not going to catch all cases.
So you have to use numeric comparisons based on the info at https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Virtual_key_codes and BASED ON EXACTLY WHAT CHARACTERS YOU NEED TO INCLUDE (or exclude).
For example, if you consider the cancel key, help key, back space, tab, etc. all to be of the type you mentioned, you can do:
window.onkeydown = function (e) {
if (e.keyCode < 0x30) {
alert('Special key pressed!');
}
};
As you can see, this allows for us to find a whole group of characters within a short amount of code (e.g., without using case). (But if we don't know exactly which characters you want to include or exclude, we can't give you a more precise answer.)
NOTE:
charCode is never set in the keydown and keyup events. In these cases, keyCode is set instead.
you can try
$(window).keydown(function (e){
if (e.ctrlKey) { there are e.altKey & e.shiftKey also.
for other keys use hardcoded integer values.
alert("control");
}
});
I'm not sure about the support of keyIdentifier but if you are using the keyup, keydown or keypress events, but you could possibly do the following. However there are no cross-browser guarantees where charcode is not defined or is zero. Not using jquery to keep things as small as possible, and only detecting the keys that you specified. See article.
Javascript
/*jslint maxerr: 50, indent: 4, browser: true */
(function () {
"use strict";
function addEvent(elem, event, fn) {
if (typeof elem === "string") {
elem = document.getElementById(elem);
}
function listenHandler(e) {
var ret = fn.apply(null, arguments);
if (ret === false) {
e.stopPropagation();
e.preventDefault();
}
return ret;
}
function attachHandler() {
window.event.target = window.event.srcElement;
var ret = fn.call(elem, window.event);
if (ret === false) {
window.event.returnValue = false;
window.event.cancelBubble = true;
}
return ret;
}
if (elem.addEventListener) {
elem.addEventListener(event, listenHandler, false);
} else {
elem.attachEvent("on" + event, attachHandler);
}
}
function checkKeys(e) {
if ("Alt,Shift,Control,CapsLock,U+0020".indexOf(e.keyIdentifier) !== -1) {
alert(e.keyIdentifier);
}
console.log(e.keyIdentifier);
}
addEvent(window, "keydown", checkKeys);
}());
On jsfiddle
Update: reading a bit furter, keyIdentifier is not supported by all browsers and so is not fullly cross-browser friendly.
3.4. New Standard Key and Character Events
The DOM3 standard abandons all hope of creating order among
event.keyCode, event.which and event.charCode, and instead defines new
values for keydown and keyup events. For a while it deprecated the
keypress event and replaced it with the textInput event, but that was
undone. Only a few browsers implemented the first version, and, so
far, no browsers have implemented the newest version. Earlier versions
of the specification defined attributes named event.keyIdentifier and
event.keyLocation. The keyIdentifier was a string that in most cases
looked like "U+0041" where the "0041" part is the unicode value of the
character sent by the key when it is typed without modifiers, in this
case the letter "A". For keys that didn't send unicode characters, or
where the unicode value is not standardized, it was a string like
"Enter", "Shift", "Left" or "F9". The keyLocation attribute gave
values to distinguish among multiple keys that had the same
identifier, like the left and right shift keys, or the keypad number
keys. It was 0 for standard keys, 1 or 2 for left or right versions of
a keys like Shift which appear twice on the keyboard, and 3 for keys
on the numeric keypad.
WebKit implemented support for keyIdentifier and got it mostly right.
Older versions conformed to an older version of the standard and
returned two extra zeros (eg, "U+000041") but this was corrected in
version 525. Windows versions of Safari and Linux versions of Chrome
return bad keyIdentifier values for all of the non-number symbol keys
(WebKit Bug 19906 reported in July 2008). The keyLocation attribute is
always 0 or 3, so it does not distinguish between left and right
modifier keys.
Konqueror returns keyIdentifier values like "Shift" and "Enter"
correctly, but instead of returning the Unicode values, it returns the
typed character itself, "a" or "A" instead of "U+0041". All
keyLocation values are zero, except for modifiers key, which are
always one, regardless of whether the left or right one was pressed.
We cannot, however expect any more browsers to implement that
standard, since it has now changed. The DOM 3 standard no longer
mentions event.keyIdentifier or event.keyLocation. Instead we have
event.key, event.char, event.location.. So far as I know, no browser
has yet implemented this new version of the DOM 3 standard.
In this standard event.char is defined only when you type a printable
character, or another character with a defined code (like tab or
backspace). It's basically like event.charCode except that it is the
character, not the character code and can be any unicode character not
just an ASCII code. Event.key is the same as event.char for printable
keys. For other keys, even ones like tab or backspace that have
character encodings, it is a string like 'Tab', 'Left' or 'F9'. These
values are supposed to be the same on keypress events as they are on
keyup and keydown events, though keypress would not be fired for those
cases where event.char is null.
Note that neither of these pretends to be a keycode identifying a
particular physical key on the keyboard. If you press the /? key on a
US keyboard while shift is off, but press the shift key before
releasing the /? key, then then on keydown you'll get event.key=='/'
and on keyup you'll get event.key=='?'. The only way your Javascript
program will know that those two events go together is if it happens
to know that those two characters are on the same key. There is an
event.locale value that is supposed to give you some clue on what type
of keyboard is being used, but figuring out what keys go with what on
a particular keyboard is up to you.
Clearly this abandonment of the idea of keycodes is going to cause
problems, but is still probably justified. In many (most?) operating
systems, I don't think the browser can actually tell which key was
pressed. In the browser source code I've seen, the keycodes are
generated from the the character codes, not vice versa, by simply
assuming that the character came from a US keyboard. So the keycode
values never really worked for non-US keyboards.
So while the keycode concept was a handly one, it isn't really
practically extensible in the real world. If you want a keycode in the
DOM 3 universe, you'll have to go on using the legacy event.keyCode
value, which, standards or no standards, isn't going away. The DOM 3
standard seems to recognize this, and reluctantly provides an appendix
with some standards for event.keyCode and the like. It casts a rather
weak vote for what I called "IE keycodes" above.

shiftKey in Safari on iOS

Is there any way to determine in javascript whether shift key is pressed on mobile keyboard, and distinguish it from the caps lock(twice pressed shift key)
Some Facts
First, let's look at some facts about iOS keyboards I assume you already know:
When you enter the keyboard mode, the shift key is always activated
Caps Lock must be activated manually (I guess this is not used too widely)
iPhone Shift Key Handling
I investigated a bit into this issue, and here's what I found:
The shift Key triggers no key Event
There is no special iPhone Browser API to detect whether the shift key is pressed or not, except in an iOS App (duh)
The keydown, keypress, keyup event triggered by iOS look normal, except they do not indicate shiftKey usage, and apart from their timestamp and type cannot be distinguished.
You cannot manually dispatch a Keyboard Event in iOS because of this issue, keyCode and which are readonly and always set to 0. Retriggering a Keyboard event to get some indication about the shift key still being on is impossible.
Actually, The iPhone treats the shift key like some sort of Short Term Caps Lock key. The difference is that normally, you activate it once, and it deactivates automatically.
What can be done
I assume you want to indicate on an input field whether the user should be careful about having Shift/Caps Lock pressed (a password field, for example). What I came up with is some sort of a workaround, but I think it's better than nothing.
You can also test the jsfiddle here.
DOM Setup
<div id="wrapper">
<label for="test">ENTER SOMETHING HERE</label>
<input type="text" name="test" id="test"/>
</div>
<div id="warning"></div>​
Javascript
This checks wheter the user did enter capitalized input, and it assumes the user is using caps lock if two capitalized letters where entered.
var isCaps = false,
isUppercase = false,
str = '',
test = document.getElementById('test'),
warning = document.getElementById('warning');
function capsDetection(e) {
// Since where on iOS, we at least don't have to care
// about cross-browser stuff
var s = String.fromCharCode(e.which);
isCaps = isUppercase;
// if the char doesn't match its lower case friend, and the shift key is
// not pressed (which is always the case on iOS, but we leave it there
// for readability), we have uppercase input
isUppercase = (s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey);
// if its the second uppercase input in a row, we may have caps lock input
isCaps = isCaps && isUppercase;
// set the warning
if (isUppercase && !isCaps) {
str = 'You where using the shift key';
}
else if (isCaps) {
str = 'Caps lock seems to be activated';
} else {
str = '';
}
warning.innerHTML = str;
}
// the right event properties are only available on keypress
test.addEventListener('keypress', capsDetection);
As I said, better than nothing, but not a solution if you need to know the shift key is pressed without the user doing any input. That seems to be impossible right now.
I don't think that this is possible with Javascript. It is possible with objective C though.
http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/TouchEventClassReference/TouchEvent/TouchEvent.html

Categories

Resources