Search code examples
angularjstwitter-bootstrapangular-ui-bootstrapbootstrap-popover

how to close popovers created in an ng repeat


using angular ui bootstrap I am creating modals with an ng repeat. I put a small example in a plunker.

https://plnkr.co/edit/lpaArn6ewYIbIMjHBb2s?p=preview

I am trying to figure out how to have the popovers open and close independently of one another now they all open and close at once.

<!doctype html>
<html ng-app="ui.bootstrap.demo">
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>

<div ng-controller="PopoverDemoCtrl">
    <div style=padding-top:200px;"></div>





    <button ng-repeat = "item in [1,2,3]"
    uib-popover-template="dynamicPopover.templateUrl" 
    popover-title="{{dynamicPopover.title}}" 
    popover-is-open="dynamicPopover.isOpen"
    type="button" 
    class="btn btn-default">
    Popover With Template
    </button>

    <script type="text/ng-template" id="myPopoverTemplate.html">
        <div>{{dynamicPopover.content.header}}</div>
        <button ng-click="dynamicPopover.isOpen = !dynamicPopover.isOpen">close</div>

    </script>

</div>
  </body>
</html>

js

angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('PopoverDemoCtrl', function ($scope, $sce) {

  $scope.content = {
    header: 'hello world'
  };

  $scope.dynamicPopover = {
    content: $scope.content,
    templateUrl: 'myPopoverTemplate.html',
    title: 'Title',
    isOpen: false
  };


});

Solution

  • You are storing the state of each popover in a single property dynamicPopover.isOpen, but you have to store the state of each popover independently. Fro your example you can store it in isOpen: [] array:

    angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
    angular.module('ui.bootstrap.demo').controller('PopoverDemoCtrl', function ($scope, $sce) {
      
      $scope.content = {
        header: 'hello world'
      };
      
      $scope.dynamicPopover = {
        content: $scope.content,
        templateUrl: 'myPopoverTemplate.html',
        title: 'Title',
        isOpen: []
      };
    
     
    });
    <!doctype html>
    <html ng-app="ui.bootstrap.demo">
    <head>
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
        <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
        <script src="example.js"></script>
        <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    
    <div ng-controller="PopoverDemoCtrl">
        <div style=padding-top:200px;"></div>
        
        <button ng-repeat="item in [1,2,3]"
                uib-popover-template="dynamicPopover.templateUrl"
                popover-title="{{dynamicPopover.title}}"
                popover-is-open="dynamicPopover.isOpen[$index]"
                type="button"
                class="btn btn-default">
            Popover With Template
        </button>
    
        <script type="text/ng-template" id="myPopoverTemplate.html">
            <div>{{dynamicPopover.content.header}}</div>
            <button ng-click="dynamicPopover.isOpen[$index] = !dynamicPopover.isOpen[$index]">close</div>
    
        </script>
    
    </div>
    </body>
    </html>