The MatDialog
popup may be positioned relative to an element. In the example below, the dialog is opened below and to the left of the clicked button based on the button's bounding client rectangle. The element may be referenced via a template reference variable.
Then use MatDialogRef
method updatePosition
.
Main Component Template
<button #myButton></button>
Main Component
import { AfterViewInit, Component, ElementRef, OnDestroy, ViewChild } from '@angular/core'
import { DialogService } from './dialog.service.ts'
@Component({
selector: 'main-component',
templateUrl: 'main.component.html',
styleUrls: ['main.component.css']
})
export class MainComponent implements AfterViewInit, OnDestroy {
@ViewChild('myButton', { static: false }) public myButtonRef: ElementRef
constructor(private dialogService: DialogService) {}
public openDialog() {
dialogRef = this.dialogService.openDialog({
positionRelativeToElement: this.myButtonRef,
has_backdrop: true
})
this.dialogRef.afterClosed().subscribe(
() => {
...
this.dialogRef = null
}
)
}
}
dialog.component.ts
import { Component, ElementRef, Inject, OnInit } from '@angular/core'
import { MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'
@Component({
selector: 'dialog-component',
templateUrl: './dialog.component.html',
styleUrls: ['./dialog.component.css']
})
export class DialogComponent implements OnInit {
private positionRelativeToElement: ElementRef
constructor(public dialogRef: MatDialogRef<DialogComponent>,
@Inject(MAT_DIALOG_DATA) public options: { positionRelativeToElement: ElementRef }) {
this.positionRelativeToElement = options.positionRelativeToElement
}
ngOnInit() {
const matDialogConfig = new MatDialogConfig()
const rect: DOMRect = this.positionRelativeToElement.nativeElement.getBoundingClientRect()
matDialogConfig.position = { right: `10px`, top: `${rect.bottom + 2}px` }
this.dialogRef.updatePosition(matDialogConfig.position)
}
}
dialog.service.ts
import { ElementRef, Injectable } from '@angular/core'
import { MatDialog, MatDialogRef } from '@angular/material'
import { DialogComponent } from './dialog.component'
/**
* Service to create modal dialog windows.
*/
@Injectable({
providedIn: 'root'
})
export class DialogService {
constructor(public dialog: MatDialog) { }
public openDialog({ position_relative_to_element, user,
has_backdrop = false, height = '135px', width = '290px' }:
{
positionRelativeToElement: ElementRef, hasBackdrop?: boolean,
height?: string, width?: string
}): MatDialogRef<DialogComponent> {
const dialogRef: MatDialogRef<DialogComponent> =
this.dialog.open(DialogComponent, {
hasBackdrop: hasBackdrop,
height: height,
width: width,
data: { positionRelativeToElement: positionRelativeToElement }
})
return dialogRef
}
}