Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Ionic 2, how to float an element above the keyboard when the keyboard shows?

I want my message input bar to float above the keyboard when the keyboard shows but it looks like there's no keyboard-attach directive (like v1) in Ionic 2 yet (maybe in the works?). Is there any alternative/workaround?

Current behaviour:

Wanted behaviour:

Here's the code of my message input bar:

<ion-toolbar position="bottom" *ngIf="userIsAdmin">

    <form (ngSubmit)="onSubmit(f)" #f="ngForm" class="message-form">

        <ion-badge class="message-form-badge">Admin</ion-badge>

        <ion-input type="text" placeholder="Type a message..." ngControl="messageInput"></ion-input>

        <button type="submit" small class="message-form-button">Send <ion-icon name="send"></ion-icon></button>

    </form>

</ion-toolbar>
like image 750
nunoarruda Avatar asked Apr 19 '16 00:04

nunoarruda


3 Answers

I found a solution which works for me on IOS.

When you inspect the <ion-item> with <ion-input> in the browser(debugging use Safari for IOS) you can find that ionic generates a <div class='input-cover'> which has the style position: absolute;.

Write a CSS which overrides this as below

.input-cover {
  position: static;
}

This did the trick for me and now when you focus on an input field, it scrolls into view and does not hide below the keyboard anymore and all this works buttery smooth.

like image 194
Anees.jsdev Avatar answered Oct 31 '22 00:10

Anees.jsdev


I've also needed to implement this. I did it and it works perfectly.

1st you need to use cordova plugins keyboard, and at the start call cordova.plugins.Keyboard.disableScroll(true); so the keyboard will not push your view up. 2nd you need to listen on keyboardshow and keyboard hide events like this with a the handlers:

cordova.plugins.Keyboard.disableScroll(true);
                    window.addEventListener('native.keyboardshow', this.dispatchMe);
                    window.addEventListener('native.keyboardhide', this.dispatchMeHide);

    dispatchMe(e) {
        var event = new CustomEvent('keyboardShown');
        event['keyboardHeight'] = e.keyboardHeight;
        document.dispatchEvent(event);
    }

    dispatchMeHide() {
        var event = new CustomEvent('keyboardShown');
        event['closed'] = true;
        document.dispatchEvent(event);
    }

Than you can make an observable from event like this:

this.keyboardObservable = Observable.fromEvent(document, 'keyboardShown');

Than you can listen to that observable. If the keyboard is open than you change the height of the container where your messages are shown. You basically have to make it lower for the height of the keyboard. Here is how I did that

this.chatService.keyboardObservable
            .subscribe(data => {
                if (data.closed) {
                    this.sectionHeight = 85 + '%';
                    this.inputBottom = 0 + '%';
                }
                else {
                    this.docHeight = document.body.clientHeight;
                    this.sectionHeight = ((this.docHeight - data.keyboardHeight - (document.getElementById('toptoolbar').clientHeight + document.getElementById('inputchat').clientHeight)) / this.docHeight) * 100 + '%';
                    this.inputBottom = data.keyboardHeight / this.docHeight * 100 + '%';
                }

            });

and you change these properties with ngStyle like this

[ngStyle]="{'height': sectionHeight}"

I also needed this for chatapp, and now it works perfectly (even if you rotate the screen portrait/landscape mode), the input always floats above the keyboard just like in the native apps :)

I hope this will help you!

like image 22
Denko Mancheski Avatar answered Oct 30 '22 22:10

Denko Mancheski


The solution I ended up using and one that I'm satisfied with is:

  1. Removing Keyboard.disableScroll(true);
  2. Using a regular <input type="text"> instead of <ion-input type="text">

Works perfectly now!

like image 2
nunoarruda Avatar answered Oct 30 '22 23:10

nunoarruda