user2324232322
user2324232322

Reputation: 353

Angular 4/5 | Dropdown directive

I am trying to create a dropdown directive which I can use to add dropdowns to any DOM element. I wrote this directive:

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

@Directive({
  selector: '[appDropdown]'
})
export class DropdownDirective {

  constructor() { }

  isOpen: boolean = false;

  @HostListener('click') toggle() {
    if (this.isOpen === true) {
      this.hide();
    } else {
      this.show();
    }
    this.isOpen = !this.isOpen;
  }

  private show() {
    // What to do here?
  }

  private hide() {
    // What to do here?
  }

}

This directive basically listens for a click on the DOM element it is applied to. When it registers a click I want to toggle the dropdown element that is in the same container as the element which I applied the directive to (by using the display property). My html code looks like this in a simplified form:

<a appDropdown>Dropdown</a>
<ul class="dropdown"> <--- How can I apply a display style property to this element when clicking the anchor (to hide/show the dropdown)?
   <li><a>Option A</a></li>
   <li><a>Option B</a></li>
</ul>

I read through the Angular docs carefully but it is not explained there.

I hope you get my problem. Thanks!

Upvotes: 0

Views: 7935

Answers (2)

sendon1982
sendon1982

Reputation: 11234

I think some Angular5 attribute should be included.

Please follow this link:

Building An Angular 5 Project with Bootstrap 4 and Firebase

Upvotes: -1

Alex
Alex

Reputation: 1137

It's my understanding that this isn't the correct use for directives. I'm trying to achieve a very similar output.

I'm trying to implement something similar, and reading through the documentation (and @evandro-mendes' answer above), structural directives are designed to alter the behavior of the DOM, without defining any templates themselves (see angular docs).

Look at https://github.com/valor-software/ngx-bootstrap/blob/development/src/dropdown/bs-dropdown.directive.ts (or the docs/demo https://valor-software.com/ngx-bootstrap/#/dropdowns) and they are using a directive to show/hide/manipulate the component, but not to declare its own content.

My solution, using ngx-bootstrap is to create a component as follows:

dropdown.component.ts:

@Component({
    selector: 'dropdown',
    template: './dropdown.component.html'
})
export class AutosuggestComponent {

    @Input() viewModel: string[];
    @Input() isOpen: boolean = false;
}

dropdown.component.html

<div dropdown [isOpen]="isOpen" [autoClose]="true" placement="top">

<ng-content #input>
</ng-content>

<div *dropdownMenu class="dropdown-menu" role="menu">
    <div *ngFor="let item of viewModel" class="dropdown-item">
        {{item}}
    </div>
</div>

usage

<dropdown [viewModel]="sourceData" [isOpen]="isDropdownOpen">
    <input type="text">
</dropdown>

This way I don't define any custom behaviour, and can still use the dropdown for any input within the app.

Hope this helps :)

Upvotes: 2

Related Questions