angular-modal-service
                                
                                
                                
                                    angular-modal-service copied to clipboard
                            
                            
                            
                        Clicking outside modal does not trigger close promise
Modals can be closed by clicking outside the modal window and I want to keep that functionality. However, closing the modal this way doesn't trigger the close promise.
Should it? Closing the modal with the close icon (X) on top right corner does trigger the promise. How do I know if the modal was closed by clicking outside of it?
I ended up using angular events outside of ModalService.showModal to handle this. Basically setup a attribute directive on the body tag listening for non-modal clicks... and when it gets ones, broadcasts an event to close the modal, which is handled in our controller that invokes ModalService.showModal (not the modal controller itself). The reason for this is that (for whatever reason) I couldn't get broadcasted or emitted events working on within the modal controller (it wasn't hearing them at all).
Hope it helps.
I was having a similar problem, but was able to deal with it by watching for the Bootstrap 'hidden.bs.modal' event. Essentially:
ModalService.showModal({
              ...
    }.then(function(modal) {
        modal.element.on('hidden.bs.modal', function () {
            modal.controller.closeModal();
        });
}
                                    
                                    
                                    
                                
@devourment77 can you provide a fiddle?
@MatteBailey can you also provide a plunkr please. I tried to use your snippet but the snippet seems to be activated every time because the buttons also will hide the modal so the that function would be passed on every click. Also closeModal is not a function so you probably defined that one?
thank you all in advance.
Yeah please provide at least something, since above ain't working for me, would love quickfix for this issue)
I've added to this since my first comment in October. Hopefully the code below is helpful:
In whatever controller you're using ModalService in:
ModalService.showModal({
    templateUrl: "exampleTemplate.html",
    controller: "ExampleController",
    controllerAs: "ctrl"
}).then(function(modal) {
    modal.element.one('hidden.bs.modal', function () {
        if (!modal.controller.closed) {
            modal.controller.closeModal();
        }
    });
    modal.element.modal();
});
And then in ExampleController:
this.closed = false;
this.closeModal = function () {
    close(null, 200);
    this.closed = true;
}
And in exampleTemplate.html
<button ng-click="ctrl.closeModal()" type="button" class="btn btn-default">Cancel</button>
This addresses the issue you mentioned @tiagomsmagalhaes. If you click the "Cancel" button, this.closed (which is modal.controller.closed in your first controller) will become true, and when you catch hidden.bs.modal you won't trigger closeModal again.
Definitely a work around, but it does the job with only a few extra lines.
Make sense?
Thx man, it's great fix indeed!!
thanks for the reply @MatteBailey. Meanwhile i got it to work as described in #128. I don't know if it's more elegant than your solution. I just added the failed promise part to catch the event. I think although the hidden.bs.modal is in the failed promise section, it's being called every time which isn't so problematic but i think it's not elegant.
Hi @tiagomsmagalhaes ,
If you want to run that code in the error callback of modal.close, you would do something like this:
modal.close.then(function(result) {
    $scope.yesNoResult = result ? "You said Yes" : "You said No";
}, function () {
    modal.element.on('hidden.bs.modal', function() {
        $('.modal').remove();
    });
});
I don't think this will help us though, because modal.close doesn't get rejected when a user clicks outside the modal to close it.
We generally provide an anonymous function for the promise callbacks. Since you're invoking modal.element.on(), it does indeed get run every time. I think what you have will behave the same as doing this:
modal.close.then(function(result) {
    $scope.yesNoResult = result ? "You said Yes" : "You said No";
});
modal.element.on('hidden.bs.modal', function() {
    $('.modal').remove();
});
This will definitely work for removing the modal from the DOM, but we will never resolve modal.close, which is problematic. This is the what my solution above addresses.
Let me know if I'm misunderstanding anything!
@MatteBailey I think we should replace
$('.modal').remove();
with
modal.scope.$destroy();
It will completely removed all the watchers in modal.
Hope it helps :)
Please look at below for the perfect and easiest solution http://magentocodes.blogspot.in/2017/10/how-to-close-modal-popup-clicking.html