blur event not firing on angular component
Asked Answered
F

2

16

I am trying to get a reactive form to properly handle blur events and it doesn't seem to react properly to blur.

import { Component, HostListener, HostBinding } from '@angular/core';

@Component({
  selector: 'app-combo-box-basic',
  templateUrl: './combo-box-basic.html'
})
export class ComboBoxBasic {

  @HostListener('blur', ['$event.target']) onBlur(target) {
    console.log(`onBlur(): ${new Date()} - ${JSON.stringify(target)}`);
  }
}
<div class="btn-group mr-3">
  <input (blur)="onBlur($event.target)" type="text" class="btn btn-outline-success">
  <div class="btn-group" ngbDropdown role="group" aria-label="Button group with nested dropdown">
    <button (blur)="onBlur($event.target)" class="btn btn-outline-primary" ngbDropdownToggle></button>
    <div class="dropdown-menu" ngbDropdownMenu>
      <button class="dropdown-item">One</button>
      <button class="dropdown-item">Two</button>
      <button class="dropdown-item">Four!</button>
    </div>
  </div>
</div>
Foundry answered 5/9, 2018 at 4:52 Comment(0)
F
17

After a lot of searching and experimentation I found a number of items that were needed to get it work properly. A fully functional demo can be found here

  1. The Outer element must have: tabindex="0" so that it is focusable. This is achieved with: @HostBinding('attr.tabindex') tabindex = '0';

  2. Adding a HostListener for blur events will catch outer component: @HostListener('blur', ['$event.target']) onBlur(target) { ... }

  3. You still need to catch the blur events for the inner components so that clicking in and out will still fire. (blur)="onBlur($event.target)"

import { Component, HostListener, HostBinding } from '@angular/core';

@Component({
  selector: 'app-combo-box-basic',
  templateUrl: './combo-box-basic.html'
})
export class ComboBoxBasic {

  // Make sure container can receive focus or else blur events won't be seen.
  @HostBinding('attr.tabindex') tabindex = '0';
  @HostListener('blur', ['$event.target']) onBlur(target) {
    console.log(`onBlur(): ${new Date()} - ${JSON.stringify(target)}`);
  }
}
<div class="btn-group mr-3">
  <input (blur)="onBlur($event.target)" type="text" class="btn btn-outline-success">
  <div class="btn-group" ngbDropdown role="group" aria-label="Button group with nested dropdown">
    <button (blur)="onBlur($event.target)" class="btn btn-outline-primary" ngbDropdownToggle></button>
    <div class="dropdown-menu" ngbDropdownMenu>
      <button class="dropdown-item">One</button>
      <button class="dropdown-item">Two</button>
      <button class="dropdown-item">Four!</button>
    </div>
  </div>
</div>
Foundry answered 5/9, 2018 at 4:52 Comment(0)
G
2

blur event does not fire on controls in formarray

The same problem i.e. blur event not firing, and the same solution as suggested by @ronnblack, in a different situation albeit: In my case, blur event was not firing under a formarray. blur event fired in development mode though, however in production build, blur event is not firing in input and select, did not check on others. Solution is the same, set tabindex="0" for containing div for formarray, and the event started firing. Just in case, if someone faces the same situation.

Gentilis answered 15/3, 2021 at 16:40 Comment(1)
WHAT? Thank you so much for this comment. I would have never figured this out otherwise.Longlongan

© 2022 - 2024 — McMap. All rights reserved.