matDialog doesn't open as dialog
Asked Answered
O

8

18

Instead of opening as a layover popup, it opens as a block on the bottom of the page left aligned.

I searched for similar problems, found this angular2 MdDialog is not appearing as a popup but also doesn't work.

Made a clean page, maybe it was some of my other css that interfered, but nope.

    <div>
  <h4 mat-dialog-title>New consultant</h4>
</div>
<mat-dialog-content>
  <div *ngIf="!allFieldsAreFilledIn()" class="alert alert-info">
    <strong>{{ getAddFeedback('emptyFields') }}</strong>
  </div>
  <div ngbDropdown class="d-inline-block">
    <button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle>{{ currentNewConsultant.user ? currentNewConsultant.user.lastName + " " + currentNewConsultant.user.firstName : activeUsers[0].lastName
      + " " + activeUsers[0].firstName }}</button>
    <div ngbDropdownMenu aria-labelledby="dropdownBasic1">
      <button class="dropdown-item" *ngFor="let user of activeUsers" (click)="updateNewConsultantProperty(user, 'user')">{{user.lastName + " " + user.firstName}}</button>
    </div>
  </div>

  <div ngbDropdown class="d-inline-block">
    <button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle>{{ currentNewConsultant.unitManager != null ? currentNewConsultant.unitManager.lastName + " " + currentNewConsultant.unitManager.firstName
      : unitManagers[0].lastName + " " + unitManagers[0].firstName }}</button>
    <div ngbDropdownMenu aria-labelledby="dropdownBasic1">
      <button class="dropdown-item" *ngFor="let um of unitManagers" (click)="updateNewConsultantProperty(um, 'unitManager')">{{um.lastName + " " + um.firstName}}</button>
    </div>
  </div>

  <div ngbDropdown class="d-inline-block">
    <button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle> {{ currentNewConsultant.profile ? currentNewConsultant.profile.name : userRoles[0].name}}</button>
    <div ngbDropdownMenu aria-labelledby="dropdownBasic1">
      <button class="dropdown-item" *ngFor="let profile of userRoles" (click)="updateNewConsultantProperty(profile, 'profile')">{{profile.name}}</button>
    </div>
  </div>

  <!-- Selecting Internal -->
  <div class="crudElement">
    <label class="crudLabel" style="padding-top: 7px;">Internal?:</label>
    <div class="btn-group crudEditElement" dropdown>
      <button type="button" class="btn green-button dropdown-margin-min-width" dropdownToggle>
        {{ currentNewConsultant.internal ? 'Internal' : 'External' }}
        <span class="caret"></span>
      </button>
      <ul *dropdownMenu role="menu" aria-labelledby="single-button" class="dropdownItems dropdown-menu dropdown-margin-min-width">
        <li role="menuitem" (click)="updateNewConsultantProperty('Internal', 'internal')">
          <a class="dropdown-item">Internal</a>
        </li>
        <li role="menuitem" (click)="updateNewConsultantProperty('External', 'internal')">
          <a class="dropdown-item">External</a>
        </li>
      </ul>
    </div>
  </div>

  <div class="form-group">
    <label for="hometown">Hometown:</label>
    <input type="text" class="form-control" name="hometown" [(ngModel)]="currentNewConsultant.hometown" required>
  </div>

  <div class="form-group">
    <label for="skills">Skills:</label>
    <input type="text" class="form-control" name="skills" [(ngModel)]="currentNewConsultant.skills" required>
  </div>

  <div class="form-group">
    <label for="comment">Comment:</label>
    <textarea class="form-control" name="comment" [(ngModel)]="currentNewConsultant.comment" required></textarea>
  </div>
  <div class="form-group">
    <label for="individualCost">Individual Cost:</label>
    <input type="number" class="form-control" name="individualCost" step="0.5" [(ngModel)]="currentNewConsultant.individualCost"
      required>
  </div>


  <!--ADDING / SAVING-->
  <div *ngIf="activeUsers && allFieldsAreFilledIn()">
    <button [ngStyle]="{'display' : (addConfirming ? 'none' : '')}" type="button" class="btn btn-success" (click)="save()">Add
    </button>
    <div [ngStyle]="{'display' : (addConfirming ? '' : 'none')}">
      <div>
        Are you certain you want to add the new Consultant {{ currentNewConsultant.user.lastName + ' ' + currentNewConsultant.user.firstName
        }}?
      </div>
      <button style="margin-right: 5px; margin-top: 10px;" type="submit" class="btn btn-danger " (click)="cancel()">
        <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
      </button>
      <button style="margin-top: 10px;" type="button" class="btn btn-success" (click)="save()">
        <span class="glyphicon glyphicon-check" aria-hidden="true"></span>
      </button>
    </div>
  </div>
  <div *ngIf="!activeUsers" class="alert alert-danger text-center" style="margin-top: 20px;">
    <strong>{{ getAddFeedback() }}</strong>
  </div>
</mat-dialog-content>

Styles.scss

@import '~@angular/material/prebuilt-themes/purple-green.css';

Open the dialog

private openDialog(): void {
    let dialogRef = this.dialog.open(CreateConsultantModalComponent, {
    });
  }

dialog component

    import { Component, OnInit, Output } from '@angular/core';
import { ConsultantService } from '../../../service/consultant.service';
import { UnitService } from '../../../service/unit.service';
import { ProfileService } from '../../../service/profile.service';
import { UserService } from '../../../service/user.service';
import { Consultant } from 'app/model/consultant.model';
import { Unit } from '../../../model/unit.model';
import { Profile } from 'app/model/profile.model';
import { User } from 'app/model/user.model';


@Component({
  selector: 'r-create-consultant-modal',
  templateUrl: './create-consultant-modal.component.html',
  styleUrls: ['./create-consultant-modal.component.scss'],
  providers: [ConsultantService, UnitService, ProfileService, UserService]
})
export class CreateConsultantModalComponent implements OnInit {

  public consultants: Consultant[] = [];
  public consultantsFilteredList: Consultant[] = [];
  public currentNewConsultant: Consultant = null;

  public units: Unit[] = [];
  public unitList: string[] = [];
  public userRoles: Profile[] = [];
  public unitManagers: User[] = [];
  public activeUsers: User[] = [];


  constructor(private consultantService: ConsultantService,
    private unitService: UnitService,
    private profileService: ProfileService,
    private userService: UserService) {
      this.getAllConsultants();
      this.getAllUnits();
      this.getAllRoles();
      this.getAllFreeAndActiveUsers();
      this.getAllUnitManagers();
      this.currentNewConsultant = new Consultant(null, null, null, null, null, true, 0, null, null, null, true, null);
      this.currentNewConsultant.unitManager = null;
     }


    ngOnInit() {

    }

    private getAddFeedback(emptyFields?: string): string {
      if (!emptyFields) {
        let message = "Can't add a Consultant without a ";

        if (!this.activeUsers) message += 'User';

        return message += '!';
      }
      return 'All fields are required!'
    }

    private updateNewConsultantProperty($event: any, property: string): void {
      switch (property) {

        case 'user':
        this.currentNewConsultant.user = $event;
          break;
        case 'internal':
        this.currentNewConsultant.internal = $event == 'Internal';
          break;
        case 'unitManager':
        this.currentNewConsultant.unitManager = $event;
          break;
        case 'profile':
        this.currentNewConsultant.profile = $event;
          break;
        default:
          console.log('NOT IMPLEMENTED for updateProperty on NEW Consultant');
      }
    }

    public cancel(){}

    private allFieldsAreFilledIn() {
      let c = this.currentNewConsultant;
      return c.user
        && c.internal
        && c.hometown
        && c.skills
        && c.comment
        && c.individualCost;
    }


  public save() {

    if (this.activeUsers) {
        this.currentNewConsultant.profile = new Profile(this.userRoles[0].id, this.userRoles[0].name, this.userRoles[0].rate);
        this.currentNewConsultant.user = this.activeUsers[0];
    }

    if (this.unitManagers) {
      let max = this.activeUsers.length;
      while (--max) {
        if (this.activeUsers[max].role.toUpperCase() == 'UM') {
          let um = this.activeUsers[max];
          this.currentNewConsultant.unitManager = new User(um.id, um.unit, um.userActivityLogs, um.email, um.password,
             um.firstName, um.lastName, um.shortName, um.employeeNumber, um.role, um.active);
        }
      }
    }

  }
  private getAllConsultants() {
    this.consultantService.getConsultants().subscribe(
      consultantList => {
        consultantList.forEach(c => this.consultants.push(
          new Consultant(
            c.id, c.user,
            c.profile, c.proposition,
            c.availableFrom, c.internal, c.individualCost,
            c.hometown, c.skills, c.comment, c.active, c.plannings, c.unitManager)
          )
        );
      },
      error => {
        console.log("Failed to get consultants data. Error message: " + error.message);
      }
    );
  }

  private getAllUnits() {
    this.unitService.findAllUnits().subscribe(
      unitList => {
        let unitNames = ['All'];
        unitList.forEach(unit => unitNames.push(unit.name));
        this.unitList = unitNames;
        this.units = unitList;
      },
      error => {
        console.log("Failed to get units data. Error message: " + error.message);
      }
    );
  }

  private getAllRoles() {
    this.profileService.findAllProfiles().subscribe(roles => {
      this.userRoles = roles;
    })
  }

  private getAllUnitManagers() {
    this.userService.findAllUnitManagers().subscribe(ums => {
      this.unitManagers = ums;
    })
  }

  private getAllFreeAndActiveUsers() {
    // Should be done in the backend but lack of time :'(, my apologies
    this.userService.findAllActiveUsers().subscribe(users => {
      const amountOfConsultants = this.consultants.length;
      const amountOfUsers = users.length;
      for (let j = 0; j < amountOfConsultants; j++) {
        for (let i = 0; i < amountOfUsers; i++) {
          const user = users[i];
          if (user && user.email === this.consultants[j].user.email && user.role === 'Admin') {
            users[i] = null;
          }
        }
      }

      for (let k = 0; k < amountOfUsers; k++) {
        const user = users[k];
        if (user) { this.activeUsers.push(user); }
      }
    })
  }



}
Outspoken answered 27/1, 2018 at 23:45 Comment(6)
Wana share the rest of your component? try to specify width of dialog inside curl brackets of this.dialog.open(..., {width: '250px'} )Indecency
Updated my post with new code. Even a brand new application with just Angular Material dialog gives that result, so I'm just missing something. But even a course on udemy can't help me.Outspoken
Your popup component is irrelevant, it's your app.module.ts where you're declaring it, and the component that calls itIndecency
you mean entryComponents array?Outspoken
app.module.ts as a whole, and the component or service that calls a function to open the dialog/popupIndecency
that was all fine, all the components are registered otherwise the page would not have rendered without errors. There were no errors and dialog showed up but just not as dialog but as a inline block on bottom of the page. Now that css is imported, everything works fine.Outspoken
I
2
  1. Make sure you're openning a dialog box with MatDialog service, and not rendering it using its selector r-create-consultant-modal


import {Component, OnInit} from '@angular/core';

import { MatDialog} from '@angular/material';
import {CreateConsultantModalComponent} from './create-consultant-modal.component';

Lets say component (or service) with function open

@Component({
  selector: 'app-debug-env',
  templateUrl: './debug-env.component.html',
  styleUrls: ['./debug-env.component.css']
})
export class DebugEnvComponent implements OnInit {

  constructor(public dialog: MatDialog) {}

  ngOnInit() { }

  private openDialog(): void {
    let dialogRef = this.dialog.open(CreateConsultantModalComponent, {

    });
  }

}

and html with simple button to call component function (or service function)

<button class="btn btn-primary" type="button" (click)="openDialog()">open</button>
  1. Declare your dialog box appropriately, you need to add it to declaration and entrycomponents


@NgModule({
  declarations: [
    CreateConsultantModalComponent,
    DebugEnvComponent,
  ],
  imports: [
    ...
  ],
  entryComponents: [CreateConsultantModalComponent],
  providers: []
})
  1. Baby steps see if you can launch a regular pop up, then change template to templateUrl to redirect to the html file.


import {Component, OnInit} from '@angular/core';

@Component({
  selector: 'r-create-consultant-modal',
  template: '<p> Pop Up </p>',
  providers: []
})
export class CreateConsultantModalComponent implements OnInit {

  constructor(){}
  ngOnInit(){}

}
Indecency answered 28/1, 2018 at 12:38 Comment(4)
The syntax for a material button is <button mat-button>Cardona
@Cardona what difference does it make? This is about dialog boxes not making angular material buttons.Indecency
I was almost about to use the dialog service of ng-bootstrap, but importing bootstrap css messed with the styling of the entire application. css wasn't imported for some reason. angular-cli.json said "styles": [ "../node_modules/font-awesome/css/font-awesome.css", "../node_modules/bootstrap/dist/css/bootstrap.min.css", "styles.scss" ],Outspoken
In my case the steps above weren't enough. The dialog did not show up (screen dimmed and got back to normal) until I added providers: [{provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: { }}] to my module definitionPalace
L
22

@Jay Cummins' answer worked for me. (Up voted but I couldn't reply to it to add this extra information)

I found that putting the style sheet in angular.json did not trigger the auto-build.

I was playing around, trying to figure why the styles would fix the problem, I found I could add this

@import '~@angular/material/prebuilt-themes/indigo-pink.css';

to the top of my styles.css. This triggers the rebuild and also fixes the problem.

Lode answered 8/2, 2019 at 12:7 Comment(0)
V
16

I had the same issue in my Angular 6 app. The solution was adding a pre-built theme to styles in the angular.json file styles property.

    "styles": [
      "src/styles.scss",
      {
        "input": "node_modules/@angular/material/prebuilt-themes/purple-green.css"
      }
    ]

enter image description here

Vinson answered 2/11, 2018 at 12:34 Comment(3)
This certainly works! But we really need to find out the core issue.Earthly
This helped me, I don't know why but now you need to import styles by yourself. It wasn't like that before :\Delectable
Very good. I spent a lot of time trying to find a solution, but it was a problem I caused and I didn't realize the error. It was this line in Angular.json that I had deleted. I put the line back in and it started working again.Degrease
C
14

Add in style.css:

@import "~@angular/material/prebuilt-themes/indigo-pink.css";
Concordat answered 6/9, 2019 at 10:7 Comment(1)
Why is this downvoted? This fixed the issue for me.Multiped
L
5

I had the same issue in Angular 8. I stopped ng serve and restarted it. It reloaded and started working properly

List answered 27/7, 2019 at 18:27 Comment(1)
This was my issue, I had to restart the app once I added angular materialsSubtotal
I
2
  1. Make sure you're openning a dialog box with MatDialog service, and not rendering it using its selector r-create-consultant-modal


import {Component, OnInit} from '@angular/core';

import { MatDialog} from '@angular/material';
import {CreateConsultantModalComponent} from './create-consultant-modal.component';

Lets say component (or service) with function open

@Component({
  selector: 'app-debug-env',
  templateUrl: './debug-env.component.html',
  styleUrls: ['./debug-env.component.css']
})
export class DebugEnvComponent implements OnInit {

  constructor(public dialog: MatDialog) {}

  ngOnInit() { }

  private openDialog(): void {
    let dialogRef = this.dialog.open(CreateConsultantModalComponent, {

    });
  }

}

and html with simple button to call component function (or service function)

<button class="btn btn-primary" type="button" (click)="openDialog()">open</button>
  1. Declare your dialog box appropriately, you need to add it to declaration and entrycomponents


@NgModule({
  declarations: [
    CreateConsultantModalComponent,
    DebugEnvComponent,
  ],
  imports: [
    ...
  ],
  entryComponents: [CreateConsultantModalComponent],
  providers: []
})
  1. Baby steps see if you can launch a regular pop up, then change template to templateUrl to redirect to the html file.


import {Component, OnInit} from '@angular/core';

@Component({
  selector: 'r-create-consultant-modal',
  template: '<p> Pop Up </p>',
  providers: []
})
export class CreateConsultantModalComponent implements OnInit {

  constructor(){}
  ngOnInit(){}

}
Indecency answered 28/1, 2018 at 12:38 Comment(4)
The syntax for a material button is <button mat-button>Cardona
@Cardona what difference does it make? This is about dialog boxes not making angular material buttons.Indecency
I was almost about to use the dialog service of ng-bootstrap, but importing bootstrap css messed with the styling of the entire application. css wasn't imported for some reason. angular-cli.json said "styles": [ "../node_modules/font-awesome/css/font-awesome.css", "../node_modules/bootstrap/dist/css/bootstrap.min.css", "styles.scss" ],Outspoken
In my case the steps above weren't enough. The dialog did not show up (screen dimmed and got back to normal) until I added providers: [{provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: { }}] to my module definitionPalace
F
1

I had the same problem and I solved it by adding angular material again as I skipped to add a theme at first. stop the application and run,

ng add @angular/material

select a theme and give yes to all the questions asked there after.

Fritts answered 31/3, 2021 at 8:8 Comment(0)
H
0

I had the same issue and hammerjs is the reason in my case. I just added that using npm i hammerjs --save (or npm i [email protected] --save) and it solved the issue. in my case in warnings this issue is poping up - Angular - 'Could not find HammerJS'

Hostility answered 4/12, 2020 at 7:46 Comment(0)
J
0

Add in styles.css/styles.scss

  1. @import "~@angular/material/prebuilt-themes/indigo-pink.css";

Not solved make sure you installed angular material and imported properly 2) install angular/material 3) import in app.module.ts file

In most of the dialog errors appears in not adding angular material themes in style.css/style.scss

Jaban answered 5/10, 2022 at 15:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.