Is there a way to automatically close Angular UI Bootstrap modal when changing the route?

I have links in templates inside modals. When I click on them, the current page changes, but the overlay and modal stay. I could add ng-click="dimiss()" to every link in all templates in modules, but is there a better way? For example. automatically close it upon successful route change or add only one ng-click for each template to process all links?

+52
angularjs angular-ui angular-ui-bootstrap
May 20 '14 at 14:18
source share
7 answers

If you want all open modals to be closed whenever the route has been successfully changed, you can do this in one central place by listening to the $routeChangeSuccess event, for example, in your application launch block:

 var myApp = angular.module('app', []).run(function($rootScope, $uibModalStack) { $uibModalStack.dismissAll(); }); 

Here you can see that the $uibModalStack service receives an injection, which you can call the dismissAll method dismissAll - this call will close all current open modalities.

So, yes, you can handle modals closing centrally, in one place, with one line of code :-)

+100
May 20 '14 at 17:13
source share

It’s best to see that whenever the pop-up window (modal) is open, on the button "Back Browser" (or "Keyboard Back") we stop changing the URL and just close the pop-up window. This works for a better user experience in my project.

The back browser button works fine if there is no open modal mode.

using:

 $uibModalStack.dismiss(openedModal.key); 

or

 $uibModalStack.dismissAll; 

Code example:

 .run(['$rootScope', '$uibModalStack', function ($rootScope, $uibModalStack) { // close the opened modal on location change. $rootScope.$on('$locationChangeStart', function ($event) { var openedModal = $uibModalStack.getTop(); if (openedModal) { if (!!$event.preventDefault) { $event.preventDefault(); } if (!!$event.stopPropagation) { $event.stopPropagation(); } $uibModalStack.dismiss(openedModal.key); } }); }]); 
+14
Nov 20 '15 at 13:12
source share

I really don't use Angular UI Bootstrap, but looking at the docs , it looks like there is a close() method to the $modalInstance .

Therefore, taking an example from docs , this should work:

 var ModalInstanceCtrl = function ($scope, $modalInstance, items) { $scope.items = items; $scope.selected = { item: $scope.items[0] }; $scope.ok = function () { $modalInstance.close($scope.selected.item); }; $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; // this will listen for route changes and call the callback $scope.$on('$routeChangeStart', function(){ $modalInstance.close(); }); }; 

Hope this helps.

+3
May 20 '14 at 14:44
source share

I solved this problem by doing something like this:

 $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ $modalStack.dismissAll(); }); 
+2
Jun 22 '15 at 17:36
source share

I save this logic in a modal controller. You can listen to the $locationChangeStart event and close the mod there. It is also useful to remove the listener after, especially if you registered the listener with $rootScope :

 angular.module('MainApp').controller('ModalCtrl',['$scope','$uibModalInstance', function ($scope, $uibModalInstance) { var dismissModalListener = $scope.$on('$locationChangeStart', function () { $uibModalInstance.close(); }); $scope.$on('$destroy', function() { dismissModalListener(); }); }]); 
+1
Aug 08 '17 at 9:23
source share

check for the corresponding route condition in the $stateChangeSuccess event and then globally close the open boot modalities using the following class:

 $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ //hide any open bootstrap modals angular.element('.inmodal').hide(); }); 

If you want to hide any other modals, such as the corner material dialog ( $mdDialog ) and the sweet alert dialog, use angular.element('.modal-dialog').hide(); & angular.element('.sweet-alert').hide();

0
Jan 02 '18 at 19:14
source share

Adding this alternative answer.

Depending on your project, using $uibModalStack.dismissAll() may cause an error message.

As JB Nizet explained in this answer, this is because dismissAll() rejected the promise, resulting in dismissAll() ", as opposed to the success callback called by close() .

Failure to promise may result in an unwanted error handling procedure.

Given that $uibModalStack does not have closeAll() , I used this:

  var modal = $uibModalStack.getTop(); while (modal && this.close(modal.key)) { modal = this.getTop(); } 

This is the same behavior as $uibModalStack.dismissAll() but uses .close() instead of .dismiss() .

I could not find any documentation describing public methods for $uibModalStack , thus, in case anyone is interested in using / viewing other methods available in $uibModalStack .

Most likely it will be located in \node-modules\angular-ui-boostrap\dist\ui-boostrap-tpls.js and dismissAll() - @line 4349

It took me a while to find it.

0
Jul 22 '19 at 22:03
source share



All Articles