keyCode on android is always 229
Asked Answered
D

11

88

On my Samsung Galaxy tab 4 (Android 4.4.2, Chrome: 49.0.2623.105) I ran into a situation where the keyCode is always 229.

I've setup a simple test for two situation

<div contenteditable="true"></div>
<input>
<span id="keycode"></span>

script:

$('div, input').on('keydown', function (e) {
    $('#keycode').html(e.keyCode);
});

DEMO

Fortunately I can find posts about this, but I couldn't find one with a working solution. Someone suggested to use keyup instead or to use the textInput event, but that one is only fired on blur.

Now, to top it all, this doesn't happen with the default stock browser :(

Any help would be appreciated!

UPDATE: If it turns out that this is not possible I can still grab the char before the caret: post

Dawna answered 20/4, 2016 at 19:37 Comment(4)
I reproduced your issue in Chrome browser on a Samsung Galaxy S4. However it works fine in the stock browser.Rap
sometimes, it is possible to listen for "beforeinput" event and use event.data property...Erudite
Bug still exists. I'm running a chrome 112.0.5615.136 on an Android 13; Pixel 7 Pro device. Very unfortunate that this hasn't been fixed! I've hacked in the 229 keycode for now.Kaneshakang
All the tech companies should sit together and make some standards. This is insane.Cinderellacindi
A
34

Normal keypress event does not give keyCode in android device. There has already been a big discussion on this.

If you want to capture the press of space bar or special chars, you can use textInput event.

$('input').on('textInput', e => {
     var keyCode = e.originalEvent.data.charCodeAt(0);
     // keyCode is ASCII of character entered.
})

Note: textInput does not get triggered on alphabets, number, backspace, enter and few other keys.

Ashmead answered 2/3, 2017 at 10:6 Comment(0)
B
15

I had the same issue and could not find any solutions.

event.target.value.charAt(event.target.selectionStart - 1).charCodeAt()
Bowleg answered 11/4, 2018 at 11:31 Comment(5)
I don't think that would work if the cursor is anywhere before the last character and the character is being inserted.Soubriquet
Hey Thanks for pointing it out. I have fixed it and it should give char code based on cursor positionBowleg
May I ask how you fixed it? Could you post the code? Thank you.Soubriquet
event.target.selectionStart this line with get caret positionBowleg
To get the most recent textInput value, I used this answer but updated the code to event.originalEvent.data.charCodeAt(event.originalEvent.data.length - 1)Outofdoor
O
7

Running into the same problem, only happens with stock Samsung keyboard on Android. A work around was to turn off the keyboard predictions, which fixed the input. Still analysing further to see if a work around can be found in JS land.

Edit: I've managed to find a solution for our case. What was happening, is that we had a whitelist of allowed characters that a user was allowed to enter in our input box. These were alphanumeric characters plus some whitelisted control characters (e.g. enter, esc, up/down). Any other character input would have the event default prevented.

What happened is that all events with keycode 229 were being prevented, and as a result no text was entered. Once we added keycode 229 to the whitelist as well, everything went back to functioning ok.

So if you are using some kind of custom or 3rd party form input control component, make sure to check that keycode 229 is whitelisted/allowed and not default prevented.

Hope this helps someone.

Overscore answered 7/1, 2017 at 2:13 Comment(2)
I would be interested in a working solution, but I gave up and I'm now focussing on a solution in which I use the caret position and compare the string before the keypress and after. Note that this solution doesn't work very well for keys like SHIFT, CTRL, etcDawna
This issue has also been seen on my Google Pixel using the GboardSaxony
L
3

I was having the same issue on Samsung S7 phones. Solved it by replacing event from keydown to keypress.

$("div, input").keypress(function (e) {
    $("#keycode").html(e.which); 
});

jQuery normalizes this stuff, so there's no need to use anything other than e.which https://mcmap.net/q/22253/-jquery-event-keypress-which-key-was-pressed

Laodicean answered 18/1, 2017 at 10:38 Comment(4)
Tried this and the event never fired for me (panasonic toughpad).Linnea
document.onkeypress and window.onkeypress never fire on my android tabletMahan
Return 229, too.Seidel
keypress is deprecated developer.mozilla.org/en-US/docs/Web/API/Element/keypress_eventChemisorb
S
3

Maybe you want to use onbeforeinput and oninput events along with their .data attribute to find the character values instead of keydown and keyup with .key and .keycode.

http://jsfiddle.net/vLga0fb9

https://caniuse.com/?search=beforeinput

Schellens answered 15/10, 2021 at 6:6 Comment(4)
It is wished to detect all keys, not only those which prints charactersAeroembolism
The question is only about keycode=229, which is basically emitted for print characters. So one can use onbeforeinput and oninput to resolve those keys. Metakeys are already resolved by keydown etc. So to resolve all keys each event needs to be checked.Seidel
When there are 2 input fields on the page and enter is pressed, it doens't detect and go to other input. Please see here jsfiddle.net/3ocv97sd/3Deodorize
This was part of my solution, but one thing that stuck out was that onbeforeinput fired after onkeydown.Obelia
I
1


I know I'm answering an old post, but yet this problem is still ON so I like to share a view on it.
However this method is not an exact solution, but just a solution for urgency as I had.
The key is to use the value of the textbox while using keypress. for every key press value will change and by the last value update we can make which key has been pressed.
Note: this only works for the visible font on the keyboard, i.e., alphanumerics and special chars, this will not record any control or shift or alt keys as you know

  $('input').keyup(function () {
  var keyChar = $(this).val().substr(-1);

 //you can do anything if you are looking to do something with the visible font characters
  });
Invigorate answered 7/7, 2018 at 23:57 Comment(1)
What if the user has placed their caret somewhere other than the end of the string? You would need to use the inputs caret position, not just substring -1Graduate
D
1

AFAIK this is still an issue on mobile so the only way to resolve it is to provide workarounds.
For the enter key you can do the following using oninput(event):

let lastData = null;
function handleInputEvent(inputEvent) {
    switch (inputEvent.inputType) {
        case "insertParagraph":
            // enter code here
            break;
        case "insertCompositionText":
            if (lastData === inputEvent.data) {
                // enter code here
            }
            break;
        case "insertText": // empty text insertion (insert a new line)
            if (!inputEvent.data) {
                // enter code here
            }
    }
    lastData = inputEvent.data;
};

To create other workarounds you can check out the docs:
https://developer.mozilla.org/en-US/docs/Web/API/InputEvent
and specs: https://w3c.github.io/input-events/#interface-InputEvent

A working example, just type in anything and press enter: https://jablazr.github.io/web-console/

Davao answered 21/5, 2021 at 17:16 Comment(1)
input event listener will not get fired on pressing the Enter key, so why are you saying For the enter key you can do the following?Aeroembolism
L
1
e.target.value.endsWith(',')

you can work with this. For android device.

something like

    $(document).on("keyup", '.tagsinput', function (e) {
        // console.log('|'+e.target.value.endsWith(',')+'|')
        // elif 

        if (e.keyCode == 188 || e.keyCode == 13 || e.target.value.endsWith(',')) { // KeyCode For comma is 188
            // alert('comma added');
            word = e.target.value.split(',')[0]
            console.log(word.length)
            if (word.length != 0) {
                console.log(word);
                tagsarray.push(word)
                e.target.value = ''
                tagarea.innerHTML += `<div class="block" id="${word}"><span class="tagscircle">${word}</span><div class="inline-block" attr-val="${word}" onclick="removeTag(event)"><svg attr-val="${word}" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2" d="M20 20L4 4m16 0L4 20"/></svg></div></div>`
                resultsBox1.innerHTML = ''
            }
            else {
                e.target.value = ''

            }

        }
    });
Labour answered 2/8, 2022 at 15:52 Comment(0)
A
0

I found that for the specific use-case of detecting the enter key, setting the input's enterkeyhint to done fixed this issue for the "enter" key. Once I did this, its key code was no longer 229, but rather the correct "enter" code.

Alidaalidade answered 6/3, 2023 at 20:7 Comment(0)
L
-1

Solution to fix it for WebView, note it handles only space character , but you can extend mapping KeyEvent.KEYCODE_SPACE => keyCode.

class MyWebview: WebView {
    override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? {
        return BaseInputConnection(this, true)
    }

    override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
        val dispatchFirst = super.dispatchKeyEvent(event)

        // Android sends keycode 229 when space button is pressed(and other characters, except new line for example)
        // So we send SPACE CHARACTER(here we handles only this case) with keyCode = 32 to browser explicitly

        if (event?.keyCode == KeyEvent.KEYCODE_SPACE) {
            if (event.action == KeyEvent.ACTION_DOWN) {
                evaluateJavascript("javascript:keyDown(32)", null)
            } else if (event.action == KeyEvent.ACTION_UP) {
                evaluateJavascript("javascript:keyUp(32)", null)
            }
        }

        return dispatchFirst
    }
}
Liguria answered 18/9, 2019 at 7:49 Comment(0)
N
-12

Try e.which instead of e.keyCode

For more information on this property check https://api.jquery.com/event.which/

Ned answered 20/4, 2016 at 20:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.