Igor Simic
2 years ago

Angular - simple reusable (yes-no) confirmation modal dialog shared component




How to create reusable component for simple yes/no modal window? In this example i will show you how to do it using Angular 8 and Material Design.The goal is to create shared component which can be used in different component - we will just pass the data to modal window and listen callbacks.

So let's start, first let us create shared component using Angular CLI:
ng g c Components/Shared/ConfirmDialog

Next, check is it already included in  app.module.ts and add it as entry component as well. So at the end this is how it should look like in app.module.ts
import { ConfirmDialogComponent } from './Components/Shared/confirm-dialog/confirm-dialog.component';

@NgModule({
  declarations: [
    ConfirmDialogComponent
  ],
  entryComponents: [ConfirmDialogComponent],

In confirm-dialog.component.html we will add html for our modal window. Notice we are using material card here, but if you want you can use plain divs (and style them):
<mat-card fxLayoutGap>

    <p mat-dialog-title>{{data.title}}</p>

    <p display-2>{{data.message}}</p>


    <div mat-dialog-actions>
        <button mat-button (click)="onDismiss()">No</button>
        <button mat-raised-button color="primary" (click)="onConfirm()">Yes</button>
    </div>
</mat-card>
Because we are using mat-card, there is a big padding around the card added by mat-dialog-container, so let's remove it. Open your style.sass (css) and add this:
mat-dialog-container
  padding: 0px !important

Let's create our shared component now. Here we will define our reusable shared component for simple yes no modal dialog. Open our shared component TS file confirm-dialog.component.ts and use this code
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { Component, OnInit, Inject } from '@angular/core';


export interface DialogData {
    title: string;
    message: string;
}

@Component({
  selector: 'app-confirm-dialog',
  templateUrl: './confirm-dialog.component.html',
  styleUrls: ['./confirm-dialog.component.sass']
})

export class ConfirmDialogComponent implements OnInit {

    dialogData: DialogData;
    title:string;
    message:string;

    constructor(
        public dialogRef: MatDialogRef<ConfirmDialogComponent>,
        @Inject(MAT_DIALOG_DATA) public data: DialogData
                ) {}

    ngOnInit() {

    }

    onConfirm(): void {
        // Close the dialog, return true
        this.dialogRef.close(true);
    }

    onDismiss(): void {
        // Close the dialog, return false
        this.dialogRef.close(false);
    }
}

Our shared modal dialog is ready to use. In component where you want to use, we have first include it:

import {MatDialog} from '@angular/material';
import {ConfirmDialogComponent} from '../../../Shared/confirm-dialog/confirm-dialog.component';

Let's assume you have a button in that component which is calling method deleteUser(), and inside of this method you want to trigger "Are you sure" yes/no modal dialog.
deleteUser(){
  // let's call our modal window
  const dialogRef = this.dialog.open(ConfirmDialogComponent, {
    maxWidth: "400px",
    data: {
        title: "Are you sure?",
        message: "You are about to delete user "}
  });

  // listen to response
  dialogRef.afterClosed().subscribe(dialogResult => {
    // if user pressed yes dialogResult will be true, 
    // if he pressed no - it will be false
    console.log(dialogResult);
    
 });

}