Angular Bootstrap Modal leaves backdrop open

Problem

I'm using AngularUI to integrate Bootstrap components in my Angular 1.4 app, such as Modals.

I'm calling a Modal in my controller like so:

var modalInstance = $modal.open({
  animation: true,
  templateUrl: '/static/templates/support-report-modal.html',
  controller: 'ModalInstanceCtrl'
});

Unfortunately, when I want to close the Modal by using:

modalInstance.close();

The modal itself dissapears, and the backdrop also fades out, but it isn't removed from the DOM, so it overlays the whole page leaving the page unresponsive.

When I inspect, I'm seeing this:

enter image description here

In the example in the Documentation on https://angular-ui.github.io/bootstrap/#/modal The class modal-open is removed from body and the whole modal-backdropis removed from the DOM on close. Why is the Modal fading out but the backdrop not removed from the DOM in my example?

I've checked out many of the other questions about the backdrop of bootstrap Modals but I can't seem to figure out what's going wrong.

Problem courtesy of: Squrler

Solution

This is apparently due to a bug. AngularUI doesn't support Angular 1.4 yet. Once http://github.com/angular-ui/bootstrap/issues/3620 is resolved this will work.

Solution courtesy of: Squrler

Discussion

I am using Angular version 1.3.13 and have a similar issue. I been researching the problem and believe this bug extends from angular version 1.3.13 to 1.4.1 details here https://github.com/angular-ui/bootstrap/pull/3400

And if you scroll to the bottom of that link you will see a post by fernandojunior showing the versions he tested and upgraded to still showing the same issue. He even created a plnker to simulate the issue http://plnkr.co/edit/xQOL58HDXTuvSDsHRbra and I've simulated the issue in the code snippet below using the Angular-UI modal code example.

// angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);

angular
  .module('ui.bootstrap.demo', [
    'ngAnimate',
    'ui.bootstrap',
  ]);

angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {

  $scope.items = ['item1', 'item2', 'item3'];

  $scope.animationsEnabled = true;

  $scope.open = function (size) {

    var modalInstance = $modal.open({
      animation: $scope.animationsEnabled,
      templateUrl: 'myModalContent.html',
      controller: 'ModalInstanceCtrl',
      size: size,
      resolve: {
        items: function () {
          return $scope.items;
        }
      }
    });

    modalInstance.result.then(function (selectedItem) {
      $scope.selected = selectedItem;
    }, function () {
      $log.info('Modal dismissed at: ' + new Date());
    });
  };

  $scope.toggleAnimation = function () {
    $scope.animationsEnabled = !$scope.animationsEnabled;
  };

});

// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.

angular.module('ui.bootstrap.demo').controller('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');
  };
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
  <head>
    <!-- angular 1.4.1 -->
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular.js"></script>
    <!-- angular animate 1.4.1 -->
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular-animate.min.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.0.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>

<div ng-controller="ModalDemoCtrl">
    <script type="text/ng-template" id="myModalContent.html">
        <div class="modal-header">
            <h3 class="modal-title">I'm a modal!</h3>
        </div>
        <div class="modal-body">
            <ul>
                <li ng-repeat="item in items">
                    <a ng-click="selected.item = item">{{ item }}</a>
                </li>
            </ul>
            Selected: <b>{{ selected.item }}</b>
        </div>
        <div class="modal-footer">
            <button class="btn btn-primary" ng-click="ok()">OK</button>
            <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
        </div>
    </script>

    <button class="btn btn-default" ng-click="open()">Open me!</button>
    <button class="btn btn-default" ng-click="open('lg')">Large modal</button>
    <button class="btn btn-default" ng-click="open('sm')">Small modal</button>
    <button class="btn btn-default" ng-click="toggleAnimation()">Toggle Animation ({{ animationsEnabled }})</button>
    <div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
  </body>
</html>

Discussion courtesy of: bfalz

I am also using Angular 1.3.0 and I am also using UI bootstrap-tpls-0.11.2 and for some reason my issue was happening when I was redirecting to the new page and the backdrop was still displaying, so I ended up adding this code...

    .then(function () {
        $("#delete").on('hidden.bs.modal', function () {
            $scope.$apply();
        })
    });

which I actually found here.... Hide Bootstrap 3 Modal & AngularJS redirect ($location.path)

Discussion courtesy of: BV2005

Simply you can do like this, first close the modal u have opened

 $('#nameOfModal').modal('hide');  

basically id of modal Second this to remove if any

 $('body').removeClass('modal-open');

lastly to close backdrop

 $('.modal-backdrop').remove();
Discussion courtesy of: yogesh mhetre

Until the team gets this sorted here is a work around.

<div class="modal-footer">
    <button class="btn btn-primary"
        ng-click="registerModal.ok()"
        remove-modal>OK</button>
    <button class="btn btn-warning"
        ng-click="registerModal.cancel()"
        remove-modal>Cancel</button>
</div>

/*global angular */
(function () {
'use strict';
angular.module('CorvetteClub.removemodal.directive', [])
.directive('removeModal', ['$document', function ($document) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.bind('click', function () {
                $document[0].body.classList.remove('modal-open');
                    angular.element($document[0].getElementsByClassName('modal-backdrop')).remove();
                    angular.element($document[0].getElementsByClassName('modal')).remove();
                });
            }
        };
    }]);
}());

Unfortunately it appears that the team is not on the same page concerning this issue as it was pushed to a separate thread by a contributor and then the thread it was pushed to was closed by another as it was considered "off topic" by another.

Discussion courtesy of: tuckerjt07

This recipe can be found in it's original form on Stack Over Flow.