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); }
      }
    })
  }



}
user1008531
  • 491
  • 2
  • 8
  • 17
  • Wana share the rest of your component? try to specify width of dialog inside curl brackets of this.dialog.open(..., `{width: '250px'}` ) – Iancovici Jan 28 '18 at 01:09
  • 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. – user1008531 Jan 28 '18 at 09:06
  • Your popup component is irrelevant, it's your app.module.ts where you're declaring it, and the component that calls it – Iancovici Jan 28 '18 at 12:26
  • you mean entryComponents array? – user1008531 Feb 01 '18 at 11:59
  • app.module.ts as a whole, and the component or service that calls a function to open the dialog/popup – Iancovici Feb 01 '18 at 12:05
  • 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. – user1008531 Feb 01 '18 at 12:10

8 Answers8

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.

J. Chaney
  • 341
  • 4
  • 11
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

Jay Cummins
  • 1,039
  • 2
  • 14
  • 31
  • This certainly works! But we really need to find out the core issue. – Sarang Nov 28 '20 at 10:08
  • This helped me, I don't know why but now you need to import styles by yourself. It wasn't like that before :\ – Massaget Jan 08 '21 at 00:52
  • 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. – Leandro Feb 27 '22 at 21:23
14

Add in style.css:

@import "~@angular/material/prebuilt-themes/indigo-pink.css";
Artem Arkhipov
  • 7,025
  • 5
  • 30
  • 52
Javed Khan
  • 151
  • 1
  • 2
5

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

NJS
  • 426
  • 4
  • 15
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(){}

}
Iancovici
  • 5,574
  • 7
  • 39
  • 57
  • The syntax for a material button is ` – Edric Jan 28 '18 at 14:17
  • @Edric what difference does it make? This is about dialog boxes not making angular material buttons. – Iancovici Jan 28 '18 at 14:19
  • 1
    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" ], – user1008531 Feb 01 '18 at 12:07
  • 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 definition – tequilacat Mar 04 '21 at 22:02
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.

Mifdha Milan
  • 327
  • 4
  • 6
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 hammerjs@2.0.8 --save) and it solved the issue. in my case in warnings this issue is poping up - Angular - 'Could not find HammerJS'

Neha Jain
  • 209
  • 2
  • 5
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

Ajay
  • 1
  • 1