Reusable Confirmation Dialog in Angular

In this tutorial we shall see how to create a custom component to act as a reusable confirmation dialog box to handle success and cancel events.

Create a new angular project

First let's create a new angular application using the angular cli command.

ng new angular-dialog

Create a component for dialogbox

This will create a new angular application. Now lets create a dialog component using the following angular cli command.

ng g c dialog

Open the dialog.component.html file and modify the code as below.

<div #container class='container'>
	<div class='dialog'>
		<div class="header">
			<h3>{{type}}</h3>
   		</div>
		<div class="content">{{message}}</div>
		<div class="footer">
			<input class='btn success' type='button' value='Ok' (click)="onSuccess()"/>
			<input class='btn cancel' type='button' value='Cancel' (click)="onCancel()"/>
    </div>
		</div>
</div>

Here, we have created a div with template reference name #container.Then we create div container with class name header to display the dialog heading from the variable name type.

Then the div container with class name content will display the message of the confirmation dialog from message parameter.

The div container with class name footer will hold two buttons with values Ok and Cancel.

The Ok button calls onSuccess() function on click event and Cancel button calls onCancel() function on click event.

The command will create a DialogComponent. Open the dialog.component.ts file and add the following code.

import {
  Component,
  OnInit,
  ViewChild,
  Renderer2
} from "@angular/core";
import { BehaviorSubject } from "rxjs";


@Component({
  selector: "app-dialog",
  templateUrl: "./dialog.component.html",
  styleUrls: ["./dialog.component.css"]
})
export class DialogComponent implements OnInit {
  type = "Alert";
  message = "";
  private $selectedOption = new BehaviorSubject<boolean>(false);
  @ViewChild("container") container;

  constructor(private renderer: Renderer2) {}

  ngOnInit() {}

  openDialog(type, message) {
    this.type = type;
    this.message = message;
    this.renderer.setStyle(this.container.nativeElement,'display', 'flex');
    
  }

  closeDialog() {
    this.renderer.setStyle(this.container.nativeElement,'display', 'none');
  }

  onSuccess() {
    this.closeDialog();
    this.$selectedOption.next(true);
  }

  onCancel() {
    this.closeDialog();
    this.$selectedOption.next(false);
  }

  getSelectedOption() {
    return this.$selectedOption;
  }
}

Let's break this one by one and analyse the code.

type = "Alert";
message = "";
private $selectedOption = new BehaviorSubject<boolean>(false);
@ViewChild("container") container;
constructor(private renderer: Renderer2) {}

First we have created two variables, the type variable to specify the dialog box heading which can be one of the following, Confirm or Alert or Warning. The message variable to display the confirmation message.

We then create a BehaviorSubject with the name $selectedOption to emit a boolean value. By default we set it to be false.

We then create a container variable to get the reference of the div container using @ViewChild. Then import the Renderer2 and inject into the constructor with the variable name renderer. This is used to change the style of the container element.

  openDialog(type, message) {
    this.type = type;
    this.message = message;
    this.renderer.setStyle(this.container.nativeElement,'display', 'flex');
    
  }

The openDialog() function will receive type and message as parameters and set it to the component's type and message variables.

Then using renderer we set the style of the container's display property to flex.

  closeDialog() {
    this.renderer.setStyle(this.container.nativeElement,'display', 'none');
  }

The closeDialog() function is responsible for setting the container's display property to none. Setting this will hide the container.

  onSuccess() {
    this.closeDialog();
    this.$selectedOption.next(true);
  }

  onCancel() {
    this.closeDialog();
    this.$selectedOption.next(false);
  }

The onSuccess function will initially close the dialog by calling the closeDialog() function and then emit true value to the $selectedOption BehaviorSubject variable by calling the next function.

The onCancel function will initially close the dialog by calling the closeDialog() function and then emit false value to the $selectedOption BehaviorSubject variable.

  getSelectedOption() {
    return this.$selectedOption;
  }

The getSelectedOption() function, will return the BehaviorSubject $selectedOption.

Now open the dialog.component.css file and add a few styles to the component.

.container {
  height: 100vh;
  width: 100%;
  opacity: 0.75;
  background-color: #3b3a3a;
  display: none;
  justify-content: center;
  align-items: center;
  position: absolute;
}

.dialog {
  width: 400px;
  min-height: 200px;
  background-color: rgb(228, 228, 228);
  box-shadow: 5px 2px #3b3a3a;
  position: relative;
}

.header {
  margin: 10px;
  height: 20%;
}

.content {
  margin: 10px;
  height: 70px;
}

.footer {
  height: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.footer .btn {
  height: 35px;
  width: 60px;
  color: white;
  margin: 5px;
  border: none;
}

.success {
  background-color: green;
}

.cancel {
  background-color: brown;
}      

Use DialogComponent in AppComponent

Now, let's use this DialogComponent in our AppComponent to show a confirmation dialog box. Open the app.component.html file and add the following code.

<app-dialog #dialog></app-dialog>
<p>
	Lorem Ipsum is simply a dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's
	standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a
	type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting,
	remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing
	Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of
	Lorem Ipsum.
</p>
<div>
	<input type='button' (click)='openModal()' value='Open Dialog'/>
</div>

In the above code we had referred the DialogComponent selector app-dialog and also provide a template reference using #dialog.

Then we create a button with the value Open Dialog, which calls the function openModal() function on the click event.

Now open the app.component.ts file and add the following code.

import { Component, ViewChild, OnInit, AfterViewInit } from "@angular/core";
import { DialogComponent } from "./dialog/dialog.component";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit, AfterViewInit {
  @ViewChild(DialogComponent) dialogComponent;
  ngOnInit(): void {}

  ngAfterViewInit(): void {
    this.dialogComponent.getSelectedOption().subscribe((value: boolean) => {
      console.log(value);
    });
  }

  openModal() {
    this.dialogComponent.openDialog(
      "Warning",
      "Are you sure to remove the content?"
    );
  }
}

In the above code, using the @ViewChild we will reference the DialogComponent. This will refer to the DialogComponent which is mentioned in the app.component.html file.

Then implement the ngAfterViewInit lifecycle event and using the variable dialogComponent call the getSelectedOption() function and subscribe to the $selectedOption.

This will supply true value whenever Ok button is clicked and false value whenever Cancel button is clicked.

The openModal() function will call the openDialog() function of the DialogComponent with dialogComponent variable.

Here, we have provided a Warning value as a type of the confirmation box and Are you sure to remove the content? content as the message for the confirmation box.

Now run the application using

ng serve --o

When the application is launched, click on the 'Open Dialog' button, it will open a confirmation dialog box with the provided message. When the Ok or Cancel button is clicked it will be logged to the console.

We can now use those boolean values and perform any action based on the boolean value.

You can check out the source in this link.


Most Read