How to create a reusable Modal component in Angular

Modals are a fundamental part of modern web applications, providing a convenient way to display information, forms, or alerts without navigating away from the current page. In this blog post, we’ll guide you through the process of creating a reusable modal component in Angular.

1. Setting Up Your Angular Project

If you haven’t set up an Angular project, use the Angular CLI to create a new one:

bashCopy code

ng new angular-modal-example cd angular-modal-example ng serve

This will create a new Angular project and start the development server.

2. Creating the Modal Component

Start by generating a new component for the modal:

bashCopy code

ng generate component modal

Now, open the modal.component.ts file and update it to include the modal template and styles:

``// modal.component.ts
import { Component, Input, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'app-modal',
  template: `
    <div class="modal-overlay" [class.active]="isOpen" (click)="closeModal()">
      <div class="modal-container" (click)="stopPropagation($event)">
        <div class="modal-header">
          <h2>{{ title }}</h2>
          <span class="close-btn" (click)="closeModal()">&times;</span>
        </div>
        <div class="modal-content">
          <ng-content></ng-content>
        </div>
      </div>
    </div>
  `,
  styles: [
    // Add your styles here
  ],
})
export class ModalComponent {
  @Input() title: string = 'Modal';
  @Input() isOpen: boolean = false;
  @Output() closeModalEvent = new EventEmitter();

  closeModal() {
    this.closeModalEvent.emit();
  }

  stopPropagation(event: Event) {
    event.stopPropagation();
  }
}

This component uses Angular’s ng-content to project the content provided by the parent component. It includes a basic template for the modal overlay, container, header, and content.

3. Creating the Modal Service

Let’s create a modal service to manage the state of the modal. Run the following command in the terminal to generate a service:

ng generate service modal

Open the generated modal.service.ts file and update it as follows:

// modal.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class ModalService {
  private showModalSubject = new BehaviorSubject<boolean>(false);
  public showModal$: Observable<boolean> = this.showModalSubject.asObservable();

  constructor() {}

  openModal() {
    this.showModalSubject.next(true);
  }

  closeModal() {
    this.showModalSubject.next(false);
  }
}

This service uses a BehaviorSubject to track the modal’s state and provides methods to open and close the modal.

4. Using the Modal Component and Service

Now, let’s use the modal component and service in another component. Open the app.component.ts file and update it as follows:

``// app.component.ts
import { Component } from '@angular/core';
import { ModalService } from './modal.service';

@Component({
  selector: 'app-root',
  template: `
    <h1>Angular Modal Example</h1>
    <button (click)="openModal()">Open Modal</button>

    <app-modal [title]="'Custom Title'" [isOpen]="isModalOpen" (closeModalEvent)="closeModal()">
      <!-- Content  -->
    </app-modal>
  `,
})
export class AppComponent {
  isModalOpen: boolean = false;
  constructor(private modalService: ModalService) {}

  openModal() {
    this.isModalOpen = true;
    this.modalService.openModal();
  }

  closeModal() {
    this.isModalOpen = false;
    this.modalService.closeModal();
  }

}

In this example, the AppComponent uses the ModalComponent and includes a form inside it. The modal’s state is managed by the ModalService. The modal is opened and closed based on the isModalOpen property, and the form data is handled in the submitForm method.

5. Styling the Modal

You can add styling to the modal by updating the styles in the modal.component.ts file. Customize the styles according to your design preferences.

? modal.component.ts

styles: [
  `
    .modal-overlay {
      display: none;
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.5);
      justify-content: center;
      align-items: center;
      z-index: 9999;
    }

    .modal-container {
      background: #fff;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    }

    .modal-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      border-bottom: 1px solid #ddd;
      padding-bottom: 10px;
      margin-bottom: 10px;
    }

    .modal-header h2 {
      margin: 0;
    }

    .close-btn {
      cursor: pointer;
      font-size: 20px;
      color: #888;
    }

    .modal-content {
      /* Add your content styling here */
    }

    .modal-overlay.active {
      display: flex;
    }
  `,
],
// ...

How To Use

app.component.html

<h1>My App</h1>
<button (click)="openModal()">Open Modal</button>

<app-modal
  [title]="'Custom Title'"
  [isOpen]="isModalOpen"
  (closeModalEvent)="closeModal()"
>
  <p>Modal Body Content</p>
</app-modal>
import { Component, VERSION } from '@angular/core';
import { ModalService } from './modal/modal.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  isModalOpen: boolean = false;

  constructor(private modalService: ModalService) {}

  openModal() {
    this.isModalOpen = true;
  }

  closeModal() {
    this.isModalOpen = false;
  }
}
Next Post Previous Post
No Comment
Add Comment
comment url