0
votes

I created a popover for a checkbox click using angular directive. It works perfectly fine but the close button does work. Here is my example code.

myApp.directive('mypopover', function ($compile,$templateCache,$interpolate) {
var getTemplate = function (contentType,attrs) {
    var template = '';
    switch (contentType) {
        case 'comment':
            var template  = "<div class=''>";
                template += "<form><div class='form-group'>";
                template += "<input type='hidden' value='"+attrs.value+"' name='documentationId' id='documentationId' />";
                template += "<textarea style='width:250px;' class='form-control' name='doc_comment' id='doc_comment'>Selected for Re-Use in 2nd Trade Workflow.</textarea>";
                template += "</div>";
                template += "<div class='form-group'>";
                template += "<input type='button' value='Close' class='btn btn-primary btn-xs' ng-click=\"closePopover()\" />";
                template += "<input type='button' value='Comment' class='btn btn-primary btn-xs pull-right'  />";
                template += "</div></form><br>";
                template += "</div>";
            break;
    }
    return template;
}

return {
    restrict: "EA",
    link: function (scope, element, attrs) {            
        var popOverContent;
        var d = new Date();
        var mm = d.getMonth()+1;

        popOverContent = getTemplate("comment",attrs);

        var options = {
            content: popOverContent,
            placement: "right",
            html: true,
            date: scope.date,
            title:"Date: "+mm+"/"+d.getDate()+"/"+d.getFullYear()
        };
        $(element).popover(options);

        scope.closePopover = function() { //this block doesn't work
            alert("called"); //does not return alert
        }
    }
};
});

html part of this is

<div class="checkbox checkbox-primary">
    <input 
        type='checkbox'                                        
        ng-model='selectedDocIds' 
        mypopover
    />
 </div>

I tried binding ng-click='closePopover()' function to main controller of this html but it doesn't work. I don't get error but just happen anything.

Can someone help me to have this ng-click event happening ?

Thanks

3
I got a pared down version working fine: plnkr.co/edit/Qlvdzy?p=info not sure yet what the scoping problem in the popover is though - wesww
@wesww, I had to do $compile to the template returned from getTemplate() to have it working. It is working in my plunker But I am having next problem, is uncheck of checkbox next time opens the popover. difference is I am unchecking the checkbox when popover is closed by clicking close button. See my example here - Aashis Binod Khanal
there's a current thread for supporting dynamic popovers you should have a look at here github.com/angular-ui/bootstrap/issues/… - wesww

3 Answers

0
votes

The problem comes from the fact that DOM is extended with html which is not Angular compiled.

There seems to be a right intention as directive injects $compile service. But it is not used.

   popOverContent = getTemplate("comment", attrs);
   $compile(popOverContent)(scope);//compile new contents bound to the same scope as directive
0
votes

a simpler way to accomplish what you are building might be to create a directive templated on top of Elijen's "angular-popover-toggle" module from this issue thread

https://github.com/Elijen/angular-popover-toggle

I made a basic working demo in plunker. You would then just have to turn it into a reusable directive. Check it out:

http://plnkr.co/edit/9QbPMV?p=preview

js

.controller('myCtrl', function($scope){
   $scope.demofor = 'Popover with close button';
   var d = new Date();
   var mm = d.getMonth()+1;
   $scope.title = "Date: "+mm+"/"+d.getDate()+"/"+d.getFullYear();
});

html

<br><br><br>
<div class="container">
  <h4>{{demofor}}!</h4>
  <label>
    Click here
    <input type="checkbox" ng-model="isPopoverOpen"
     popover-template="'tmpl.html'" 
     popover-toggle="isPopoverOpen"
     popover-placement="right"
     popover-title="{{title}}">
  </label>
</div>

<script type="text/ng-template" id="tmpl.html">
  <div>
    <form>
      <div class="form-group">
        <input type="hidden" value="attrs.value" name="documentationId" id="documentationId">
        <textarea style="width:250px;" class="form-control" name="doc_comment" id="doc_comment">Selected for Re-Use in 2nd Trade Workflow.</textarea>
      </div>
      <div class="form-group">
        <input type="button" value="Close" class="btn btn-primary btn-xs" ng-click="$parent.isPopoverOpen = false">
        <input type="button" value="Comment" class="btn btn-primary btn-xs pull-right" ng-click="saveComment(this)">
      </div>
    </form>
    <br>
  </div>
</script>
0
votes

Look at my attempt to answer your question. May be this script on plunker will help you.

customDirectives.directive('customPopover', function () {
return {
    restrict: 'A',
    template: '',
    link: function (scope, el, attrs) {
        scope.label = attrs.popoverLabel;
        $(el).popover({
            trigger: 'hover', // or click
            html: true,
            content: attrs.popoverHtml,
            placement: attrs.popoverPlacement
        });
    }
};

});

UPDATED 19-Aug-2015:

ANOTHER SOLUTION...

I discovered that button "Close" which runs function "$(element).popover('hide')" does not invoke series of actions which must be performed to hide bubble and toggle checkbox in right way. So I looked inside "bootstrap.js" and found out that "popover" makes all required actions over function "tooltip.toggle()". Furthermore, this function is called only one time on page start and sticked inside event handler to checkbox only. Hence, you can download "bootstrap.js" from site, make changes and enforce bootstrap to handle more elements then only one checkbox. But it is little bit weird way. So I offer to insert only one string to your current code and remove two strings.

Look at your file "app.js", line 47... Better, look at my plunker. This is full copy (forked copy) of your plunker but has three changed rows from line 47.

    scope.closePopover = function() {
      $(element).click();
      // $(element).popover("hide");
      // $(element).attr({checked:false});
    }

Explanation...

Function "$(element).click()" simulates clicking event. In this case bootsrap performs all needed actions to hide bubble and uncheck checkbox.