bryan60
bryan60

Reputation: 29335

Angular CDK Connected Overlay, how to not cover the origin with the overlay backdrop?

I'm trying to create an overlay that connects to a row in a material table. I've got that working, but the issue is that I do not want the origin row it's connected to, to get covered by the overlay backdrop, but I do want the rest of the page covered by it. I've tried adding some padding to the element within the overlay and positioning to top, but this clearly didn't get it.

here is my row html:

<tr mat-row *matRowDef="let element; columns: columnsToDisplay;"
  cdkOverlayOrigin
  #row
  (click)="setOverlay(row)">

and some test code to set the overlay:

  @ViewChildren(CdkOverlayOrigin)
  orgins: QueryList<CdkOverlayOrigin>;

  @ViewChildren('row')
  rows: QueryList<ElementRef>;

  constructor(private _overlay: Overlay) {}

  setOverlay(row) {
    let idx = this.rows.toArray().findIndex(e => e === row);
    let origin = this.orgins.toArray()[idx];
    const positionStrategy = this._overlay
        .position()
        .connectedTo(origin.elementRef, 
          {originX: 'start', originY: 'top'}, 
          {overlayX: 'start', overlayY: 'top'});

    const overlayRef = this._overlay.create({
        width: origin.elementRef.nativeElement.clientWidth,
        hasBackdrop: true,
        positionStrategy,
        scrollStrategy: this._overlay.scrollStrategies.reposition()
    });

    overlayRef.backdropClick().subscribe(() => overlayRef.detach());

    const overlayPortal = new ComponentPortal(TestOverlayComponent);

    overlayRef.attach(overlayPortal);
  }

and here's a blitz where I've been playing with it all: https://stackblitz.com/edit/angular-8sqnol?file=app%2Ftable-expandable-rows-example.ts

note: an expandable row is NOT what I'm after here. I need the overlay behavior where the overlay covers the entire table and does not push it down.

I'd appreciate any help / advice. I'm not convinced this is possible with the current approach. Wondering if I need to somehow limit the overlay backdrop to only come down to the top of the overlay and then create the rest of the backdrop as part of my actual overlay.

Upvotes: 2

Views: 14367

Answers (2)

im.pankratov
im.pankratov

Reputation: 1888

The way CDK overlay works is that it creates <div class="cdk-overlay-container"> right before the closing </body> tag. Overlay container has following css rule:

.cdk-overlay-container {
  position: fixed;
  z-index: 1000;
}

So in order to make any element be above the overlay container, you can use couple CSS rules, for example:

.show-above-overlay {
  position: relative; // *
  z-index: 1001; // This should be enough
}

* You can read More on why we need to specify relative in this article.

Now you need to attach that class to the desired element (best way to do so when overlay is shown):

<div
  cdkOverlayOrigin
  [ngClass]="{ 'show-above-overlay': panelOpen }"
  (click)="setOverlay()">
</div>

where panelOpen is boolean variable that reflects overlay state.


I've also tried to make your stackblitz example work and it looks like table require more fiddling simply because it won't allow to restack single row. It's probably worth to try alternative html variant of CDK table.

Upvotes: 1

Shah
Shah

Reputation: 565

I have added this in your code..

  if(this.isAllSelected()){
          this.selection.clear();
          // this.isButtonEnable = true;
      }else{
          this.dataSource.data.forEach(row => this.selection.select(row));
          // this.isButtonEnable = false;
  }

For more you can look here stackblitz

Upvotes: 0

Related Questions