Reputation: 2967
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>
Upvotes: 6
Views: 12761
Reputation: 1
WorkAround I haven't found a solution, but I discovered a workaround for the ion-input being covered by the keyboard problem, I just gave the ion-input a pointer-events:none;
ion-input{
pointer-events: none;
}
This solved the issue for me
Upvotes: 0
Reputation: 2914
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.
import * as $ from "jquery";
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";
});
}
Upvotes: 12
Reputation: 525
The following works for me to show the input box just over the keyboard. I am using Ionic 7 with react.
Using IonFooter
achieves that the content is at the bottom and not hidden. Using IonModal
with height equal to 'auto' achieves that the modal is just as tall as its content.
Important: You must add the following line to variables.css
so that the modal has an auto height.
ion-modal.auto-height {
--height: auto;
}
The example component:
export const TestPage: React.FC = () => {
return (
<>
<IonContent>
<IonText><h2>Content area</h2></IonText>
</IonContent>
{/* Added green background to make the footer/modal area visible for this example. */}
<IonFooter style={{ backgroundColor: 'green' }}>
<IonButton id="open-custom-dialog" fill='clear'>
<IonLabel>Open modal</IonLabel>
</IonButton>
<IonModal
breakpoints={[0, 1]}
initialBreakpoint={1}
handle={false}
trigger="open-custom-dialog"
className='auto-height'>
<IonList>
<IonItem>
<IonInput
label="Your input"
placeholder="Type here"/>
</IonItem>
</IonList>
</IonModal>
</IonFooter>
</>
);
}
Upvotes: 0
Reputation: 11
<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.
Upvotes: 1
Reputation: 141
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
Upvotes: 0
Reputation: 1
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
Upvotes: 0
Reputation: 21
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);
});
Upvotes: 1
Reputation: 562
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
Upvotes: 0
Reputation: 71
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
Upvotes: 0