0

I've referred to this other walk through and am not able to understand exactly how it works. I've added this into my ts file:

@Component({
  host: {
   '(document:click)': 'onOutsideClick($event)',
  },
})

class SomeComponent() {
  constructor(private _eref: ElementRef) { }

  onOutsideClick(event) {
    console.log('click')
    if(!this._eref.nativeElement.contains(event.target)){
      this.companyResults = null;
  }
}

And want to apply it to this dropdown in HTML where someone will have the ul data set to null when clicked outside.

<input id="positionCompanyName" name="companyName_{{i}}" class="search-input"
     [(ngModel)]="candidate.positions[i].company_name"
     (keyup)="$event.target.value && searchCompany$.next($event.target.value)">
       <ul class="search-dropdown-ul" *ngIf="companyResults && positionIndex === i">
         <a class="search-dropdown-div" *ngFor="let companyResult of companyResults" (click)="addCompany(companyResult, i)">             
          <li class="search-dropdown-li">
            {{ companyResult.name } 
           </li>
          </a>
        </ul>
Kenzo
  • 367
  • 2
  • 5
  • 21

1 Answers1

1

ElementRef (in the constructor) gives you a reference to the native element (DOM element) of the component itself.

  if(!this._eref.nativeElement.contains(event.target)){
  }

This part checks if you clicked on any part of the component, and this isn't something you want. You can check if you clicked on search-dropdown-ul by using a @ViewChild So, in the HTML, you declare that something is a ViewChild

<ul #list class="search-dropdown-ul" *ngIf="companyResults && positionIndex === i">

Note the #list. Now in the component, you reference it by saying

 @ViewChild('list') list: ElementRef;

And finally, you see if it's clicked:

if(!this.list.nativeElement.contains(event.target)){
  //do your thing here
}
Stefa
  • 656
  • 5
  • 13
  • It works! But I am getting a console error saying cannot read nativeElement of undefined. Do I have to call #list somewhere else? – Kenzo May 23 '18 at 21:28
  • are you available to check? – Kenzo May 24 '18 at 14:37
  • 1
    @ViewChild is a decorator, meaning Angular will wrap you typescript class with another class that knows how 'wire' that view child. The error you are getting is because of *ngIf="companyResults && positionIndex === i" ngIf will add elements to DOM when condition is true, and remove them otherwise. The element #list is destroyed, and you check if it's clicked on it, and that element doesn't exist. To handle this, you add https://angular.io/api/core/ChangeDetectorRef to the constructor and after the conditions are set to show the #list, call detectChanges() from changeDetectorRef. – Stefa May 24 '18 at 19:27