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.

Mark
  • 3,231
  • 3
  • 32
  • 57
  • 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? – Viktor Feb 10 '15 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. – Mark Feb 10 '15 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. – Viktor Feb 10 '15 at 13:05

3 Answers3

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.

Victor Gomes
  • 184
  • 7
  • 15
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.

Community
  • 1
  • 1
Doug
  • 195
  • 1
  • 1
  • 13
  • 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 – Mark Feb 10 '15 at 12:38
  • 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? – Mark Feb 10 '15 at 15:57
  • 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. – Doug Feb 19 '15 at 10:25
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

chovy
  • 72,281
  • 52
  • 227
  • 295