2

Is there a way to prevent the an AngularJS modal from closing/dismissing in the controller logic of the modal?

What I want is to show a warning when the users closes the modal and the form inside the modal contains unsaved data.

I've tried searching for a before close event or something else I could use in the official documentation, but no luck so far.

3
  • In the docs they're using a cancel function upon clicking on the cancel button. Which then calls "$modalInstance.dismiss('cancel');" inside the ModalInstanceCtrl. Can't you just check in there if there's any unsaved data? Commented Feb 10, 2015 at 10:50
  • Unfortunately the modal also closes when the user clicks on the backdrop or presses the escape key, this functionality should be left unchanged. Commented Feb 10, 2015 at 12:41
  • I checked the source code for the modal directive and I can't find anything that allow you to prevent it from closing. Either fork it and modify the module or use something else. You could suggest this feat to the angular-ui team, maybe even add it yourself. Commented Feb 10, 2015 at 13:05

3 Answers 3

7

You can watch the 'modal.closing' event, broadcasted to the modal's scope, like this:

.controller('modalCtrl', function($scope, $modalInstance) {

  $scope.$on('modal.closing', function(event, reason, closed) {
      var r = prompt("Are you sure you wanna close the modal? (Enter 'YES' to close)");

      if (r !== 'YES') {
        event.preventDefault();
      }
  });
})

The first parameter is the event, which you can preventDefault() to prevent it from closing.

The second parameter is the reason (whatever is passed to the $close() method)

The third parameter is a boolean indicating whether the modal was closed or dismissed.

Here a working plunker

I don't know when this was added, but currently it is mentioned in the official documentation.

Sign up to request clarification or add additional context in comments.

Comments

2

If you set backdrop: 'static' in your modalInstance, solve the problem?

Like this:

var modalInstance = $modal.open({
  ...
  backdrop: 'static',
  ...
});

Then, you need only control the ngClick button responsible to close the modal.

Hope this helps.

UPDATE 1 [only more info]

Use keyboard: false for disable Escape:

var modalInstance = $modal.open({
  ...
  backdrop: 'static',
  keyboard: false
  ...
});

UPDATE 2

I researched and found an option. In your modal controller, use:

$modalInstance.result.then(function (e) {
    //...
}, function (e) {
    //called before modal close
});

Example:

var modalInstance = $modal.open({
  templateUrl: templateUrl,
  controller: modalController
});

function modalController($scope, $modalInstance){

... //your code

  $modalInstance.result.then(function (e) {
      //...
  }, function (e) {
      //called before modal close
  });

... //your code

}

But you need a way to not continue the events for to close the modal. Or allow user save the data before close modal. That's what got so far.

UPDATE 3

Check this.

3 Comments

Thanks for thinking along, I also thought of this but the product owner wants the dialog to be dismissable when selecting the backdrop. So making it static is not an option unfortunately
Thanks a lot! Am I correct that the last update specifies how to catch the event, but not a way to prevent it from preceding?
I believe there is no way to prevent the closing of the modal, in the way I understand what you want. You may attempt to override the methods of the modal. Any news I have, I'll update my answer.
2

This will stop the backdrop from triggering a $modal.close event:

$modal.open({
   // ... other options
   backdrop  : 'static',
   keyboard  : false
});

The keyboard's ESC key can still close the modal, so if you want to diable that use keyboard: false

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.