'Ionic 4 keyboard covers input field
I have an Ionic 4 app that has a form with inputs in it.
When the user clicks on the input, it opens the keyboard, but it hides the content, without scrolling.
Is there any way around this?
This is my code:
<form #f="ngForm" (ngSubmit)="sendMail()">
<ion-item>
<ion-label position="floating">name
</ion-label>
<ion-input [(ngModel)]="senderName">
</ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">mail
</ion-label>
<ion-input [(ngModel)]="senderMail">
</ion-input>
</ion-item>
<ion-item class="borderedTextArea">
<ion-textarea [(ngModel)]="mailText" style="height:150px;"></ion-textarea>
</ion-item>
<ion-button type="submit" style="float:left">send</ion-button>
</form>
Solution 1:[1]
I'm currently using Ionic4 with Cordova 9 and all the latest packages, and I could not find any settings within the framework that worked for me. In the end I made this workaround that completely circumvents the framework. It has a little animation and looks pretty OK, so I'm using it until the framework solves this properly.
global.scss
ion-app {
/*animation of native keyboard show*/
transition: margin 300ms;
}
app.component.ts
declare var $: any;
ngAfterViewInit() {
// This element never changes.
let ionapp = document.getElementsByTagName("ion-app")[0];
window.addEventListener('keyboardDidShow', async (event) => {
// Move ion-app up, to give room for keyboard
let kbHeight: number = event["keyboardHeight"];
let viewportHeight: number = $(window).height();
let inputFieldOffsetFromBottomViewPort: number = viewportHeight - $(':focus')[0].getBoundingClientRect().bottom;
let inputScrollPixels = kbHeight - inputFieldOffsetFromBottomViewPort;
// Set margin to give space for native keyboard.
ionapp.style["margin-bottom"] = kbHeight.toString() + "px";
// But this diminishes ion-content and may hide the input field...
if (inputScrollPixels > 0) {
// ...so, get the ionScroll element from ion-content and scroll correspondingly
// The current ion-content element is always the last. If there are tabs or other hidden ion-content elements, they will go above.
let ionScroll = await $("ion-content").last()[0].getScrollElement();
setTimeout(() => {
$(ionScroll).animate({
scrollTop: ionScroll.scrollTop + inputScrollPixels
}, 300);
}, 300); // Matches scroll animation from css.
}
});
window.addEventListener('keyboardDidHide', () => {
// Move ion-app down again
// Scroll not necessary.
ionapp.style["margin-bottom"] = "0px";
});
}
Solution 2:[2]
<preference name="resizeOnFullScreen" value="true" />
You can install cordova-plugin-ionic-keyboard and edit your config.xml file and add this line of code
There is an Android bug that prevents the keyboard from resizing the WebView when the app is in full screen (i.e. if StatusBar plugin is used to hide the StatusBar). This setting, if set to true, add a workaround that resizes the WebView even when the app is in full screen.
Solution 3:[3]
I've solved this Ionic bug provisionally with:
...
<ion-texarea (ionFocus)="fixTextareaBug()">
...
and in your .ts
@ViewChild(IonTextarea)
public ionTextArea: IonTextarea;
private focusFix = false;
...
...
public fixTextareaBug() {
setTimeout(() => {
if (this.focusFix) {
this.focusFix = false;
return;
}
(this.ionTextArea as any).el.lastElementChild.blur();
this.focusFix = true;
(this.ionTextArea as any).el.lastElementChild.focus();
}, TEXTAREA_TIMEOUT);
}
I hope it solved your problem
Solution 4:[4]
I solve that by downgrading the keyboard plugin
ionic cordova plugin remove cordova-plugin-ionic-keyboard
ionic cordova plugin add [email protected]
and then remove the android platform and add it again
Solution 5:[5]
I was having that issue too but only in android, what i did was to create a script that get the height of the focused element and the keyboard, and using jQuery I added a marginTop to move the body above the keyboard when the keyboard shows, this is my code:
constructor(
private platform: Platform,
private keyboard: Keyboard
) {
if(this.platform.is('android')){
this.keyboard.onKeyboardShow().subscribe((e) => {
const offset = $(document.activeElement).offset().top;
let height = (offset - e.keyboardHeight)*-1;
height = height > 0 ? 0 : height;
$('body').animate({ 'marginTop': height + 'px' }, 100);
});
this.keyboard.onKeyboardHide().subscribe(e => {
$('body').animate({ 'marginTop': 0 + 'px' }, 100);
});
}
}
libs needed:
npm install jquery
npm install @types/jquery
ionic cordova plugin add cordova-plugin-ionic-keyboard
npm install @ionic-native/keyboard
imports
import { Platform } from '@ionic/angular';
import * as $ from "jquery";
import { Keyboard } from '@ionic-native/keyboard/ngx';
Is not an elegant solution but it works
Just some change in this code will give better experience
this.keyboard.onKeyboardShow().subscribe((e) => {
const safeArea = 40 ;
const offset1 = $(document.activeElement).offset().top;
const offset2 = window.innerHeight - e.keyboardHeight - $(document.activeElement).height() - safeArea ;
const diff = offset1 - offset2;
if(offset1 > window.innerHeight - e.keyboardHeight - safeArea)
$('body').animate({ 'marginTop': -1 * diff + 'px' }, 100);
});
Solution 6:[6]
Simply solve it with ionFocus event and scrollToBottom fuction and then call it in ionFocus so when you focus in input your content will scroll to bottomstrong text
Solution 7:[7]
you could try some combination of
ionFocus
https://ionicframework.com/docs/api/input#events and
scrollIntoView
https://developer.mozilla.org/de/docs/Web/API/Element/scrollIntoView if nothing else is working
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Reniel Gimeno |
Solution 3 | lokoxumusu |
Solution 4 | poimsm2 |
Solution 5 | dev.doc |
Solution 6 | Ibni Amin |
Solution 7 | D4NT3 |