21

I'm currently using the Angular Material cdkoverlay and want to close it when I click anywhere else on the screen except for the overlay. I've gone aheadand subscribed to backdropClick() but I can't get it to fire.

launchOverlay() {
        let strategy = this.overlay.position()
        .connectedTo(
            this._overlayOrigin,
            {originX: 'end', originY: 'top'},
            {overlayX: 'end', overlayY: 'top'} );
        let config = new OverlayConfig({positionStrategy: strategy, width: '280px', scrollStrategy: this.overlay.scrollStrategies.reposition()});
        this._overlayRef = this.overlay.create(config);
        this._overlayRef.attach(new TemplatePortal(this.filterTemplate, this.viewContainerRef));
        this._overlayRef.backdropClick().subscribe(() => this.close()}, () => console.log("ERROR"), () => console.log("COMPLETE"));
}

 close(){
    this._overlayRef.dispose();
}

<ng-template cdkPortal #columnFilter>
    <mat-card>
        HELLO WORLD
    </mat-card>
</ng-template>

Everything with creating and launching the overlay works fine, it's just responding to the outside click.

If I add hasBackdrop: true to OverlayConfig then it creates the dark grey backdrop and the click outside works, but I don't want a visiable backdrop, like the selete component.

DevEng
  • 1,114
  • 2
  • 15
  • 29

4 Answers4

25
hasBackdrop: true,
backdropClass: 'cdk-overlay-transparent-backdrop'

Adds the transparent backdrop inwhich the select and other components use.

DevEng
  • 1,114
  • 2
  • 15
  • 29
9

In case if someone is using template and directives then you can use cdkConnectedOverlayHasBackdrop and cdkConnectedOverlayBackdropClass directives.

And for transparent backdrop use the css class cdk-overlay-transparent-backdrop

<ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]="trigger" [cdkConnectedOverlayHasBackdrop]="true"
    [cdkConnectedOverlayBackdropClass]="'cdk-overlay-transparent-backdrop'" [cdkConnectedOverlayOpen]="isDropdownOpen"
    (backdropClick)="toggleDropdown()">
Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
4

For anyone that doesn't want/need a backdrop, you can use the overlayOutsideClick event emitter documented in https://material.angular.io/cdk/overlay/api#CdkConnectedOverlay :

<ng-template>
  cdkConnectedOverlay 
  (overlayOutsideClick)="close()"
</ng-template>
Yu Chia Wu
  • 876
  • 12
  • 14
1

There are a few ways but I'll tell you two of them when you want to handle it with code, not on HTML.

1. Dispose of the Overlay on the Backdrop Click

this.overlayRef.backdropClick().subscribe(() => { this.overlayRef.dispose();});

2. Dispose of the Overlay on Outside Pointer Event

With this one, you don't need to keep the backdrop and with this out of overlay would be clickable to take some actions. It's up to you. It works with a backdrop too.

this.overlayRef.detachBackdrop(); //detach backdrop to make clickable out of the overlay
//Event Listener Observable to dispose itself:
this.overlayRef.outsidePointerEvents().subscribe(() => {
      //maybe some actions that you could take  
    this.overlayRef.dispose();
    });