How can i control android keyboard in flutter inAppWebView and react? - javascript

I have a trouble with controlling the enter key with using InAppWebView in flutter.
there are issue with inputs which automatically move to next input with android keyboard.
i tried to make blur in react code with 'OnkeyDownCature' or 'OnkeyDown'. it works well.
however, the android enter key is different when there are next input like images above.
So, i want to change the android keyboard with react, js side.
<InputBox isFocus={isFocus} disabledProp={disabledProp} {...props}>
<Input
type={currentType}
ref={ref}
// onKeyDownCapture={onKeyDownCapture}
onKeyDownCapture={(e) => {
if(e.key === 'Enter'){
(document.activeElement as HTMLElement).blur();
e.stopPropagation();
}
}}
how can i control the android keyboard from react side through the InAppWebView in Flutter.

Related

Stop dictation on iOS using JavaScript

I'm working on a chat app and I'm facing a weird problem with the dictation feature on iOS.
Here is the scenario:
The user focuses the input field and starts to dictate some text (using the native dictation offered by iOS)
Now they click the send button, which creates the chat messages, clears the text of the input and focuses the input again (to enable the user to write the next message right away).
But the dication doesn't seem to be stopped. When the user clicks the input field again, the text that has already been sent will re-appear and anything the user said in the meantime will also show up.
Does anyone know how to tell iOS to stop the dictation (preferably using JavaScript but a solution in Swift would also help).
Thanks!
Jesse
Minimal example:
const input = document.getElementById('input');
const button = document.getElementById('button');
button.addEventListener('click', () => {
input.value = '';
input.focus();
})
<input id="input"/>
<button id="button">Send</button>
<ul>
<li>Open this page on iOS</li>
<li>Focus the input and start dication</li>
<li>Click send => input is cleared</li>
<li>Click on the input => text is entered again :(</li>
</ul>
https://codepen.io/jjd/pen/vYZMGBy
I had the same situation recently and managed to replicate it on some chat demos around the web with the same issue, and after digging up for a while, I found old answers as well as explanations to why that occurs (and why some solutions fails).
The key here is that the iOS dictation ends when:
User lose focus of the input (taps elsewhere).
User taps on the Done button of the iOS keyboard.
While in theory tapping your Send button should remove the focus from the chat input and finish the dictation, in practice the sequence between losing input focus and reverting it is so quick that iOS doesn't bother to finish the dictation, as it recovers the focus right away anyways. And plus, adding some delay to allow the iOS keyboard to finish will end up hiding the keyboard, which could end up closing and opening many times as you send messages and handle the focus manually, which is not desirable.
If you look here, you can see a quick explanation of the subject, with a possible solution for your problem, I tested most solutions in that thread and they still works as for iOS 14. The idea that worked for me is to remove the focus on an element and focus on a similar element to avoid hiding the keyboard, and then revert it back manually, with the difference that it must be asynchronous to guarantee a proper response from iOS. The way I did it was to create a dummy text input and redirect the focus to that:
const dummy = document.createElement('input');
dummy.setAttribute('type', 'text');
dummy.style.position = 'absolute';
dummy.style.opacity = 0;
dummy.style.height = 0;
document.body.append(dummy);
dummy.focus();
Then, set an async timeout to redirect to the real input element, clear input, etc:
setTimeout(() => {
input.value = '';
input.focus();
dummy.remove(); //Notice this
}, 100);
Is hacky, but it gets the job done. I have no idea how other websites/applications handle this situation, as I only tested native applications instead of websites. Perhaps their clean code doesn't have this issue in the first place? 😛

How to capture barcode hex code keystrokes in an input tag

I have a Datalogic Memor10 barcode scanner which looks and acts a lot like an Android phone, except that additionally it has a barcode scanner in the front. The barcode scanner can be triggered by pressing a key on the side of the Memor10. It also has a feature it calls a Keyboard Wedge which is luckily enabled by default, since I was unable to figure out how to get its complicated settings to be changed. The Keyboard Wedge apparently causes any scanned barcode to also be typed as keystrokes; so that, for example, when you have an input tag on a web application it will type the barcode into that input as keystrokes.
This works great for simple barcodes, however the barcode I would like to scan is an South African drivers license barcode which is encrypted with RSA encryption and therefore the keystrokes returned could be any byte character. This is a problem, since keystrokes such as Tab and Enter would leave the input field or submit by default.
The included form tag is only to prevent Oracle Apex's native form submission.
I have tried unsuccessfully to prevent this and just get the byte codes as hex characters with a simple input screen in Oracle Apex. My Javascript/jQuery/HTML code is currently the following:
Static content region:
<form method="POST" action="javascript:void(0);">
<input type="text" id="barcode" name="barcode">
</form>
On page load:
/*
$("#barcode").on('keyup', function(e) {
console.log(e.keyCode.toString(16));
e.preventDefault();
});
*/
$("#barcode").keypress(function(event) {
console.log(event.which.toString(16));
event.preventDefault();
});
However this does not work well, since Tab still leaves the input field and Enter works the first time and then stops working, only to start working again if you press another key inbetween. Not sure which other byte codes would cause issues. What code can I use to successfully capture the long string of byte codes sent as keystrokes to the input tag by the Memor10 barcode scanner? Or is there some other way of achieving this? I would like this to be a web application and not an Android native app.
The keypress event is fired when a character value is pressed down. Also, it is deprecated. You should use the keydown event, which is fired for all keys.
<form method="POST" action="javascript:void(0);">
<input type="text" id="barcode" name="barcode">
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
/*$("#barcode").on('keyup', function(e) {
console.log(e.keyCode.toString(16));
e.preventDefault();
});*/
$("#barcode").on('keydown',function(event) {
console.log(event.which.toString(16));
event.preventDefault();
});
</script>
This first snippet will help you prevent the tab character from causing damage.
Next, to see if there are issues with other key codes, I wrote a script which will fire an event for all key codes from 0 to 256.
$("#barcode").on('keydown',function(event) {
console.log(event.keyCode.toString(16));
event.preventDefault();
});
const el = document.getElementById('barcode')
for (let i = 0; i < 256; ++i) {
el.dispatchEvent(new KeyboardEvent('keydown',{'keyCode':i}));
}
<form method="POST" action="javascript:void(0);">
<input type="text" id="barcode" name="barcode">
</form>
<script
src="https://code.jquery.com/jquery-3.6.0.slim.min.js"
integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI="
crossorigin="anonymous"></script>
It seems to work. Now you can gather all key strokes in an array to recompose your bar code.

a11y & angularjs - windows screen reader overrides keydown event

im working on making a photo gallery app more accessible.
the app has a feature of showing expanded view of an image when clicked.
one of the a11y requirements is that when a user focus an image and click enter the expand mode will open and the focus will go inside the expanded view, and will be set on one of the buttons in it. it work's fine without screen reader, or with screen reader on mac. but on windows
when using screen reader it seems that the code that fires is the one that subscribed to the click event and not the keydown event. because the flag that suppose to be set to true on keydown is false (both events fire the same function but the keydown also add the enterClicked variable set to true).
this is the div that hold the image and subscribed to the events:
<div
tabindex="0"
id="{{media.id}}"
data-ng-repeat="media in row track by media.id"
data-ng-mouseenter="events.toggleVideoPlay(media.type, media.id, media.link, ( rowNummer ) * (row.length) + ($index + 1))" class="imgContainer"
ng-keydown="$event.keyCode == 13 ? events.openExpandMode(media.id, true) : null"
data-ng-click="events.openExpandMode(media.id)"
>
openExpandMode function:
$scope.events.openExpandMode = (mediaId, isEnterClicked) => {
const state = {
isEnterClicked,
mediasId,
currentIndex,
pagination: $scope.mediasPagination,
settings: {
isUserName: $scope.settings.user_name_checkbox,
isTemplate: !$scope.userConnected && !$scope.userConnectedWithOldApi,
isLikeComments: $scope.settings.like_comments_checkbox,
isDescriptions: $scope.settings.description_checkbox,
isComments: $scope.settings.comments_checkbox,
theme: $scope.settings.expand_theme,
lang: $translate.use()
}
};
localStorageService.set('state', state);
}
expand mode component init:
const _init = () => {
if ($scope.isOpenFromEnter) {
document.getElementById('nextArrow').setAttribute('data-focus-visible-added', "");
document.getElementById('nextArrow').className += ' focus-visible';
document.getElementById('nextArrow').focus();
}
}
is there a way to stop windows screen reader event interception ?
Short answer
It's common to send a click event instead of a press enter event.
The best is probably to adapt your code so that click and enter do the same thing, and that either or both event can be sent, because
you only have a quite limited influence on which is sent or not and when
Longer answer
You haven't indicated which screen reader you were using (Jaws or NVDA), but anyway, it's common for both to send a click event when pressing enter, instead of sending key events.
Reasons for that may seem strange and illogical at first, but there are at least two good ones:
It's certainly as much illogical to have two different things happening when clicking or pressing enter. IN all applications since GUI exist, most often, both do the same action (the only exception I can think of right now is multiline or rich text fields).
Scren readers existed before web accessibility, and accessibility is still rarely implemented nowadays. Sending a click event when pressing enter provide a minimal usability in all the places where designers didn't even thought that the keyboard could be used instead of the mouse.
By the way, screen reader or not, guess which event is sent if you press enter when the focus is on a link or a button?
Depending on the browser, the answer isn't unanimous as far as I know.
And on the screen reader side, it isn't unanimous either. Some even allow to configure the exact behavior to take, in order to adapt to different more or less unaccessible sites.
is there a way to stop windows screen reader event interception ?
You can stop some form of interception by calling preventDefault in your event listener function, if the click event is generated by the browser.
By doing so, you can actually do something different on click and on enter. But ask yourself first if it is really justified. Think about my first point above.
However, you can't prevent screen readers from intercepting keyboard events, translate them to something else and send or don't send them to your page.
There exists the ARIA application mode, but it has several important implications, so you shouldn't use it unless you have true good reasons.
To wrap up, the best is probably to adapt your code so that click and enter do the same thing, and that either or both event can be sent.
adding role="application" to the container div fixed it.

Cordova/Phonegap iOS - html5 input text type changed after application is sent to background

I am totally new in phonegap/cordova development and I have a problem with the keyboard on cordova webview for my app.
What I am trying to achieve is to have an input text with keyboard type that only shows numeric pad (which is type="tel") and also hides the characters that are typed into the input textbox (which is type="password"). What I have tried to achieve this behaviour is by changing the input type twice with javascript. Here's the code for that :
<script>
function changeInputType(){
document.getElementById("txtPin").setAttribute("type", "tel");
setTimeout(function(){document.getElementById("txtPin").setAttribute("type", "password");}, 750);
}
</script>
//here is how I use it on the html input
<input type = "tel" id="txtPin" onlick="changeInputType()" onkeypress="changeInputType()"/>
This dirty trick works fine when the user types on the textbox, but when the keyboard is present and I press the home button or do whatever that results to the app being sent to the background, and then I go back to open the app again, the keyboard type will change to the default text keyboard. And the javascript seems to not work anymore when I dismiss the keyboard and then open it up again by clicking on the textbox.
So, if anyone has any idea what I'm doing wrong here or has any suggestion on what I can do to fix this problem, please help.
Thank you! cheers!
I found out that to make the keyboard go back to numeric (type="tel") again is to call the javascript method on my AppDelegate through the current visible view controller like so :
//get the current visible view controller
UIViewController *viewController = ((UINavigationController*)self.window.rootViewController).visibleViewController;
if([viewController isKindOfClass:[MyViewController class]])
{
MyViewController *vc = (MyViewController *)viewController;
if(vc.webView respondsToSelector:#selector(stringByEvaluatingJavaScriptFromString:)
{
//call the javascript function on the webview
[vc.webView stringByEvaluatingJavaScriptFromString:#"changeInputType"];
}
}

How to keep on-screen keyboard from disappearing when focus changes from one text field to another

I've got an HTML5 app that uses a some input type="text" fields for entering text. I am catching keystroke events in order to link together certain fields.
I am having problems when testing this on any mobile device. Initially I tried it on an iPad using Safari or Chrome. However, later I also tried it on an android device running the latest version of Mobile Firefox and experienced the same problem.
The issue is that as soon as the input element changes, the on-screen keyboard goes away. I have tried doing this in several different ways but it always seems to produce the same effect - as soon as I focus() on a different text input, the keyboard disappears. This represents a serious impediment to flow, as it requires an extra motion to correctly re-select a text field that is already selected and should have focus and get keyboard input. On a small device such as a phone it is even worse, as all of this is accompanied by zooming and panning as the removal and re-display of the keyboard causes the page to re-render. This is similar in severity to what would happen if one's keyboard would stop working and require replugging every time one hit enter when editing a text document - it clearly would be a critical issue.
The following minimal code reproduces the problem:
<!doctype html>
<html lang="en">
<head>
<style type="text/css">
:focus { color: red; }
</style>
<script type="text/javascript">
function init() {
var tf1 = document.getElementById('tf1')
var tf2 = document.getElementById('tf2')
tf1.focus()
tf1.onkeydown = function(evt) {
if (evt.which == KeyEvent.DOM_VK_RETURN
|| evt.which == KeyEvent.DOM_VK_Q
|| evt.which == KeyEvent.DOM_VK_ENTER) {
tf2.focus()
if (evt.stopPropogation) evt.stopPropogation()
if (evt.preventDefault) evt.preventDefault()
return false
}
}
}
</script>
<body onload="init()">
<input type='text' id='tf1' value='field1' />
<input type='text' id='tf2' value='field2' />
</body>
</html>
First thing I note is that, while the initial focus() works (the element turns red) the on-screen keyboard does not appear. While this is troubling, it is not a huge deal to tap to initially tap a text field. However, as soon as I press any of the triggering keys (I have thrown an ordinary character in there to confirm that it doesn't matter what it is), suddenly the keyboard disappears. This doesn't make any sense to me, not only is a text element still focused, which requires the on-screen keyboard, but it was a keyboard event that changed the focus, which would suggest that the keyboard might still be needed - it's not like I did this from a delay or something.
I have tried onkeydown, onkeyup, and onkeypress - all exhibit the same behavior.
How can I keep the on-screen keyboard from going away? I have wasted a lot of time trying to get this one critical piece of functionality to work, and it still doesn't! Is there some sort of meta-tag I need to include or something? Or is the just a pervasive, cross-platform bug that all mobile devices have
try using the click() method instead of or after tf1.focus();
Like this:
tf1.click();
This may cause little to no software keyboard hiding.

Categories

Resources