ModalComponent is a pre-built component exposed by @abp/ng.theme.shared package to show modals. The component uses the ng-bootstrap's modal service inside to render a modal.

The abp-modal provides some additional benefits:

  • It is flexible. You can pass header, body, footer templates easily by adding the templates to the abp-modal content. It can also be implemented quickly.
  • Provides several inputs be able to customize the modal and several outputs be able to listen to some events.
  • Automatically detects the close button which has a abpClose directive attached to and closes the modal when pressed this button.
  • Automatically detects the abp-button and triggers its loading spinner when the busy input value of the modal component is true.
  • Automatically checks if the form inside the modal has changed, but not saved. It warns the user by displaying a confirmation popup in this case when a user tries to close the modal or refresh/close the tab of the browser.

Note: A modal can also be rendered by using the ng-bootstrap modal. For further information, see Modal doc on the ng-bootstrap documentation.

Getting Started

In order to use the abp-modal in an HTML template, the ThemeSharedModule should be imported into your module like this:

// ...
import { ThemeSharedModule } from '@abp/ng.theme.shared';

  imports: [..., ThemeSharedModule],
export class MyFeatureModule {}


You can add the abp-modal to your component very quickly. See an example:

<!-- sample.component.html -->

<button class="btn btn-primary" (click)="isModalOpen = true">Open modal</button>

<abp-modal [(visible)]="isModalOpen">
  <ng-template #abpHeader>
    <h3>Modal Title</h3>

  <ng-template #abpBody>
  <p>Modal content</p>

  <ng-template #abpFooter>
    <button type="button" class="btn btn-secondary" abpClose>Close</button>
// sample.component.ts

@Component(/* component metadata */)
export class SampleComponent {
    isModelOpen = false

Example modal result

See an example form inside a modal:

<!-- book.component.ts -->

<abp-modal [(visible)]="isModalOpen" [busy]="inProgress">
  <ng-template #abpHeader>

  <ng-template #abpBody>
    <form id="book-form" [formGroup]="form" (ngSubmit)="save()">
      <div class="form-group">
        <label for="book-name">Author</label><span> * </span>
        <input type="text" id="author" class="form-control" formControlName="author" autofocus />

      <div class="form-group">
        <label for="book-name">Name</label><span> * </span>
        <input type="text" id="book-name" class="form-control" formControlName="name" />

      <div class="form-group">
        <label for="book-price">Price</label><span> * </span>
        <input type="number" id="book-price" class="form-control" formControlName="price" />

      <div class="form-group">
        <label for="book-type">Type</label><span> * </span>
        <select class="form-control" id="book-type" formControlName="type">
          <option [ngValue]="null">Select a book type</option>
          <option [ngValue]="0">Undefined</option>
          <option [ngValue]="1">Adventure</option>
          <option [ngValue]="2">Biography</option>
          <option [ngValue]="3">Fantastic</option>
          <option [ngValue]="4">Science</option>

      <div class="form-group">
        <label for="book-publish-date">Publish date</label><span> * </span>

  <ng-template #abpFooter>
    <button type="button" class="btn btn-secondary" abpClose>

    <button form="book-form" class="btn btn-primary" [disabled]="form.invalid || form.pristine">
      <i class="fa fa-check mr-1"></i>
// book.component.ts

import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';

@Component(/* component metadata */)
export class BookComponent {
 form ={
    author: [null, [Validators.required]],
    name: [null, [Validators.required]],
    price: [null, [Validators.required, Validators.min(0)]],
    type: [null, [Validators.required]],
    publishDate: [null, [Validators.required]],

  inProgress: boolean;

  isModalOpen: boolean;

  constructor(private fb: FormBuilder, private service: BookService) {}

  save() {
    if (this.form.invalid) return;

    this.inProgress = true; => {
      this.inProgress = false;

The modal with form looks like this:

Form example result




@Input() visible: boolean

visible is a boolean input that determines whether the modal is open. It is also can be used two-way binding.


@Input() busy: boolean

busy is a boolean input that determines whether the busy status of the modal is true. When busy is true, the modal cannot be closed and the abp-button loading spinner is triggered.


@Input() options: NgbModalOptions

options is an input typed NgbModalOptions. It is configuration for the ng-bootstrap modal.


@Input() suppressUnsavedChangesWarning: boolean

suppressUnsavedChangesWarning is a boolean input that determines whether the confirmation popup triggering active or not. It can also be set globally as shown below:


// app.module.ts

import { SUPPRESS_UNSAVED_CHANGES_WARNING } from '@abp/ng.theme.shared';

// ...

  // ...
  providers: [{provide: SUPPRESS_UNSAVED_CHANGES_WARNING, useValue: true}]
export class AppModule {}

Note: The suppressUnsavedChangesWarning input of abp-modal value overrides the SUPPRESS_UNSAVED_CHANGES_WARNING injection token value.



@Output() readonly visibleChange = new EventEmitter<boolean>();

visibleChange is an event emitted when the modal visibility has changed. The event payload is a boolean.


  @Output() readonly appear = new EventEmitter<void>();

appear is an event emitted when the modal has opened.


  @Output() readonly disappear = new EventEmitter<void>();

disappear is an event emitted when the modal has closed.

Was this page helpful?
Please make a selection.
Thank you for your valuable feedback!

Please note that although we cannot respond to feedback, our team will use your comments to improve the experience.

In this document
Mastering ABP Framework Book
Mastering ABP Framework

This book will help you gain a complete understanding of the framework and modern web application development techniques.