Search code examples
javascriptangularjsangular-ui-bootstrappopover

Popover AngularJs still shows even after setting its trigger to none


The 'Thanks' pop-over when clicking the thumbs up for the first time appears, but it is still appearing the second time the thumbs up is clicked even after setting its trigger to 'none'

Steps to reproduce:

  1. Click any thumbs up, 'Thanks' pop-over will appear
  2. Click anywhere outside such as white area to dismiss the 'Thanks' pop-over
  3. Click again that thumbs up and the 'Thanks' pop-over is still appearing

In the code, I set my own custom directive to conditionally set the popover-trigger such that when thumbs up is clicked once, it will set the popover-trigger to 'none': Inspected in Element tab that popover-trigger is really set to none.

Code in html:

<span ng-click="sendFeedback(false, result.id)"
      uib-popover="Thanks"
      popover-trigger="'outsideClick'"
      ...
      my-directive
      shown="this.shown[result.id]">
</span>

Code in controller:

feedbackApp.directive('myDirective', function () {
  return {
    restrict: 'A',
    scope: {
      shown: '=',
    },
    link: function(scope, element, attrs) {
      scope.$watch('shown', function(shown) {
          if (shown) 
              attrs.$set('popover-trigger', "none");
          }
      });
    }
  };
});

Simulation of the problem

Bottom line is if the user intends to undo the thumbs up, the 'Thanks' pop-over should not appear

Here is my full code in public repo


Solution

  • You try to change the DOM via injection attrs.$set('popover-trigger', "none") and this is not recognized by the compiled AngularUI template. You could recompile the template but this is not needed. Your approach is to complex for such simple requirement. Simply us the popover-enable option and you will be fine. You don't need to handle this inside a directive. Also $watch is not needed.

    angular.module('demoApp', ['ui.bootstrap'])
        .controller('DemoCtrl', function ($scope, $compile) {
        
        $scope.popoverState = true;
        
        $scope.clicked = function () {
            $scope.popoverState = false;
        };
        
    });
    /* EOF */
    <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    
    <script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-rc.0/angular.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-calendar/1.0.0/calendar.js"></script>
    
    
    <div ng-app="demoApp">
      <div ng-controller="DemoCtrl">
         <br />
         <br />
         <br />
         <button popover-placement="top" 
            ng-click="clicked()"
            uib-popover="On the top" 
            type="button" 
            popover-enable="popoverState"
            class="btn btn-default ng-binding"
            my-directive>Popover top</button>
      </div>
    </div>