How can I position a dialog above the triggering button?

A better way to do this is to inject the button element and pass it into the dialog. This way, the dialog has the full context on how to size it up/position it (and leverage the element.getBoundingClientRect() function):

Dialog Component:

import { Component, ElementRef, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogConfig, MatDialogRef } from '@angular/material';

@Component({
  selector: 'app-dialog-component',
  templateUrl: './dialog.component.html',
  styleUrls: ['./dialog.component.scss']
})
export class MyDialogComponent implements OnInit {
  private readonly _matDialogRef: MatDialogRef<MyDialogComponent>;
  private readonly triggerElementRef: ElementRef;
  constructor(_matDialogRef: MatDialogRef<MyDialogComponent>,
              @Inject(MAT_DIALOG_DATA) data: { trigger: ElementRef }) {
    this._matDialogRef = _matDialogRef;
    this.triggerElementRef = data.trigger;
  }

  ngOnInit() {
    const matDialogConfig: MatDialogConfig = new MatDialogConfig();
    const rect = this.triggerElementRef.nativeElement.getBoundingClientRect();
    matDialogConfig.position = { left: `${rect.left}px`, top: `${rect.bottom - 50}px` };
    matDialogConfig.width="300px";
    matDialogConfig.height="400px";
    this._matDialogRef.updateSize(matDialogConfig.width, matDialogConfig.height);
    this._matDialogRef.updatePosition(matDialogConfig.position);
  }
  cancel(): void {
    this._matDialogRef.close(null);
  }
}

Usage:

onShowDialog(evt: MouseEvent): void {
  const target = new ElementRef(evt.currentTarget);
  const dialogRef = this._matDialog.open(MyDialogComponent, {
    data: { trigger: target }
  });
  dialogRef.afterClosed().subscribe( _res => {
    console.log(_res);
  });
}

Leave a Comment