1

I'm implementing a bootsrap's single button dropdown (docs).

In order to make it to be "open", it must add a show class to main <div> and to the <ul>.

This is closed:

<div class="btn-group">
  <button
      type="button"
      class="btn btn-primary dropdown-toggle">
      Manage (Using Directive) <span class="caret"></span>
    </button>
  <ul class="dropdown-menu">
    <li><a style="cursor: pointer;">Edit </a></li>
    <li><a style="cursor: pointer;">Delete </a></li>
  </ul>
</div>

This is open:

<div class="btn-group show">
  <button
      type="button"
      class="btn btn-primary dropdown-toggle">
      Manage (Using Directive) <span class="caret"></span>
    </button>
  <ul class="dropdown-menu show">
    <li><a style="cursor: pointer;">Edit </a></li>
    <li><a style="cursor: pointer;">Delete </a></li>
  </ul>
</div>

I'm trying to make it work as a directive with:

<div class="btn-group" appDropdown>
  <button
      type="button"
      class="btn btn-primary dropdown-toggle">
      Manage (Using Directive) <span class="caret"></span>
    </button>
  <ul class="dropdown-menu">
    <li><a style="cursor: pointer;">Edit </a></li>
    <li><a style="cursor: pointer;">Delete </a></li>
  </ul>
</div>

And the dropdown.directive.ts:

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

@Directive({
  selector: '[appDropdown]'
})
export class DropdownDirective {
  @HostBinding('class.show') isOpen = false;

  @HostListener('click') toggleOpen() {
    this.isOpen = !this.isOpen;
  }
}

This way I'm only able to add the show class to the <div> without adding it to the <ul>, Is there a way to affect the directive children?

Here is a StackBlitz

This is a related question, but it does not mention any @HostBinding

Shahar Shokrani
  • 7,598
  • 9
  • 48
  • 91

1 Answers1

1

I came across this post when I was looking for the answer to the same question. I solved the issue myself using ElementRef. I'm fairly new to Angular but coming from a React background I thought if the 'Ref' in element ref is similar to Refs in React then it should have HTML attributes & properties, specifically querySelector.

So if anyone else is stumped on this, this can serve as a solution.

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

@Directive({
  selector: '[appDropdown]',
})
export class DropdownDirective {
  constructor(private dropdownRef: ElementRef<HTMLElement>) {}

  @HostListener('click') toggleOpen = () => {
    this.dropdownRef.nativeElement
      .querySelector('div')
      .classList.toggle('hidden');
  };
}
Jose Munoz
  • 56
  • 1
  • 3