Search code examples
angularjsmodal-dialogreusability

How do I add a reusable modal dialog in Angular?


I'm new to Angular and attempting to implement this solution into my project.

It looks painfully easy, however, I'm trying to make this into a re-usable element so that I can call it from anywhere and just pass in the content to be shown (otherwise, what's the point?).

So, my specific question is: assuming I already have a controller that's bound to some DOM element and it has a feature that goes and fetches some factory driven $http call and upon the response I wish to notify the user via this dialog of something, how do I combine *this directive and *this controller with my existing one and how do I do it in a way that allows me to then use it again from a totally different controller?

Or is this perhaps a bad example for this use and should I be looking at a different one?


Solution

  • Compared to other options, below given the minimalist approach, using angular factory. See a sample snippet below.

    Note: using Angular JS with UI Bootstrap - AngularUI.

    1. Reusable modal view - ConfirmationBox.html

    <div class="modal-header">
      <h3 class="modal-title">{{title}}</h3>
    </div>
    <div class="modal-body">
      {{message}}
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-primary btn-warn" data-ng-click="ok(); $event.stopPropagation()">OK</button>
    
      <button type="button" class="btn btn-default" data-ng-click="cancel(); $event.stopPropagation()">Cancel</button>
    </div>

    1. Reusable module and shared factory, for handling the reusable modal dialog

    angular.module('sharedmodule',['ui.bootstrap', 'ui.bootstrap.tpls'])
    .factory("sharedService",["$q", "$modal", function ($q, $modal)
    {
        var _showConfirmDialog = function (title, message)
        {
            var defer = $q.defer();
    
            var modalInstance = $modal.open({
                animation: true,
                size: "sm",
                templateUrl: 'ConfirmationBox.html',
                controller: function ($scope, $modalInstance)
                {
                    $scope.title = title;
                    $scope.message = message;
    
                    $scope.ok = function ()
                    {
                        modalInstance.close();
                        defer.resolve();
                    };
    
                    $scope.cancel = function ()
                    {
                        $modalInstance.dismiss();
                        defer.reject();
                    };
                }
            });
    
            return defer.promise;
        }
    
        return {
    
            showConfirmDialog: _showConfirmDialog
        };
    
    }]);

    1. Portion of your View, using the shared modal dialog

    <a data-ng-click="showConfirm()">Go Back to previous page</a>

    1. Controller of your view, opening your shared reusable modal dialog and handling notifications (Ok and Cancel)

    var myModule = angular.module("mymodule", ['sharedmodule', 'ui.bootstrap', 'ui.bootstrap.tpls']);
    
    myModule.controller('myController', ["$scope", "sharedService", "$window",
    function ($scope, sharedService, $window)
    {
        $scope.showConfirm = function ()
        {
            sharedService.showConfirmDialog(
                'Confirm!',
                'Any unsaved edit will be discarded. Are you sure to navigate back?')
                .then(function ()
                {
                    $window.location = '#/';
                },
                function ()
                {
                });
        };
    }]);