Angular directive to toggle a Bootstrap dropdown button

Here is a directive working in Angular 9 and Bootstrap 4 for toggling a Bootstrap dropdown button.

The class that needs toggling is the .show class on the parent list item.

The directive code is as follows:

import { 
  Directive, 
  HostListener, 
  HostBinding 
} from "@angular/core";

@Directive({
  selector: "[appDropdown]",
  exportAs: "appDropDown"
})
export class DropdownDirective {
  private wasInside = false;

  @HostBinding("class.show") isOpen = false;

  @HostListener("click") toggleOpen() {
    this.isOpen = !this.isOpen;
    this.wasInside = true;
  }

  // https://stackoverflow.com/a/46656671
  @HostListener("document:click") clickout() {
    if (!this.wasInside) {
      this.isOpen = false;
    }
    this.wasInside = false;
  }
}

The HTML code is as follows:

<div class="btn-group">
    <button
      class="btn btn-secondary dropdown-toggle"
      type="button"
      id="dropdownMenuButton"
      data-toggle="dropdown"
      aria-haspopup="true"
      aria-expanded="false"
      appDropdown
      #r="appDropDown"
    >
      Actions
    </button>
    <div
      [ngClass]="{'show':r.isOpen}"
      class="dropdown-menu"
      aria-labelledby="dropdownMenuButton"
    >
      <a
        class="dropdown-item"
        (click)="onOption('One')"
        style="cursor: pointer;"
        >One</a
      >
      <a
        class="dropdown-item"
        (click)="onOption('Two')"
        style="cursor: pointer;"
        >Two</a
      >
    </div>
  </div>

The code creates a reference to the directive inside the element which submits the event of toggling and accessing it from where it is needed, the div.dropdown-menu element.

Got help from this SO anwser to get the event for clicking outside the element.

Back to bits

Comments