angularjsangular-strap

AngularJS call AngularStrap Modal from service


I am trying to create a service to display Angular-Strap modals since I have many different parts of code that will need to trigger a modal and I don't want to run into a situation where I would have a circular reference.

This is code that works where you have access to $scope. For instance, in the applications controller.

function MyModalController($scope) {
            $scope.title = 'Draw Object Properties';
            $scope.content = 'Hello Modal<br />This is place holder test';
        };
        MyModalController.$inject = ['$scope'];

        // Pre-fetch an external template populated with a custom scope
        var myOtherModal = $modal({ controller: MyModalController, templateUrl: 'webmapapi/modal/toolproperties.html', show: false });
        // Show when some event occurs (use $promise property to ensure the template has been loaded)
        $scope.showModal = function () {
            myOtherModal.$promise.then(myOtherModal.show);
        };

Like I said I need to call this from a service though.

(function (angular, undefined) {
'use strict';
angular.module('ModalService', ['service', 'webValues', 'msObjects', 'mgcrea.ngStrap',])
    .config(function ($modalProvider) {
        angular.extend($modalProvider.defaults, {
            html: true
        });
    })        
    .factory("ModalService", function (MapApiService, webValues, VectorObjs,$modal) {
        var modalSVC = {

        };  
        modalSVC.showModal = function (modalType) {
            var scope = angular.element(document.getElementById('mainContainer')).scope();
            function MyModalController(scope) {
                scope.title = 'Draw Object Properties';
                scope.content = 'Hello Modal<br />This is place holder test';
            };
            MyModalController.$inject = ['scope'];

            // Pre-fetch an external template populated with a custom scope
            var myOtherModal = $modal({ controller: MyModalController, templateUrl: 'myURL.html', show: true });
            // Show when some event occurs (use $promise property to ensure the template has been loaded)
            myOtherModal.show;
        };

        return modalSVC;
    })

 }(angular));

The above does not like the scope I'm getting.


Solution

  • Okay, It's amazing how easy something can be once you know what you are doing!!

    Essentially you will want to set up a service...

    (function (angular, undefined) {
    'use strict';
    angular.module('ModalService', ['mgcrea.ngStrap'])
        .controller('ModalServiceController', modalServiceController)
        .factory("ModalService", function ($animate, $document, $compile, $controller, $http, $rootScope, $q, $templateRequest, $timeout, $modal) {
            function ModalService() {
    
                var self = this;
    
                self.showModal = function (title,templateUrl) {                 
    
                    var modal = $modal({
                        title: title,
                        templateUrl: templateUrl,
                        show: true,
                        backdrop: 'static',
                        controller: 'ModalServiceController'
                    });
                    modal.show;
                };
    
            }
    
            return new ModalService();
    
    
    
        })
    modalServiceController.$inject = ['$scope', '$modal'];
    function modalServiceController($scope,$modal) {
        //title and content need to be populated so I just left the default values
            $scope.title = 'Draw Object Properties';
            $scope.content = 'Hello Modal<br />This is place holder test';
    
    };
    }(angular));
    

    Now that you have your controller set up and injecting $modal, all you have to do from anywhere you have your service reference injected is...

    ModalService.showModal("Your Title", 
    "Your URL");
    

    I have a template(must be formatted as ) set up as Template.html and the contents are...

    <div class="modal" tabindex="-1" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header" ng-show="title">
                <button type="button" class="close" ng-click="$hide()">&times;</button>
                <h4 class="modal-title" ng-bind-html="title"></h4>
            </div>
            <div class="modal-body" ng-show="content">
                <h4>Text in a modal</h4>
                <p ng-bind-html="content"></p>
                <pre>2 + 3 = {{ 2 + 3 }}</pre>
                <h4>Popover in a modal</h4>
                <p>This <a href="#" role="button" class="btn btn-default popover-test" data-title="A Title" data-content="And here's some amazing content. It's very engaging. right?" bs-popover>button</a> should trigger a popover on click.</p>
                <h4>Tooltips in a modal</h4>
                <p><a href="#" class="tooltip-test" data-title="Tooltip" bs-tooltip>This link</a> and <a href="#" class="tooltip-test" data-title="Tooltip" bs-tooltip>that link</a> should have tooltips on hover.</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" ng-click="$hide()">Close</button>
                <button type="button" class="btn btn-primary" ng-click="$hide()">Save changes</button>
            </div>
        </div>
    </div>
    

    I hope this helps you!!