Search code examples
angularangular-materialfocusblur

How manage focus and blur in Angular 17 and Angular Materials


  1. I want to manage focus in my app. In login i want, thats field 'code' focused, after server return result 'true"

  @ViewChild('telephone') telephone!:ElementRef<any>
  @ViewChild('code') code!:ElementRef<any>
...
if (response.body.result) {
          this.frm.controls['codeField'].enable();
          this.renderer.selectRootElement('#code').focus()
}

HTML:
<mat-form-field class="codeField" >
        <mat-label>Code</mat-label>
        <span matPrefix> &nbsp;</span>
        <input type="text" matInput placeholder="00-00" mask="00-00" formControlName="codeField"  id='code' >
    </mat-form-field>

I have tried to use:

renderer.selectRootElement('#focus').focus()/click()
ElementRef.nativeElement.focus()/click()
MatInput.focus()/click()
  1. I want to manage blur in my app. I want, that's 'address' and the 'room' blurred, after user select.
@ViewChild('address') adressInput!: MatAutocomplete;
@ViewChild('room') roomInput!: MatAutocomplete;

TS:
address_is_selected(event: any) {
 this.address.blur()

HTML:
<mat-form-field layout-align='center center'>
                <input matInput placeholder="address" aria-label="address" [matAutocomplete]="address"
                        formControlName="adress" #addressInput/>
                    <mat-autocomplete #address="matAutocomplete" id="address" (optionSelected)="address_is_selected($event.option.value)">
                        <mat-option *ngFor="let addressof filteredaddress | async" [value]="address">
                            <span> {{ address}}</span>
                        </mat-option>
                    </mat-autocomplete>
            </mat-form-field>

I tried all of these methods, but no one of them can help me.


Solution

  • A template reference variable it's used to get the ViewChild, but it's not an html attribute. In .ts you use the variable and gets the ElementRef. but you use the "template reference variable" (without the "#")

    So if you write "see the #addressInput" in the "matInput"

    <input #addressInput matInput.../>
    

    You get it

    @ViewChild('addressInput') address!:ElementRef
    

    The elementRef.nativeElement is the HTMLElement

    So you simply use "javaScript"

       //see that you use the "variable"
       this.address.nativeElement.focus()
    

    Another way is "pass" the HTMLElement in your submit function, put be carefull, in this case the variable is the own HTMLElement

    <form [formGroup]="form"  (submit)="submit(form,addressInput)">
      ...
    </form>
    
    submit(form:FormGroup,el:HTMLElement)
    {
       ...do something, e.g....
       if (form.valid)
       {
           this.service.saveData(form.value).subscribe(res=>{
               if (res.succesfull)
                   el.focus() //<--see that directly
           })
       }
       else
       {
          form.updateValueAndValidity();
          el.focus()
       }
    }