Keycode is always zero in Chrome for Android - javascript

I need to detect the keycode for a custom search box on my website, but the keycode always returns as zero on Chrome for Android (except for backspace, which returns 8). Has anyone else experienced this, and how did you get around it? Our website works on all mobile browsers except Chrome for Android because we can't detect a non-zero keycode or charcode.
I'm running Chrome 27.0.1453.90 on Android 4.1.2 Jelly Bean. The problem can be duplicated with something as simple as:
alert(event.keyCode);

below solution also work for me. might be useful for others also.
var getKeyCode = function (str) {
return str.charCodeAt(str.length - 1);
}
document.getElementById("a").onkeyup = function (e) {
var kCd = e.keyCode || e.which;
if (kCd == 0 || kCd == 229) { //for android chrome keycode fix
kCd = getKeyCode(this.value);
}
alert(kCd)
}

I faced this issue and this is how I figured out how to solve the problem.
First, you need to enable USB debugging onto your Android phone so
you can see the logs of your browser on your desktop machine.
Second, refresh your web app on your phone and inside your console on the desktop type "monitorEvents(document)" or whatever element you want to inspect.
Do the action you want to inspect on your phone.
And this is how I found that the keydown event was actually fired by a unique event called "textInput" which contains the information inside event.originalEvent.data.
Hope this saves you time and good luck!

The true way to get the keyCode is to use
event.which
This property on event object is standardize the event.keyCode property. You can read about it also in jQuery documentation here or in MDN here
In other way, I have a lot of experience with keyboard events on android devices.
Android browser has problems sometimes with keyboard events due to device fragmentation (different ROMs between devices or external keyboard apps). The best way is to try to use all the keyboard events (keydown, keyup and keypress) and compare every result to get the pressed key.
The best way is to use in "input" event and get all the time the last charter. The input event can control like in my answer here.

We encountered this problem recently on a China made Android phone Meizu MX3, which has a deeply customized OS based on Android 4.4.4.
The default browswer and Chrome work just fine, but for some weird reasons we don't know, event.keyCode, event.charCode and event.which return 0 all the time in some other browsers(such as CM Browser or webview of Wechat app).
We resolved this by checking the last character you input such as 'A' or ' '(space), then we convert it to ascii code using charCodeAt such as "A".charCodeAt(0) which returns 97, which is the actual char code we need.
But we can only determine the char code of visible chars using this strategy, which meets our current need thank god.
Hope you guys can get some inspiration from this.

I have faced the same issue with Android Devices of SonyXperia and HTC. I have developing hybrid application where i am validating Amount text field by reading event.keyCode() of the entered char on keydown event from text field, so that i can allow only numbers and dot(.) char to be entered. I tried but it doesn't worked, returning always 0 in these devices.
Later i came with other solution with keyup event and char matching through Regular Expression:
$("#AmountField").keyup(function (e) {
var regex = /^[0-9\.]$/;
var str = $(this).val();
var subStr = str.substr(str.length - 1);
if(!regex.test(subStr)) {
if(str.length >0){
$(this).val(str.substr(0, (str.length - 1)));
}else{
$(this).val();
}
}
});
Hope this can help for the people who facing this issue. Good Luck.

<input type="text" id="char" size="15" onblur="showKeyCode()" value="a">
<input type="button" value="Show Key Code" onclick="showKeyCode();">
<script>
function showKeyCode()
{
var character = document.getElementById ( "char" ).value.substr(this.length - 1);
var code = character.charCodeAt();
var stringall = document.getElementById ( "char" ).value;
var msg = "The Key Code for the \""+character+"\" character is "+code+".";
alert(msg);
}
</script>
For reference

If anybody still digging it.Problem appears on stock Samsung keyboard for
android devices.
Instead use onkeyup.

change the type of the input to tel : <input type="tel">
this will let you log the keyCode but it doesnt log the backspace, and it might force the keyboard on mobile to only numbers.

So in most Android browser if u use keydown or keyup you wont be able to get the data from key or keyCode or which or code
You can use event.data(Inserted data key) and event.inputType(backspace or del in mobile)
In order to achieve the functionality you need you have to apply condition based on user agent for android mobile
if (navigator.userAgent.match(/Android/i)) {
node.addEventListener('input', handleInput, false);
} else {
node.addEventListener('keydown', handleKeyDown, false);
}
const handleKeyDown = event => {
event.preventDefault();
if (!event.key) {
return false;
}
genericFunctionHandleThings(event.key, event.code === 'Backspace');
};
const handleInput = event => {
event.preventDefault(); // Here event.preventDefault doesn't stop user from typing
genericFunctionHandleThings(event.data, event.inputType === 'deleteContentBackward');
node.value = storedOrProcessedValue;
};
Here I have used node.value = storedOrProcessedValue because if we want to make some restriction for user typing we need to process and re assign it to the input
You can use this with Input type text,url,email,tel these I have tested rest I need to check

Need to use charCode instead of keyCode
<input type="text" onKeyPress="return funName(this,event)" />
<script language="javascript">
function funName(th,ev)
{
alert(ev.charCode);
}
</script>

Related

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()
}

keydown event - key pressed on different systems

I have a number input, which I want user to by unable to insert any non-digit characters. We have attempted this in a number of ways:
We started with removing all non-numeric characters on blur:
$(my_input).blur(function() {
$(this).val($(this).val().replace(/[^\d]/, '')
}
The problem with the code above is that number field's val function returns empty string if the input is invalid. We definitively want a number field as our website is to be used on mobiles.
The option which I would prefer is to use keydown event:
$(my_input).keydown(function(e) {
if (e.shiftKey === true ) {
if (e.which == 9) {
return true;
}
return false;
}
if (e.which > 57) {
return false;
}
if (e.which==32) {
return false;
}
return true;
});
The above works almost as a charm. The problems are:
numeric keyboard not included in a range - this can be however easily fixed and is not a subject of this question.
For unknown to me reasons js on iOS is using different key codes, hence this is not working on huge part of mobile phones, iPads etc.. This is a deal breaker.
So the question - is there any way to determine which key was actually pressed with an keydown event. I have seen number of similar questions, none of them however covered those iOS differences. I've noticed that event has a 'key' property, however I am not sure how reliable this property is.
EDIT: I fell on this post which might be a neat way to solve your problem:
JavaScript: Avoiding hardcoded keycodes
It would boil down to
var digitCodes = "0123456789".split('').map(function (x) { return x.charCodeAt(0); });
There might be a better way to do this but you could detect if the device is running iOS (c.f. Detect if device is iOS) and use the appropriate keycodes (c.f. http://notes.ericjiang.com/posts/333).
var digitCodes;
if (isiOS()) {
digitCodes = keycodes.ios;
}
else {
digitCodes = keycodes.default;
}
if (digitCodes.indexof(e.which) != -1) {
...
}
Something like that...
You can try it this way
sample text box
<input type="text" name="sample" id="sample" onkeyup="positiveNumericOnly(this);" />
JS Code
function positiveNumericOnly(ele)
{
tempVal = ele.value.replace(/[^\d]/g, "");
if(tempVal != ele.value)
ele.value = tempVal;
}

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

JavaScript KeyCode Values are "undefined" in Internet Explorer 8

I'm having trouble with some JavaScript that I've written, but only with Internet Explorer 8. I have no problem executing this on Internet Explorer 7 or earlier or on Mozilla Firefox 3.5 or earlier. It also executes properly when I use compatibility mode on Internet Explorer 8.
What I'm doing is overriding the Enter keystroke when a user enters a value into a textbox. So on my element I have this:
<asp:TextBox ID="ddPassword" runat="server" TextMode="Password" onkeypress="doSubmit(event)" Width="325"></asp:TextBox>
And then I have the following JavaScript method:
function doSubmit(e)
{
var keyCode = (window.Event) ? e.which : e.keyCode;
if (keyCode == 13)
document.getElementById("ctl00_ContentPlaceHolder1_Login").click();
}
Again, this all works fine with almost every other browser. Internet Explorer 8 is just giving me a hard time.
Any help you might have is greatly appreciated.
UPDATE: Thanks everyone for your quick feedback. Both Chris Pebble and Bryan Kyle assisted with this solution. I have awarded Bryan the "answer" to help with his reputation. Thanks everyone!
It looks like under IE8 the keyCode property of window.Event is undefined but that same property of window.event (note the lowercase e) has the value. You might try using window.event.
function doSubmit(e)
{
var keyCode = (window.event) ? e.which : e.keyCode;
if (keyCode == 13)
document.getElementById("ctl00_ContentPlaceHolder1_Login").click();
}
Just a hunch, try this:
var keyCode = e.keyCode ? e.keyCode : e.which;
It's worked on this way on my code:
var kcode = (window.event) ? event.keyCode : event.which;
try this:
function checkKeyCode(e){
if (!e) e = window.event; var kCd = e.which || e.keyCode;
return kCd;
}
I personally prefer the multi-key approach. This allows multiple keys to be detected, but also a single key just the same, and it works in every browser I've tested.
map={}//declare object to hold data
onkeydown=onkeyup=function(e){
e=e||event//if e doesn't exist (like in IE), replace it with window.event
map[e.keyCode]=e.type=='keydown'?true:false
//Check for keycodes
}
An alternative method would be to separate the onkeydown and onkeyup events and explicitly define the map subitems in each event:
map={}
onkeydown=function(e){
e=e||event
map[e.keyCode]=true
}
onkeyup=function(e){
e=e||event
map[e.keyCode]=false
}
Either way works fine. Now, to actually detect keystrokes, the method, including bug fixes, is:
//[in onkeydown or onkeyup function, after map[e.keyCode] has been decided...]
if(map[keycode]){
//do something
map={}
return false
}
map[keycode] constitutes a specific keycode, like 13 for Enter, or 17 for CTRL.
The map={} line clears the map object to keep it from "holding" onto keys in cases of unfocusing, while return false prevents, for example, the Bookmarks dialog from popping up when you check for CTRL+D. In some cases, you might want to replace it with e.preventDefault(), but I've found return false to be more efficient in most cases. Just to get a clear perspective, try it with CTRL+D. Ctrl is 17, and D is 68. Notice that without the return false line, the Bookmarks dialog will pop up.
Some examples follow:
if(map[17]&&map[13]){//CTRL+ENTER
alert('CTRL+ENTER was pressed')
map={}
return false
}else if(map[13]){//ENTER
alert('Enter was pressed')
map={}
return false
}
One thing to keep in mind is that smaller combinations should come last. Always put larger combinations first in the if..else chain, so you don't get an alert for both Enter and CTRL+ENTER at the same time.
Now, a full example to "put it all together". Say you want to alert a message that contains instructions for logging in when the user presses SHIFT+? and log in when the user presses ENTER. This example is also cross-browser compatible, meaning it works in IE, too:
map={}
keydown=function(e){
e=e||event
map[e.keyCode]=true
if(map[16]&&map[191]){//SHIFT+?
alert('1) Type your username and password\n\n2) Hit Enter to log in')
map={}
return false
}else if(map[13]){//Enter
alert('Logging in...')
map={}
return false
}
}
keyup=function(e){
e=e||event
map[e.keyCode]=false
}
onkeydown=keydown
onkeyup=keyup//For Regular browsers
try{//for IE
document.attachEvent('onkeydown',keydown)
document.attachEvent('onkeyup',keyup)
}catch(e){
//do nothing
}
Note that some special keys have different codes for different engines. But as I've tested, this works in every browser I currently have on my computer, including Maxthon 3, Google Chrome, Internet Explorer (9 and 8), and Firefox.
I hope this was helpful.
Try adding onkeyup event as well and call the same function.
TIP:
You can add debugger; at beginning of doSubmit to set a break, then you can examine keyCode.
I think window.Event.keyCode works in IE8 (I can't test right now though)
Or something like that.
var keyCode = e.which || e.keyCode;

Categories

Resources