Koder
Koder

Reputation: 1914

Warn user before navigating to a different view

I would like to warn user and get a confirmation before the user navigates away from certain pages in my application, like composing a new message view. Which events can i capture and cancel/continue to make this happen ?

Upvotes: 6

Views: 6643

Answers (3)

Nate Anderson
Nate Anderson

Reputation: 21084

When defining a state, use the onExit callback, which is a transition hook:

An onEnter/onExit declared on a state is processed as a standard Transition Hook. The return value of a hook may alter a transition.

.state('foo', {
  //dont return a value else it the transition will wait on the result to resolve (Promise)
  onEnter: (MyService) => { MyService.doThing(); },

  //return false to cancel the transition; i.e. prevent user from leaving
  onExit: (MyService) => { return MyService.isSatisfied(); }
});   

https://ui-router.github.io/ng1/docs/latest/interfaces/ng1.ng1statedeclaration.html#onexit

Upvotes: 0

harishr
harishr

Reputation: 18055

You should handle the $locationChangeStart event in order to hook up to view transition event, so use this code to handle the transition validation in your controller/s:

$scope.$on('$locationChangeStart', function( event ) {
  var answer = confirm("Are you sure you want to leave this page?")
  if (!answer) {
    event.preventDefault();
  }
}

also you can use this directive angularjs-unsaved-changes which would be much more reusable than writing it per controller..

Upvotes: 8

ms87
ms87

Reputation: 17492

If you have say a link or button navigating to another route or state, you could simply show a modal confirming the navigation:

<a href="" ng-click="goToAnotherState()">Go Away...</a>

$scope.goToAnotherState = function(){

//show modal and get confirmating however your like
  if(modalResponse.Ok){
     $state.go('anotherState');
  }
}

another option would be to do this in the $locationChangeStart event of ui-router, but if you're looking to this only here n there, then the first approach is better. $locationChangeStart approach:

$rootScope.$on('$locationChangeStart', function (event, next, prev) {
  event.preventDefault();
  //show modal
  if(modalResponse.ok){
    var destination = next.substr(next.indexOf('#') + 1, next.length).trim();
    $location.path(destination)
  }
}

Upvotes: 7

Related Questions