AngularJS โ Custom Modal Example & Tutorial
AngularJS โ Custom Modal: In the past Iโve always used plugins for implementing modals but now i am decided to have a crack at it myself recently,
Mostly when you designing a website probably you have to take care of speed and codes too. one of the reasons was that I wanted my modal window to share the same controller and viewmodel ($scope) as the page it was in.
Why Angularjs Modal is used ??
I didnโt want to have to create a separate controller for each modal that would then need to send data to the parent page controller via some other means, I wanted to keep it as simple as possible.
Another reason I wanted to create a custom modal was to make my app as lean as possible by removing the extra bloat added by unnecessary (and sometimes large) third party libraries.
AngularJS Custom Modal Setup
There are three main pieces of code that make up this custom modal implementation:
- Modal LESS/CSS styles in _/content/modal.less
- Angular Modal Service in _services/modal.service.js
- Angular Modal Directive in _directives/modal.directive.js
Adding an AngularJS Custom Modal to your page
Once you have the above three files (or the code from them) integrated into your project, you can add modals to your pages with the custom <modal> tag like this:
<modal id="custom-modal-1"> <div class="modal"> <div class="modal-body"> <h1>A Custom Modal!</h1> <p> Home page text: <input type="text" ng-model="vm.bodyText" /> </p> <button ng-click="vm.closeModal('custom-modal-1');">Close</button> </div> </div> <div class="modal-background"></div> </modal>
A unique id is required for each modal on a page, this is passed to the modal service from your controller to identify which modal you want to open/close.
The modal, modal-body and modal-background divs are required, but everything inside the modal-body can be changed.
You could also update the modal LESS/CSS if you want to change the styles of the modals, e.g to make them smaller or add CSS transitions etc.
Opening & Closing AngularJS Custom Modals
Check Out Website Designing Company in Delhi
To open and close (show/hide) modal windows you need to use the ModalService by injecting it into your controller and calling the ModalService.Open() and ModalService.Close() methods, e.g
(function () { 'use strict'; angular .module('app') .controller('Home.IndexController', Controller); function Controller(ModalService) { var vm = this; vm.openModal = openModal; vm.closeModal = closeModal; initController(); function initController() { vm.bodyText = 'This text can be updated in modal 1'; } function openModal(id){ ModalService.Open(id); } function closeModal(id){ ModalService.Close(id); } } })();
The example controller passes the modal id from the view, but it could also be set directly in the controller like this:
ModalService.Open('my-custom-modal');
The view then calls the functions exposed by the ViewModel in the usual way:
<div class="col-md-6 col-md-offset-3"> <h1>Home</h1> <p>{{vm.bodyText}}</p> <button ng-click="vm.openModal('custom-modal-1')">Open Modal 1</button> <button ng-click="vm.openModal('custom-modal-2')">Open Modal 2</button> </div>
Breakdown of the AngularJS Custom Modal Code
Below is a breakdown of the pieces of code used to implement the custom modal example, you donโt need to know the details of how it all works to use the modals in your project, itโs only if youโre interested in the nuts and bolts or if you want to modify the code of behavior.
LESS/CSS Styles for Custom Angular Modal
These are the styles applied to the custom modals in this example, however, they could also be used in non-angular projects as itโs just pure LESS/CSS.
/* MODAL STYLES -------------------------------*/ modal { /* modals are hidden by default */ display: none; .modal { /* modal container fixed across whole screen */ position: fixed; top: 0; right: 0; bottom: 0; left: 0; /* z-index must be higher than .modal-background */ z-index: 1000; /* enables scrolling for tall modals */ overflow: auto; .modal-body { padding: 20px; background: #fff; /* margin exposes part of the modal background */ margin: 40px; } } .modal-background { /* modal background fixed across whole screen */ position: fixed; top: 0; right: 0; bottom: 0; left: 0; /* semi-transparent black */ background-color: #000; opacity: 0.75; /* z-index must be below .modal and above everything else */ z-index: 900; } } body.modal-open { /* body overflow is hidden to hide main scrollbar when modal window is open */ overflow: hidden; }
AngularJS Custom Modal Service
The modal service manages the communication thatโs required between angular controllers and custom modal directive instances. It maintains a current list of available modals on the page exposes methods for interacting with those modals
(function () { 'use strict'; angular .module('app') .factory('ModalService', Service); function Service() { var modals = []; // array of modals on the page var service = {}; service.Add = Add; service.Remove = Remove; service.Open = Open; service.Close = Close; return service; function Add(modal) { // add modal to array of active modals modals.push(modal); } function Remove(id) { // remove modal from array of active modals var modalToRemove = _.findWhere(modals, { id: id }); modals = _.without(modals, modalToRemove); } function Open(id) { // open modal specified by id var modal = _.findWhere(modals, { id: id }); modal.open(); } function Close(id) { // close modal specified by id var modal = _.findWhere(modals, { id: id }); modal.close(); } } })();
AngularJS Custom Modal Directive
The custom modal directive is used for adding modals anywhere in an angular application by using the <modal> tag. Each modal instance registers itself with the ModalService
when it loads in order for the service to be able to open and close modal windows, and removes itself from the ModalService
when itโs destroyed using the scope โ$destroy
โ event.
(function () { 'use strict'; angular .module('app') .directive('modal', Directive); function Directive(ModalService) { return { link: function (scope, element, attrs) { // ensure id attribute exists if (!attrs.id) { console.error('modal must have an id'); return; } // move element to bottom of page (just before </body>) so it can be displayed above everything else element.appendTo('body'); // close modal on background click element.on('click', function (e) { var target = $(e.target); if (!target.closest('.modal-body').length) { scope.$evalAsync(Close); } }); // add self (this modal instance) to the modal service so it's accessible from controllers var modal = { id: attrs.id, open: Open, close: Close }; ModalService.Add(modal); // remove self from modal service when directive is destroyed scope.$on('$destroy', function() { ModalService.Remove(attrs.id); element.remove(); }); // open modal function Open() { element.show(); $('body').addClass('modal-open'); } // close modal function Close() { element.hide(); $('body').removeClass('modal-open'); } } }; } })();