blur event not firing on angular component

RonnBlack picture RonnBlack · Sep 5, 2018 · Viewed 10.1k times · Source

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

Answer

RonnBlack picture RonnBlack · Sep 5, 2018

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>