5

I've been with this same problem for months and I still can't find a solution. I have an application where there are several forms, when focusing on an input field the keyboard covers this input field and the user cannot see anything. This only happens on iOS, on android everything works normal.

In this application I am using ionic 5 with capacitor.

This is how I would like my application to work: EXAMPLE 1

It is currently working like this: EXAMPLE 2

.HTML

<form [formGroup]="formSubmit" (ngSubmit)="formSubmit()">      
  <mat-form-field appearance="outline" class="field-style">
    <input matInput maxlength="35" class="input-form" placeholder="Agregar un alias (opcional)" formControlName="alias">
  </mat-form-field>
  <button mode="ios" class="btn-siguiente-enable" expand="block" type="submit" *ngIf="formSubmit.valid">Siguiente</button>    
</form>

.TS

ngOnInit() {
    this.initForms();

    Plugins.Keyboard.setScroll({isDisabled: true});

    Plugins.Keyboard.addListener('keyboardWillShow', (info: KeyboardInfo) => {
      Plugins.Keyboard.setResizeMode({mode: KeyboardResize.None});
    });

    Plugins.Keyboard.addListener('keyboardWillHide', () => {
      Plugins.Keyboard.setResizeMode({mode: KeyboardResize.Native});
    });
  }  

Any idea how to solve this?

Giannis
  • 1,790
  • 1
  • 11
  • 29
Angel Guillen
  • 531
  • 4
  • 11
  • Maybe this [topic](https://forum.ionicframework.com/t/keyboard-hides-input-until-i-start-typing/60827/2) can help you – antoineso Dec 24 '20 at 11:19
  • I'll try to do what you suggest there. But it seems like a lot of code and I have more than 10 forms in my application and the same thing happens in all of them. I think there should be a better alternative... – Angel Guillen Dec 24 '20 at 11:55
  • this part don't look so long [helper](https://forum.ionicframework.com/t/keyboard-hides-input-until-i-start-typing/60827/24) but ok . – antoineso Dec 24 '20 at 13:05

3 Answers3

4

I had this problem too and it was very problematic for my project. So I had three solutions for this

Solution 1 : In your app.component.ts, try forcing the focus on the element clicked like that :

      window.addEventListener('keyboardDidShow', (e) => {
        const elementFocused: any = document.querySelector(':focus');
        if (elementFocused) {
          elementFocused.blur();
          elementFocused.focus();
        }
      });

Adding these lines in the platform.ready method solved my problem for some cases.

Solution 2 : @Eliseo Like he said, adding margin-bottom to simulate the space for the keyboard is also a solution, but if you want to apply it in any input, add it in the app.component.ts using window.addEventListener('keyboardDidShow', (e) => {}); , you can test on keyboardDidShow but also focus event or blur

Solution 3 : Programmatically scroll on click.

I defined my variables like this on my .ts :

@ViewChild('scrollableContent', { static: false }) scrollableContent: ElementRef;
  private scrollContainer: any;

  ngAfterViewInit() {
    this.scrollContainer = this.scrollableContent.nativeElement;
  }
  private scrollToBottom(): void {
    this.scrollContainer.scrollTop = this.scrollContainer.scrollHeight;
  }

And then in my html, i'm doing

<div class="my-scrollable-content" #scrollableContent>
 <input (click)="scrollToBottom()">....</input>  // click event or focus
</div>

Or you can add the listener on your ts like that :

 window.addEventListener('keyboardDidShow', (e) => {
        const elementFocused: any = document.querySelector(':focus');
        if (elementFocused) {
          this.scrollToBottom();
        }
      });

It can sound like a little bit magic but that was the only solutions that worked for my case. The scroll method was the one working the best for me.

Shinichi Kudo
  • 345
  • 3
  • 15
1

why not enclosed your app in a div with, e.g. margin-bottom:300px? this makes that the keyboard has enougth space.

You can also make a directive that is applied to input type text that emit a value to a subject. If your main app listen the value you can get it

export class MarginDirective {
   @HostListener('focus', ['$event.target'])_(){
         this.auxService.marginSubject.next(true)
   }
   @HostListener('blur', ['$event.target'])__(){
         this.auxService.marginSubject.next(false)
   }
   constructor(private auxService:AuxService){}
}

Your service

@Injectable({
  providedIn: 'root',
})
export class AuxService {

  marginSubject:Subject<boolean>=new Subject<boolean>()
  constructor() { }

}

In your main.ts inject the servcie as public

   constructor(public auxService:AuxService){}

And

<router-outlet></router-outlet>
<div *ngIf="auxService.marginSubject|async" style="height:200px">

A fool of all of this in this stackblitz

Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • If margin-bottom is the solution ionic default app setting must be having this predefined – Naga Sep 02 '22 at 19:10
1

Although this question is two years old, there is a new, easy solution when using @capacitor/keyboard with ionic: The method scrollIntoView() easily allows you to move the current element into view. As soon, as the keyboard did show, you can simply run this method. I've implemented it this way:

Keyboard.addListener("keyboardDidShow", () => {
  if (document.activeElement) {
     document.activeElement.scrollIntoView({behavior: "smooth", block: "center"});
  }
});

As soon as the keyboard is being shown, the input element will automaticaly scroll into view.

Please note, that this will only work with resize set to KeyboardResize.BODYor KeyboardResize.IONIC.

Hope that will help someone.

SimaxDev
  • 11
  • 2
  • This worked for me just add the code in `capacitor.config.ts` to set `KeyboardResize.BODY` `plugins: { Keyboard: { resize: KeyboardResize.Body } }` – LuscaDev Jul 27 '23 at 21:07