43

I'm about to put a fist through my PC screen. I have a dialog box that refuses to budge a hot inch above my submit button at the bottom of the screen -- I want it at the very top.

I have made sure my theme is loading. That was validated here: ide loading of CSS

I have tried:

this.dialogBox.open(thankYouModal, {position: {top: '0%', left: '20%'}});

I've tried negative and positive numbers for top. The best I get is that I can shift the modal further down so the user has to scroll down to close it. However, that sucker won't budge a hair past the submit button

I've attempted to put a style sheet into the component with the following:

div#cdk-overlay-0.cdk-overlay-container{
    position: fixed !important;
    left: 20%;
    top: 0%;
    background-color: white;
    pointer-events: auto;
}

I cannot get this thing to budge an inch above that submit button. I will give someone my first born child if they help me figure out what I'm doing wrong.

(yes I know I'm dramatic, but I've fought with it and searched the web for 3 hours; I am a defeated man ... )

Edit

here is the thankYouModalComponent code:

import {Component} from "@angular/core";
import {MdDialogRef, MdDialogConfig} from "@angular/material";

@Component({
             selector: 'thank-you-modal',
             template: `
                                <h3>Thank You for Your Submission</h3>
                                <p>Your Feedback has been Saved.</p>
                                <button md-raised-button (click)="dialogRef.close()">Close</button>

                        `,
            styles: [`
                        .md-dialog-container {
                                            position: fixed !important;
                                            left: 20%;
                                            top: 0%;
                                            background-color: white;
                                            z-index: 100000;
                    }`]
})

export class ThankYouComponent{
    constructor(public dialogRef: MdDialogRef<any>, ) {}
}

Here's the calling method and constructor for the component:

constructor(@Inject(FormBuilder) fb : FormBuilder,
                 private feedbackService: feedbackService,
                 private dialog : MdDialog){

-------<irrelevant code here>------------

}



    submitFeedback(group : FormGroup){
            const feedback = new Feedback(  group.get('nameBox').value,
                                            group.get('productBox').value,
                                            group.get('upsBox').value,
                                            group.get('downsBox').value);

            if(confirm("Is the data entered what you want to submit?")){
                this.dialog.open(ThankYouComponent, {position: {top: '0%', left:'20%'}});

    }

Resulting dialog at bottom of form

Resulting dialog box at the bottom of the form despite requesting is show at top

FAISAL
  • 33,618
  • 10
  • 97
  • 105
Tom L'esperance
  • 764
  • 1
  • 6
  • 17
  • Any change for a working example of your issue, or at least the HTML markup that works with this? – Narxx Apr 18 '17 at 22:56
  • edited the OP for you. HTML is just a basic entry form with free form text fields. seems like the dialog box gets appended to the bottom of the html when it is called but the styles don't allow it to go above any elements on the original form. I can manually change the style I wrote in the OP in the webdev tools for chrome, and as soon as I set it to fixed position it works. I just can't get the style to stick to the dialog box when launched from the code. – Tom L'esperance Apr 19 '17 at 13:55
  • This seems to have been resolved in later versions. I'm using a config like your first example and the dialog is positioned with respect to the viewport. – isherwood Oct 31 '17 at 21:39

4 Answers4

58

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);
  });
}
mwilson
  • 12,295
  • 7
  • 55
  • 95
  • 1
    Works for me, nice guy – Paulo Gustavo Aug 09 '18 at 14:13
  • 1
    This is the real solution – Dev Db Aug 31 '18 at 06:00
  • 5
    This worked for me. The position stuff should be in documentation. – drav Sep 13 '18 at 16:28
  • 2
    That `MatDialogPosition` is in the documentation. The technique on how you would go about automatically positioning it is more of a specific use case so that is out of scope for angular documentation (IMO). – mwilson Sep 13 '18 at 16:35
  • It works but since this is relative to the window and not the button, if I resize the window the dialog will not move along with the button. Is there any way I can change this? – eddy Jun 13 '20 at 05:22
  • You will need to hook up the positioning logic into a window resize handler (or breakpoint observer). – mwilson Jun 15 '20 at 15:37
  • Just to reply to your comment @eddy, as already suggested by mwilson you could add an HostListener to his example @HostListener('window:resize', ['$event']) onResize(event: any) { this.updateModal(); } ngOnInit() { this.updateModal(); } private updateModal() { const rect = this.triggerElementRef.nativeElement.getBoundingClientRect(); const matDialogConfig: MatDialogConfig = new MatDialogConfig(); ...... – Emanuele Fricano Mar 27 '22 at 22:45
43

You can adjust position of dialog component using updatePosition() method of MdDialogRef. first import this line in your dialog component

import { MdDialog, MdDialogConfig, MdDialogRef } from '@angular/material';

in constructor use this

constructor(public dialModalRef: MdDialogRef<any>) { }

then from inside dialog modal component call this method anywhere you want

 changePosition() {
        this.dialModalRef.updatePosition({ top: '50px', left: '50px' });
    }

read more about it here https://material.angular.io/components/component/dialog

i hope this will help :)

Amit kumar
  • 6,029
  • 6
  • 30
  • 40
  • 1
    I don't think this will work for responsive design. Say that for desktops I will need to show to the right of the button and for mobile devices to the bottom. Is there any way I can do that? – eddy Jun 11 '20 at 04:03
23
const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
      width: '250px',
      data: { name: this.name, animal: this.animal },
      position: {
        top: '0px',
        left: '0px'
      }
    });
chevybow
  • 9,959
  • 6
  • 24
  • 39
Sehul Viras
  • 587
  • 5
  • 9
5

The styles from your component won't affect its parents. Since the dialog-container is the parent of your ThankYouComponent, it won't override its position.

As a workaround, you can add the positioning to your global styles.css.

⚠️ Caution though, this affects all of your dialogs! ⚠️

styles.css

mat-dialog-container {
  position: fixed;
  left: 20%;
  top: 0%
  background-color: white;
  z-index: 100000;
}
Kim Kern
  • 54,283
  • 17
  • 197
  • 195