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
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;
});
};
};
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(...);
};
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;
});
});
}