21

I've a table with a popover for every cell as in the follow example:

the call to popover:

<td ng-repeat="i in c.installments" ng-class="{ 'first' : i.first, 'last' : i.last, 'advance' : i.advance.value > 0, 'edited' : i.edited, 'final-installment' : i.last }" popover-trigger="{{ popoverFilter(i) }}" popover-placement="top" popover-title="{{i.id == 0 ? 'Advance' : 'Installment ' + i.id}}" popover-append-to-body="true" popover-template="popoverTemplate(i)" ng-init="payment= i; newpayment= i.amount.rounded_value" >

The popover template:

<script type="text/ng-template" id="editPopoverTemplate.html">
    <form name="editPayment">
      <h2>{{payment.amount.value|currency:undefined:cents}}</h2>
      <div class="form-group" ng-class="{ 'has-error' : editPayment.newpayment.$invalid }">
        <label>New value:</label>
        <input type="number" name="newpayment" ng-model="newpayment" class="form-control no-spinner" step="1" min="10" required>
        <span ng-messages="editPayment.newpayment.$error" class="help-block" role="alert">
          <span ng-message="required">The value is mandatory</span>
          <span ng-message="min">The value is too low</span>
          <span ng-message="max">The value is too hight</span>
        </span>
      </div>
      <div class="btn-group btn-group-justified" role="group">
        <div class="btn-group" role="group">
          <button class="btn" type="button">Cancel</button>
        </div>
        <div class="btn-group" role="group">
          <button class="btn btn-primary" type="button" ng-disabled="editPayment.$invalid">Save</button>
        </div>
      </div>
    </form>
  </script>

working example on plunker

I need to close the popover via a "Cancel" button inside the popover. It's possible? I need to extend the Angular UI Bootstrap library to do that?

Any help is appreciated.

The solution suggested in the linked answer close the popover when user click inside the popover, or outside the popover, but i need to close it by "close" button inside the popover.

Zauker
  • 2,344
  • 3
  • 27
  • 36
  • possible duplicate of [Hide Angular UI Bootstrap popover when clicking outside of it](http://stackoverflow.com/questions/30512748/hide-angular-ui-bootstrap-popover-when-clicking-outside-of-it) – callmekatootie Aug 02 '15 at 10:06

3 Answers3

33

The proper solution using the new popover-is-open attribute, as mentioned by @icfantv below, allows the use of controller scopes. I placed a live example in Codepen, and it goes like this:

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

app.controller(
  'myPopoverCtrl', ['$scope',
    function($scope) {

      // query popover
      $scope.myPopover = {

        isOpen: false,

        templateUrl: 'myPopoverTemplate.html',

        open: function open() {
          $scope.myPopover.isOpen = true;
          $scope.myPopover.data = 'Hello!';
        },

        close: function close() {
          $scope.myPopover.isOpen = false;
        }
      };

    }

  ]);
<head>

  <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
  <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.4/ui-bootstrap-tpls.min.js">
  </script>
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

</head>

<body 
      ng-app="ui.bootstrap.demo" 
      class="container">

  <button 
          class="btn btn-danger" 
          ng-controller="myPopoverCtrl" 
          popover-template="myPopover.templateUrl" 
          popover-title="This is a popover" 
          popover-placement="bottom" 
          popover-is-open="myPopover.isOpen" 
          ng-click="myPopover.open()">Click me!</button>

  <script type="text/ng-template" 
          id="myPopoverTemplate.html">
    <h2 ng-bind="myPopover.data" />
    <button class="btn btn-success" 
            ng-click="myPopover.close()">Close me!</button>

  </script>

</body>

Original answer:

I spent the last two days on this problem, and finally came up with a simple enough hack. This goes on my controller:

 $scope.close = function(e) {
     el = angular.element(e.target).closest("td"); // `td` is the parent of my clickable
                                                   // element, in this case a `span`
     $timeout(function() { // need $timeout so we don't conflict with the digest loop
     el.children(":first").trigger('close'); // couldn't select the `span` element directly
     });
 },

Now we set up the close trigger on the provider:

app.config(['$tooltipProvider', function($tooltipProvider){
  $tooltipProvider.setTriggers({
    'click': 'close', // Clicks now only open the tooltip, 'close' events close it.
  });
}]);

And on my custom popover HTML template:

<button type="button" 
        class="btn btn-sm btn-success pull-right" 
        ng-click="close($event)">Close</button>

Voila! I can now close the popover through the button!

dmvianna
  • 15,088
  • 18
  • 77
  • 106
  • thanks a lot for posting your solution. I'll try it soon on plunker, i'm also interested to see the use of new attribute popover-is-open as suggested by icfantv. – Zauker Sep 03 '15 at 07:14
  • If you choose to update to the latest version of UI Bootstrap, this won't work, as they seem to have dropped support for custom-made triggers. – dmvianna Sep 14 '15 at 03:47
  • @dmvianna this is fixed in master. – icfantv Sep 15 '15 at 04:56
  • I have not tried these solutions yet. Could you post a little live example on plunker made with popover-is-open attribute? – Zauker Sep 16 '15 at 17:16
  • @icfantv, feel free to use this example as documentation for angular-ui-bootstrap. – dmvianna Sep 17 '15 at 01:11
  • @dmvianna - I just looked and we didn't update our examples on tooltip or popover to show an example on how to programmatically show/hide the tooltip/popver. We won't link to CodePen, but you want to submit a PR with the update to our example docs, we will accept it. – icfantv Sep 17 '15 at 19:48
5

This solution for several ng-repeat popovers via isOpen field of popover's scope.

angular.module('ui.bootstrap.demo', ['ui.bootstrap']).controller('PopoverDemoCtrl', function ($scope) {  
  $scope.template = 'myPopoverTemplate.html';
  $scope.close = function(e) {    
    angular.element(e.target).parent().parent().parent().parent().scope().$parent.isOpen = false;
  }
});
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

<body ng-app="ui.bootstrap.demo">
<div ng-controller="PopoverDemoCtrl">
    <button ng-repeat="item in ['First Popover','Second Popover','Third Popover']" popover-placement='bottom' uib-popover-template="template" popover-title="{{item}}" type="button" class="btn btn-default">{{item}}</button>  
    <script type="text/ng-template" id="myPopoverTemplate.html">        
        <div class="form-group">
          <button class='btn btn-danger' ng-click='close($event)'>Close Me</button>
        </div>
    </script>
</div>
</body>
Slava Utesinov
  • 13,410
  • 2
  • 19
  • 26
3

Starting with Angular UI Bootstrap release 0.13.4, we've added the ability to programmatically close tooltips and popovers via the tooltip-is-open or popover-is-open boolean attribute.

icfantv
  • 4,523
  • 7
  • 36
  • 53
  • good news, a question, i see that the stable version available on bower or via download is in this moment the 0.13.3. When version 0.13.4 will be released as stable? – Zauker Sep 01 '15 at 07:14
  • i saw that last angular ui bootstrap tag is 0.13.3, but the master branch report reports on his package.json the number version 0.13.4-SNAPSHOT i suppose it is under development in this moment, isn't? – Zauker Sep 01 '15 at 08:27
  • please don't ask the same question on multiple threads. right now, the plan is to release 0.13.4 on thursday, 03SEP2015. – icfantv Sep 01 '15 at 17:48