I’m trying to troubleshoot why it seems not possible to detect a shift+Enter combination from JavaScript in a simple textarea from popular mobile operating systems.
The core problem is: classic web application that assumes Enter to submit, and shift+Enter for newline, that has problems only with Android.
Basically the code was just the following one:
<textarea id="my-textarea"></textarea>
var myInput = document.getElementById( 'my-textarea' );
myInput.addEventListener('keyup', function(e) {
// if pressing "Enter"
if( e.keyCode == 13 ) {
// and if pressing "shift"
if (e.shiftKey) {
// just a new line
// this does not work on Android
} else {
// submit
}
}
} );
As I will show, it seems this works just as expected in any browser but Android, that never has shiftKey
to any truly value.
You can verify on yourself using this nice tool:
https://w3c.github.io/uievents/tools/key-event-viewer.html
Event table of "shift+Enter" on most devices
If I understand correctly this is the supposed JavaScript event table on most devices:
https://w3c.github.io/uievents/tools/key-event-viewer.html
The above correct situation was verified in:
- desktop, physical keyboard, Linux, Firefox 111
- desktop, physical keyboard, Linux, Chromium 111
- mobile, Android 11 LineageOS, virtual keyboard "Hackers Keyboard", with stock browser
- mobile, Android 11 LineageOS, virtual keyboard "Hackers Keyboard", with Firefox 110
- feel free to add other devices but I’m quite sure that this is the very correct behavior
Event table of "shift+Enter" on Android stock keyboard: bug?
But, on many Android devices with the default virtual keyboard, the shift+enter seems just undetected from JavaScript:
https://w3c.github.io/uievents/tools/key-event-viewer.html
The above problematic situation was reproduced on:
- mobile, Android 11 LineageOS, stock keyboard AOSP, Firefox 110
- mobile, Android 11 LineageOS, stock keyboard AOSP, DuckDuckGo browser
- mobile, Android 11 LineageOS, stock keyboard AOSP, stock browser
Note that, for all of these problematic cases, I used the default keyboard (stock Android AOSP keyboard). So it really seems like a bug that doesn’t have anything to do with JavaScript and it doesn’t have anything to do with my anyone web development skills.
How are you pressing shift+Enter on a virtual keyboard?
Note that I think most virtual keyboards support a simple a way to type the shift+Enter combination. Common examples:
- holding down left shift with a finger, and pressing Enter with another finger
- double tap on shift (so that it stays active) then tap on Enter
- dragging from shift, dropping on Enter (this is a valid gesture for example to write an uppercase letter)
For example here you see I double-tapped the left shift (that assumes a more-prominent color), then I pressed Enter.
This specific screenshot comes from Android 11 AOSP which is the one that does not send the shift+Enter combination correctly. Even if, as you can see, it seems just like any other keyboard supporting the shift key (just like the iPhone virtual keyboard, for example, that works instead).
Resources
- https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key – Mozilla Web Documentation has a very useful page to explain what should happen, and that indicates that what I’m seeing on the Android keyboard does not adhere to the standard
- https://developer.mozilla.org/en-US/docs/Web/API/Element/keydown_event – complete documentation to the
keydown
keyboard event - https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/shiftKey – description of the specific flag that should reflect the status of the shift key (and that it simply does not seem to work on this version of this Android keyboard)
- https://github.com/valerio-bozzolan/dom-event-viewer/commit/4a48a9a92818ea5bd31260326dbbc54a5c3c3e45 – I’ve also forked the DOM Event Viewer to test
<textarea>
elements as well as the default<input type="text" ... />
element and yes, I can reproduce the same results even with that element
Questions
- Is there any known workaround that could be suggested to JavaScript programmers in this situation, to identify shift+Enter from Android default keyboard?
- Is this in your opinion a bug in Android? If yes, is it known any upstream issue in Android AOSP?
2
Answers
My friend, your JavaScript problem is very probably not fixable by JavaScript.
You got yourself into a cosmic trap since this seems and just related to the default keyboard on most Android phones: the Android AOSP keyboard.
Official homepage / Source code:
https://android.googlesource.com/platform/packages/inputmethods/LatinIME/
Why this happens
As mentioned by the user @padeso, probably the root cause is that the backend of the Android AOSP keyboard does not support multi-key events even though its frontend makes it look like. You may be interested in following this bug report on the Google issue tracker:
https://issuetracker.google.com/issues/276611340
Edited: it seems this issue is now assigned to a person in Google.
How to verify if your Android is affected
It's very probable that your Android has this keyboard, and so, you are probably affected.
Anyway here is how to check if you have this problematic virtual keyboard:
com.android.inputmethod.latin
)Workarounds
There is no JavaScript workaround to detect the shift+Enter combination and there are really no "alternative events" to detect that. The only concrete fix is contacting your Android users to abandon their default AOSP keyboard and install a "normal" one but - obviously - this is not a feasible option for any website.
I mean, can you really expect to ask such variation to visitors of your website? «To visit this website, change keyboard, yours is bugged.» That would really fix, but it's not feasible.
So? What do you suggest now?
Probably more than a billion Android devices, at the moment, are affected by this problem. This is not something a JavaScript developer should fight. Give up.
My advice is: avoid relying on the distinction of these two cases on mobile. So, avoid stuff like "send with Enter" and "add newline with shift+Enter". On mobile, make sure the Enter key always just adds a newline, and make sure to have a dedicated button to "submit" (not just the Enter key).