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()">×</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;
}
}