My Issue
I am currently in the process of writing an application for iOS using Cordova. I have a page with a form on it like so:
When the user taps on a field, the keyboard appears as expected on iOS. However, to prevent my app from moving off the screen, I have enabled the following setting:
// Prevent the keyboard from pushing up the webview
cordova.plugins.Keyboard.disableScroll(true);
Unfortunately, this prevents a few things that are causing me issues:
When a field is focused, the screen does not scroll to that field so sometimes, the field appears behind the keyboard.
Even if I did have a solution to the above, for the elements that are at the bottom of the screen, I will not be able to scroll down far enough to bring them into view above the keyboard.
My Question(s)
Solution 1
Is there any way, in Cordova, to auto scroll to the focused field without moving the whole app off the screen?
If it is possible, then how can I handle fields that are close to the bottom and cannot be scrolled up any further into view?
Obviously, the first point can be achieved using JavaScript/jQuery and some clever logic with the keyboard_height, position() and scrollTop(). But, this then creates the issue with the second point about the input fields behind the keyboard...
Solution 2
If I apply the following code, it will fix the issue highlighted above, but it will create another issue (explained below):
// Enable the auto scroll when the keyboard is shown
cordova.plugins.Keyboard.disableScroll(false);
Is there anyway to fix my header (the 'Edit Profile' bit), to the top of the screen to ensure that part is always visible?
Use https://www.npmjs.com/package/cordova-plugin-keyboard#keyboardshrinkview and its Keyboard.shrinkView method.
Related
I am working on an advanced search feature for a web project in React using the Algolia React Instant search package.
I am struggling a bit with keyboard navigation.
The search result features a long list of articles with various URLs. The list is very cumbersome to navigate only with the tab-key, so I have implemented navigation with the arrow-keys that works really great.
However, I have stumbled upon an issue I am unsure how to solve regarding focus-visible. When navigating with arrow keys a function inside the component will set focus using element.focus();
If I focus the search field with the mouse and start navigating with the arrow keys the focus-visible outline is missing. However, if I navigate to the search field with the tab key and start navigating with the arrow keys the focus-visible outline is visible.
This is according to specs, as focus() will not change to focus-visible and the last navigation was done with the mouse.
But this makes it impossible to navigate with the keys - you have no idea what element is in focus. Any idea how to force the browser into thinking that I am navigating with the keyboard when setting focus programmatically?
I ended up rethinking my styling and using a focus style.
But the behavior in Chrome is really weird.
If I set a style like focus:not(:focus-visible) it will be styled with the focus style when navigating with the mouse on focus, but not if I set focus with Element.focus() (and the focus was initially set on the active element with the mouse);
So the Chrome browser knows this was not navigated by a mouse? This makes absolutely no sense to me?
My iOS app uses a WKWebView with contenteditable = true on a specific div. I'd like to have code to make the keyboard show up for the web view, so the user can just start typing. Things I've tried that have had no effect:
Telling the web view to becomeFirstResponder (a long shot, because the web view wouldn't know what div to use).
Injecting JS to tell the div to focus(). (This works in other browsers, but sadly not in WKWebView)
Simulating touch events in JS via TouchEvent and dispatchEvent() in the hope of making it seem that the user had tapped on the div.
In the third case I also used addEventListener() to observe the simulated touches and compare them to real touch events from tapping the screen. It looks like the key difference is that the event's isTrusted value is false for the simulated touches.
I get that it's a potential security issue to let apps simulate touch events, but I didn't have any other ideas. I'm trying to get the keyboard to appear, what the user types is up to them and not something I want to mess with. Basically I want the same thing as calling becomeFirstResponder() on a UITextView.
This is very similar to a WebKit issue 142757 but I haven't figured out how to use the suggested workaround linked from there.
Clarification: I can set up and use an editable web view, but the keyboard doesn't appear until I tap on the web view. I'm trying to make the keyboard appear automatically, without requiring a tap to initiate editing.
I tried this in an iPad playground, and it works without any action on my part. It’s possible there is another view that is capturing touches, or “contenteditable” is misspelled, or something else?
When clicking on an an input type=text, a keyboard comes up. Unfortunately, that changes the height of the web page, so that all the thinks that were "stickied" to the bottom of the page want to come up above the keyboard.
And, in my case, the element that's anchored to the bottom of the page (e.g. the Apply button below) ends up covering the next input element (e.g. Max textbox), so that when the user presses Next on the virtual keyboard, you can't see it at all because the button is still covering it.
My question is whether there is any way to prevent the keyboard from changing the height of the page?
P.S. On iOS it works like you would expect. Bringing up the keyboard doesn't change the dimensions of the page.
It is default behavior on Android devices. As I know, you can not prevent this.
So I am using this plugin to prevent the whole webview from scrolling to the correct place on keyboard show when clicking on an <input> or <textarea> by doing:
cordova.plugins.Keyboard.disableScroll(true)
This works well, but I would like to be able to move it to the right spot manually, within the page using javascript/css. I assume it's a combination of using offset().top, while also adding more padding if the page height is too "short" and goes under the keyboard.
I want to understand how to capture user intent i.e. when a user decides to leave the page and moves his/her mouse (as of now), show them an alternate version (without refresh).
An example
When you open this page, it will show you a couple of listings. Now, if you move your mouse to the address bar again. It hides the content and shows a separate part of the layout, basically a modal window with some messaging.
Is it handled via javascript - detect the cursor position and change the layout.
Any help would be welcome.
Using document mouseleave and mouseenter you can achieve this.
$(document).on('mouseleave',function(){
$('#test').removeClass('disnone');
}).on('mouseenter',function(){
$('#test').addClass('disnone');
});
FIDDLE DEMO