Creating a dynamic modal component in AngularJS (1.5+) involves building a reusable modal component that can be easily triggered from different parts of the application.
1. Features of the Modal Component
Reusable – Can be used anywhere in the app.
Customizable – Accepts different titles, content, and actions.
Two-Way Binding – Can open and close dynamically.
Backdrop Click Dismissal – Closes when clicking outside the modal.
2. Step-by-Step Implementation
Step 1: Create the Modal Component
var app = angular.module('myApp', []);
app.component('modalComponent', {
bindings: {
title: '@', // Accepts modal title as attribute
isOpen: '<', // One-way binding for modal state
onClose: '&' // Event binding for closing modal
},
transclude: true, // Allows inserting custom content inside modal
template: `
<div class="modal-backdrop" ng-if="$ctrl.isOpen" ng-click="$ctrl.closeModal($event)">
<div class="modal-content" ng-click="$event.stopPropagation()">
<h3>{{$ctrl.title}}</h3>
<div class="modal-body" ng-transclude></div>
<button ng-click="$ctrl.closeModal()">Close</button>
</div>
</div>
`,
controller: function() {
this.closeModal = function(event) {
if (event) event.stopPropagation(); // Prevent event bubbling
this.onClose(); // Trigger parent function
};
}
});
How it Works
- The
isOpen
binding controls modal visibility. - The
title
attribute sets the modal heading. - The
onClose
function notifies the parent to close the modal. - The
ng-transclude
directive allows dynamic content inside the modal. - The click outside (backdrop click) closes the modal.
Step 2: Create the Main Controller
app.controller('MainController', function($scope) {
$scope.showModal = false;
$scope.openModal = function() {
$scope.showModal = true;
};
$scope.closeModal = function() {
$scope.showModal = false;
};
});
Step 3: Add the Modal to HTML
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AngularJS Modal Component</title>
<style>
.modal-backdrop {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
}
.modal-content {
background: white;
padding: 20px;
border-radius: 8px;
text-align: center;
min-width: 300px;
}
.modal-body {
margin: 10px 0;
}
</style>
</head>
<body ng-controller="MainController">
<button ng-click="openModal()">Open Modal</button>
<modal-component title="My Modal" is-open="showModal" on-close="closeModal()">
<p>This is a dynamic modal component!</p>
</modal-component>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="app.js"></script>
</body>
</html>
3. Explanation
How the Modal Works
- Clicking “Open Modal” sets
showModal = true
, triggering modal display. - Clicking “Close” or outside the modal calls
closeModal()
, hiding it. - The modal is reusable, allowing different titles and content.
Key Features Used
- One-way binding (
<
): Controls visibility (isOpen
). - Event binding (
&
): Handles closing (onClose
). ng-if
: Prevents rendering when hidden.ng-transclude
: Inserts custom content dynamically.- Click event handling: Prevents modal from closing on content clicks.
4. Enhancements
Adding a Fade Animation
Modify the .modal-content
with an animation effect:
.modal-content {
transform: scale(0.9);
opacity: 0;
transition: all 0.3s ease-in-out;
}
.modal-backdrop.ng-enter .modal-content {
transform: scale(1);
opacity: 1;
}
Adding Dynamic Actions
Extend the component with an actions array for customizable buttons:
bindings: {
actions: '<' // Accepts an array of buttons
},
Usage:
<modal-component title="Confirm Action" is-open="showModal" on-close="closeModal()" actions="modalActions"></modal-component>
Define modalActions
in the controller:
$scope.modalActions = [
{ label: "Yes", action: function() { alert("Confirmed!"); $scope.closeModal(); } },
{ label: "No", action: function() { $scope.closeModal(); } }
];
Modify the template:
<div class="modal-actions">
<button ng-repeat="action in $ctrl.actions" ng-click="action.action()">{{ action.label }}</button>
</div>