input field hidden when soft keyboard appears in phonegap
Asked Answered
P

8

5

Creating a mobile application using Phonegap 3.6.3 for Android and iOS. The problem is only for Android, as iOS acts as I would like it to.

When I click on an input text field, or a textarea, a soft keyboard appears. It covers these elements sometimes.

The pages are placed within a iScroll, right at the bottom, and another absolute-placed div, thus I cannot scroll to either of these once the screen pops up. I suspect I have to change the webview to be smaller when the keyboard comes up. However, after trying many things, it isn't working.

config.xml

    <preference name="permissions" value="none" />
    <preference name="phonegap-version" value="3.5.0" />
    <preference name="orientation" value="default" />
    <preference name="target-device" value="universal" />
    <preference name="fullscreen" value="false" />
    <preference name="webviewbounce" value="true" />
    <preference name="prerendered-icon" value="false" />
    <preference name="stay-in-webview" value="false" />
    <preference name="ios-statusbarstyle" value="black-opaque" />
    <preference name="detect-data-types" value="true" />
    <preference name="exit-on-suspend" value="false" />
    <preference name="show-splash-screen-spinner" value="false" />
    <preference name="auto-hide-splash-screen" value="false" />
    <preference name="disable-cursor" value="false" />
    <preference name="android-minSdkVersion" value="13" />
    <preference name="android-windowSoftInputMode" value="adjustResize|stateHidden" />
    <preference name="android-installLocation" value="auto" />
    <preference name="SplashScreen" value="splash" />

(have tried many different values for android-windowSoftInputMode, as per example below)

    <preference name="android-windowSoftInputMode" value="stateVisible|adjustResize|adjustPan" />

head of web page

    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" />

(yes, I've tried many other things too)

anything else you may perceive as relevant, please let me know. Unfortunately, I'm not at liberty to share too much of the code, but from my understanding that's all we need to worry about.

Thanks,

Pistareen answered 18/2, 2015 at 4:27 Comment(1)
Try adding <style> <item name="android:windowTranslucentStatus">true</item> </style> in your pagePediatrics
P
4

Remove this line from config.xml

<preference name="android-windowSoftInputMode" value="adjustResize|stateHidden" />

And change the line in 'head of web page' to

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
Poisonous answered 18/2, 2015 at 4:47 Comment(4)
Thanks @MJB but sadly, to no avail. It made some divs scrollable to the end, but there is still a lot of the page blocked off by the soft keyboardPistareen
I'm thinking something has to be different because of the iscroll. The bottom of the iscroll is still at the bottom of the screen, thus I cannot scroll all the way downPistareen
thanks for your help, i realised that when i type, it does adjust the webview to focus on where I am typing at least - not ideal, but still effective, better than being completely hidden!Pistareen
I'm just glad I could help. Yes, it sort of scrolls the page further down (even though there's no space there) in order to make room for the keyboard instead of letting it covering the input fields.Poisonous
P
11

I too had the same problem - the underlying problem it seems is you can't edit the androidManifest file with cordova Build. All you can do is edit the config.xml file which really only allows you to change a limited subset of settings. What I would like is to be able to change the windowSoftInputMode.

I did find a solution to my problem. which was the keyboard appearing over fields at the bottom of the screen which I think is the same problem you're having. I have used the cordova 2.9.0 and cordova 3.6.0

Solution 1: The solution I found was to change this setting in config.xml

<preference name="fullscreen" value="false" />

This does with that setting set to "false" instead of "true" - the page now scrolls up to reveal the field you're editing when the keyboard opens. (to be more accurate, I believe the viewport changes rather than scroll up. Hope you are right on your viewport part)

Solution 2: Try remove or replace this line from config.xml

<preference name="android-windowSoftInputMode" value="adjustResize|stateHidden" />

as

<preference name="android-windowSoftInputMode" value="stateVisible|adjustResize"/>

instead. This works for me now.

Solution 3: Try adding this style to your page

<style> <item name="android:windowTranslucentStatus">true</item></style>

EDIT:

If your are using jQuery you can try that.

$('input, textarea, button, a, select').off('touchstart mousedown').on('touchstart mousedown', function(e) {
    e.stopPropagation();
});
Pediatrics answered 18/2, 2015 at 5:22 Comment(6)
Thanks @rajmathan, but still no dice. I'm thinking something has to be different because of the iscroll. The bottom of the iscroll is still at the bottom of the screen, thus I cannot scroll all the way downPistareen
Oh.ok. Try to override the input fields by adding input[type="text"] { -webkit-user-select: text; } to your css file which is active for mobile/tablet devices.Pediatrics
actually, putting that syle tag does make it move up now :s but it is stuck in that same webview. going to manually add it in and remove it depending on whether textarea is on focus or notPistareen
nope, not sure, that tag only made it work once - perhaps it was just a random bug that just went away magically (i think my app is doing that because so much going on) have tried suggestions in edit, sorry still no dice on that. the css method isnt the best as im actually using a plugin that goes over the textarea - called tinymcePistareen
if you are clueless. Try replicating the issue as a separate app. ie.)1.Create new project: "phonegap create autoScrollTest" 2. Change config.xml preference "fullscreen" to "false" 3. Add a bunch of input fields to index.html 4. Run "phonegap run android" and deploy it to a KitKat Android (also tested and verified with iOS 7) 5. Tap into one of the inputs at the bottom of the page.Pediatrics
thanks @rajmathan, tried that but to no avail. going to go with the other answer - see comment in there for details. Thanks for your effort.Pistareen
G
7

My solution was using Ionic keyboard plugin and implementing this code:

HTML:

<div id="page" class="page-content">
    ...         
</div> 

CSS:

.page-content {    
height: 100%;
overflow: auto;}

Javascript:

  • when keyborad is open

        window.addEventListener('native.keyboardshow', function (e) {
        var deviceHeight = window.innerHeight;
        var keyboardHeight = e.keyboardHeight;
        var deviceHeightAdjusted = deviceHeight - keyboardHeight;//device height adjusted
        deviceHeightAdjusted = deviceHeightAdjusted < 0 ? (deviceHeightAdjusted * -1) : deviceHeightAdjusted;//only positive number
        document.getElementById('page').style.height = deviceHeightAdjusted + 'px';//set page height
        document.getElementById('page').setAttribute('keyBoardHeight', keyboardHeight);//save keyboard height
    });
    
  • when keyboard is closed

        window.addEventListener('native.keyboardhide', function (e) {
        setTimeout(function () {
            document.getElementById('page').style.height = 100 + '%';//device  100% height
        }, 100);
    

To provide a better user experience, add this code for all inputs

var inputs = document.querySelectorAll('input');//select all input
var n = inputs.length;
for (var i = 0; i < n; i++) {
    var input = inputs[i];
    input.addEventListener('focus', function (e) {//add event focus
        var inp = this; 
       //wait 0.6 seconds to scroll down to the input has focus
        setTimeout(function () {
            try {
                //if the keyboard is open
                if (cordova.plugins.Keyboard.isVisible) {
                    var padding = 15;
                    var targetPosition = parseInt($$(inp).offset().top + padding);
                    var keyboardHeight = parseInt(document.getElementById('page').getAttribute('keyBoardHeight'));//get keyboard height   

                    //if the input is hidden by the keyboard,scroll to the input 
                    if (targetPosition >= keyboardHeight) {
                        padding *=5;
                        document.getElementById('page').scrollTop = targetPosition - padding;
                    }
                }
            } catch (ex) {
                alert(ex.message);
            }
        }, 600);
    }, true);
Gentianella answered 17/4, 2015 at 18:35 Comment(2)
Where do you set ion-content scroll= true? @AzmeerOperate
Adding event listeners to all elements and timeouts seems a bit inefficient. It is possible to achieve a similar effect using only the two events provided by the plugin, see this answer.Rettarettig
P
4

Remove this line from config.xml

<preference name="android-windowSoftInputMode" value="adjustResize|stateHidden" />

And change the line in 'head of web page' to

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
Poisonous answered 18/2, 2015 at 4:47 Comment(4)
Thanks @MJB but sadly, to no avail. It made some divs scrollable to the end, but there is still a lot of the page blocked off by the soft keyboardPistareen
I'm thinking something has to be different because of the iscroll. The bottom of the iscroll is still at the bottom of the screen, thus I cannot scroll all the way downPistareen
thanks for your help, i realised that when i type, it does adjust the webview to focus on where I am typing at least - not ideal, but still effective, better than being completely hidden!Pistareen
I'm just glad I could help. Yes, it sort of scrolls the page further down (even though there's no space there) in order to make room for the keyboard instead of letting it covering the input fields.Poisonous
S
2

I have the most efficient solution to scroll into input automatically and make it visible. First you need to add the keyboard plugin(cordova plugin add com.ionic.keyboard) as mentioned by @Fedir. Then on your event handler of 'keyboardshow' event add the following code:

window.addEventListener('native.keyboardshow', function(e){ 
    setTimeout(function() {
        document.activeElement.scrollIntoViewIfNeeded();
    }, 100);
});

P.S: This is supported only on Android (Chrome) and Safari. :D

Spongy answered 14/12, 2016 at 9:8 Comment(0)
C
0

Only one solution which worked for my full-screen app, it's to add to the Cordova application ionic-plugin-keyboard plugin

cordova plugin add com.ionic.keyboard

JS code :

// This event fires when the keyboard will hide
window.addEventListener('native.keyboardshow', keyboardShowHandler);

function keyboardShowHandler(e){
    $("body").addClass("keyboardOn");
}

// This event fires when the keyboard will show
window.addEventListener('native.keyboardhide', keyboardHideHandler);

function keyboardHideHandler(e){
    $("body").removeClass("keyboardOn");
}

After that You could adjust the view with CSS.

ref.: https://mcmap.net/q/964845/-cordova-3-4-detect-keyboard-event

Crusted answered 18/9, 2015 at 6:41 Comment(2)
Fedir, could please share the CSS with us.Discretion
@Discretion Normally, You don't need CSS, only the plugin and JS code.Crusted
S
0

My App uses the Android fullscreen / immersive mode. I have solved it by switching the the modes as soon as the keyboard appears/disappears.

I have installed the cordova-plugin-fullscreen and ionic-plugin-keyboard plugins and added this code:

document.addEventListener('deviceready', 
  function(){
    // disable immersive mode  on Android when keyboard is shown
        try {
      if (cordova.platformId == 'android') {
        AndroidFullScreen.immersiveMode(false, false);
        window.addEventListener('native.keyboardshow', function (e) {
          AndroidFullScreen.showSystemUI(false, false);

        });
        window.addEventListener('native.keyboardhide', function (e) {
          AndroidFullScreen.immersiveMode(false, false);
        });
      }
    } catch (error) {
      console.log('deviceready - ' + error);
    }
}, false);
Shanna answered 21/2, 2017 at 11:53 Comment(0)
R
0

I am using the Ionic Keyboard Plugin to detect when the keyboard is open and add necessary padding accordingly to the body:

phonegap plugin add ionic-plugin-keyboard --save

When the events fire, you can adjust the padding-bottom on the body to match the height of the keyboard.

Then, in order to detect if the focused element is visible, you have to do the math and scroll the container if necessary. The final code I am using is the following:

cordova.plugins.Keyboard.disableScroll(true);
$$(window).on('native.keyboardshow', function(e) {
    $$('body').css('padding-bottom', e.keyboardHeight + 'px');

    var el = $$('input:focus, textarea:focus');
    var content = el.closest('.page-content');
    var offset = el.offset().top + content.scrollTop();
    /* 15 is an arbitrary value to add a bit of padding */
    var safeAreaHeight = el.outerHeight(true) + 15;
    var maxPosition = content.height() - safeAreaHeight;
    if (content.scrollTop() < (offset - maxPosition)) {
            content.scrollTop(offset - maxPosition);
    }

});
$$(window).on('native.keyboardhide', function(e) {
    $$('body').css('padding-bottom', 0);
});

The code makes use of Framework7 and its Dom7 library which is very similar to jQuery. It assumes the scrollable element is .page-content, but you can adjust it accordingly.

You should leave the android-windowSoftInputMode preference at its default value.

Rettarettig answered 28/2, 2017 at 14:25 Comment(0)
R
-1

Just add following line to config.xml file, that's it..

<preference name="android-windowSoftInputMode" value="stateVisible|adjustResize"/>
Rickie answered 1/3, 2018 at 6:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.