PhoneGap Issue: Keyboard Scatters the UI on Exit

Here is a complete guide that will tell you everything you need to know about the PhoneGap issue and how you can solve it.

image

Technology

image

May 1, 2014

image

Barkan Saeed

image

 

Using PhoneGap with Jquery for an app that I was developing, I ran into an issue with a requirement that required a custom position of the header, footer, and content containers.

 

Using the CSS below, I was able to set the custom positions.
.ui-header {
position : fixed;
top : 0px;
left : 0;
width : 100%;
height : 50px;
}
/* specify content-height*/
.ui-content {
position : fixed;
height: 80%;
top : 50px;
right : 0;
bottom : 50px;
left : 0;
}
/* position footer at the bottom */
.ui-footer {
position : fixed;
bottom : 0px;
left : 0;
width : 100%;
height : 50px;
}
 

 

The CSS above does the job perfectly unless you add an input element on the page. When the input element gains focus, the keyboard (or a picker) is shown and the user is able to enter (or select) values. However, when the user finishes his input and is looking to close the keyboard overlay, he has two choices: click on the done button to hide the keyboard, or click on an empty area of the screen to close it. It is in the second case, that the UI scatters upon the keyboard hide. Actually, the UI-content container does not get resized correctly on hiding the keyboard via this method.
 

Solution

The solution to this problem is setting and resetting the position attribute of the relevant containers, and finally triggering a reset scroll that forces the window to redraw and correctly position all page elements. Here is the actual code that did the job for me:

 

$(‘input, textarea, select’)
.on(‘focus’, function (e) {
$(‘header, footer’).css(‘position’, ‘absolute’);
})
.on(‘blur’, function (e) {
$(‘header, footer’).css(‘position’, ‘fixed’);
setTimeout( function() {
window.scrollTo( $.mobile.window.scrollLeft(),
$.mobile.window.scrollTop() );
}, 20 );
});
});

 

Copying the above code on all screens carrying an input field solves the main issue. There is, however, one corner case that is not covered. When the user clicks directly on a navigating button instead of clicking on an empty screen area, the UI scatters again. This is resolved with the help of a timeout that gives the page time to redisplay before any navigation starts. The use of the following construct (in addition to the above code) is recommended to solve this issue.

Compile and run the app and it should work fine.