1

First of all, I know this has been asked A LOT with differente technologies, I've tried everything, for hours, and I still haven't been able to manage to make it work.

I have an angular 15 project, mixing Material and bootstrap 5 (no ng-bootstrap), made a simple form that has a button which displays a bootstrap modal window, everything's fine except I can't manage to set focus to a specific input after the modal is displayed.

Followed some examples and got a directive which sets the elementRef.nativeElement.focus() in ngAfterViewInit() with a timer, however, it doesn't work in the modal.

import { AfterViewInit, Directive, ElementRef, Input } from '@angular/core';

@Directive({
  selector: '[appAutoFocusDirective]'
})
export class AutoFocusDirective implements AfterViewInit {
  @Input() public appAutoFocus: boolean;
  constructor(private _elementRef: ElementRef){}

  public ngAfterViewInit(): void {
    setTimeout(() => {
      this._elementRef.nativeElement.focus();
    }, 500);
  }

}

If I use that directive in a normal input that's being displayed from the start it works like a charm, however, it doesn't happen with the modal.

What I noticed is that ngAfterViewInit() ALWAYS executes even if I don't click the button to display the modal so I'm assuming that it does apply the focus but the input is still hidden. If i set the timer to 3 seconds and I click the button to display the modal, it will set the focus to the input when the timer is done but I can't fix that behaviour.

As a note, the modal is in the same component as the main form (like in the bootstrap docs examples), I really want to do it this way because I really don't want to flood my project with hundreds of files nor hundreds of imports for each file.

I'm at a complete loss on what to do.

Hikaros
  • 101
  • 1
  • 12
  • are you sure your using a directive right? https://angular.io/guide/attribute-directives – Grant mitchell Dec 23 '22 at 23:49
  • @Grantmitchell yes, i'm 100% sure. I have applied the directive to 2 different inputs. One in the initial form as a test and one in the modal, the one in the initial form works fine. the one in the modal doesn't work. – Hikaros Dec 24 '22 at 00:01
  • 1
    have you tried this : this._elementRef.nativeElement.querySelector('input').focus(); – AmirHossein Rezaei Dec 24 '22 at 05:44
  • @AmirHosseinRezaei I went to try that and it didn't work as is, however, that gave me an idea of calling a method in the button that opens the modal with a timer that sets document.getElementById('Input').focus(); and that solved it. Thank you! – Hikaros Dec 24 '22 at 14:39

1 Answers1

-1

In case you are experiencing the same issue that I did, @AmirHossein Rezaei gave me the idea of accessing the form-control via query selector or getting it from document by id.

Instead of using a directive for the modal input, you can call a function with a timer from the button that opens the modal:

html:

<button class="btn btn-primary" 
    data-bs-toggle="modal" 
    data-bs-target="#Modal" 
    (click)="setInputFocus()">Open Modal</button>

component:

setInputFocus(): void {
    setTimeout(() => {
      document.getElementById('codeInput').focus();
    }, 500);
}

This solved the issue.

Hikaros
  • 101
  • 1
  • 12