8
votes

I've implemented the modal directive, and set the $modal.open option backdrop to false. However, now I can trigger multiple modals to open. Is there a way to prevent the trigger button from firing once one modal is open?

var accountSummaryCtrl = function ($scope, $modal, $log) {

    $scope.open = function () {

        var modalInstance = $modal.open({
            templateUrl: '/Apps/generic/modal/Templates/AccountSummary.html',
            controller: ModalInstanceCtrl,
            backdrop: false
        });

        modalInstance.result.then(function (selectedItem) {
            $scope.selected = selectedItem;
        }, function () {
            $log.info('Modal dismissed at: ' + new Date());
        });
    };
};

Thanks

3
disable the button when you open the modal - m.e.conroy

3 Answers

14
votes

Use a boolean flag to avoid it:

var accountSummaryCtrl = function ($scope, $modal, $log) {

    var opened = false;

    $scope.open = function () {

        if (opened) return;

        var modalInstance = $modal.open({
            templateUrl: '/Apps/generic/modal/Templates/AccountSummary.html',
            controller: ModalInstanceCtrl,
            backdrop: false
        });

        opened = true;

        modalInstance.result.then(function (selectedItem) {
            $scope.selected = selectedItem;
            opened = false;
        }, function () {
            $log.info('Modal dismissed at: ' + new Date());
            opened = false;
        });
    };
};
1
votes

I've made a simple directive which uses same technique as in J. Bruni's answer.

/**
 * Directive which helps to prevent multiple modals opened when clicking same button many times.
 *
 * Just replace "ng-click" with "open-single-modal" in your html. Example:
 *
 * <button open-single-modal="openModal()">Open Window</button>
 *
 * NOTICE! "openModal()" function must return modalInstance which is a result of "$uibModal.open()"
 */
app.directive('openSingleModal', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var opened = false;

            element.bind('click', function () {
                if(opened) {
                    return;
                }

                opened = true;
                var modalInstance = scope.$eval(attrs.openSingleModal);

                if(!modalInstance || !modalInstance.result || typeof modalInstance.result.then !== 'function') {
                    console.error('Incorrect modal instance returned from the open modal function', element, modalInstance);
                    return;
                }

                modalInstance.result.then(function () {
                    opened = false;
                }, function () {
                    opened = false;
                });
            });
        }
    };
});

To switch your code for this directive just change "ng-click" to "open-single-modal" and the function fired by ng-click must return modal instance.

Example. Before:

<a ng-click="openModal()">Open Me!</a>

After:

<a open-single-modal="openModal()">Open Me!</a>

and

$scope.openModal = function() {
    return $uibModal.open(...);
};
1
votes

J Bruni's answer is very good, but instead of using an additional variable, use what you already have with modalInstance. Since you declare modal instance higher up, you also gain flexibility to use that variable elsewhere (such as for when you may want to dismiss the dialog).

    link: function(scope, element, attrs) {
        var modalInstance;        /*assign to undefined if you like to be explicit*/

        element.bind('click', function () {
            if(modalInstance) {
                return;
            }

            modalInstance = scope.$eval(attrs.openSingleModal);

            if(!modalInstance || !modalInstance.result || typeof modalInstance.result.then !== 'function') {
                console.error('Incorrect modal instance returned from the open modal function', element, modalInstance);
                return;
            }

            modalInstance.result.then(function () {
                modalInstance = undefined;
            }, function () {
                modalInstance = undefined;
            });
        });
    }