I am trying to get the screen dimensions of a just opened Angular Material dialog box. What is the best way to do that?
Background: I am using Angular Material 5.2.5 and am unable to upgrade. If a dialog box is too tall for the window, it gets clipped at the top and the bottom and there is no way to reach the action buttons at the bottom. See Dialog position and size problems on GitHub.
When the dialog opens, I would like to check its position to see if any part of it is off screen. If so, I will apply a class to make the dialog full-screen and adjust the scrollable parts so the users can get to everything. (Other ideas welcome.)
What I've Tried:
1. I tried using a template variable on a wrapper element:
<button mat-raised-button (click)="showDialog()">Click me to show dialog</button>
<ng-template #dialogTemplate>
<div #dialogFrame class="dialog-frame">
<div> ... dialog content ... </div>
</div>
</ng-template>
Then in the component's showDialog()
function:
...
export class dialogButtonComponent implements OnInit {
@ViewChild('dialogTemplate') private dialogModal: TemplateRef<any>;
@ViewChild('dialogFrame', {read: ElementRef}) private dialogFrame: ElementRef;
...
showDialog(config: MatDialogConfig = {}) {
this.dialogRef = this.dialog.open(this.dialogModal, dialogConfig);
const box = this.dialogFrame.nativeElement.getBoundingClientRect();
// this.dialogFrame is undefined when this executes
}
}
2. Based on this answer, I tried injecting MatDialogContainer to get a reference:
We also need to inject MatDialogContainer in our directive so that we can get initial position of dialog container. We have to calculate initial offset because Angular material library uses flex to center dialog and it doesn't get us specific top/left values.
Specifically:
const box = this.container['_elementRef'].nativeElement.getBoundingClientRect();
Where this.container
is the injected MatDialogContainer. I tried doing this in my component, but had trouble injecting it. I haven't worked with directives as much, so I'm looking into that.
3. On the dialogRef returned from opening the dialog box, access dialogRef._containerInstance._elementRef
:
...
const dialogRef = this.dialog.open(this.overlayModal, dialogConfig);
const dialogBoxElement = dialogRef._containerInstance._elementRef;
// dialogBoxElement now has an ElementRef that I can call getBoundingClientRect() on.
This actually works locally, but it won't build. The problem is that there's a Typescript error because "Property '_elementRef' is private and only accessible within class 'MatDialogContainer'."
I hope there is a simpler way to get the screen coordinates of an Angular Material dialog box. Any ideas?