Angular Multiselect Handling Outside Clicks

Home / Angular Multiselect Handling Outside Clicks

angular_small

In my last post regarding an Angular2 Multiselect dropdown, I showed how to integrate form validation. One of the last UI interaction pieces is handling clicks outside of the component. This is necessary to close the dropdown when, for example, a user clicks the document body.


The host property of an Anuglar2 component allows attaching event handlers for events that occur within the host (document body in this case). The multiselect component already has a host property set for host change event handling. To add a document click event handler, it looks like this within the @Component definition:

@Component({
    selector: 'multiselect',
    templateUrl: 'templates/multiselect.html',
    host: {'(change)': 'manualChange($event)', '(document:click)': 'hostClick($event)'},
    providers: [MULTISELECT_VALUE_ACCESSOR]
})

With that definition in place, when the document is clicked, our method called “hostClick,” within the component, will be executed. There is already a click handler on the dropdown button. Our “hostClick” event handler, then, can check that event target and only act when the target is not the component’s native element (button). The “hostClick” method will toggle the visibility of the dropdown when this condition is met and the dropdown is visible.:

  hostClick(event) {
   if (this.isOpen && !this._elRef.nativeElement.contains(event.target))
     this.isOpen = false;
  }

With these small additions, the multiselect dropdown will now behave the way we want with the visibility of the dropdown being toggled appropriately. The previous plunker has been updated and is below. The next thing I’ll be adding to the dropdown is a similar mechanism as is present in the Angular 1.x version to allow the dropdown to be attached to the body to eliminate formatting/DOM element shifting when the dropdown is expanded.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.