Search code examples
angularjsangularjs-directiveangularjs-scopeqtip2

AngularJS binding jQuery qTip2 plugin


I am trying to figure out how to bind the content of a tooltip with angular. I have a directive that looks like this:

script.js

var myApp = angular.module('myApp', []);

myApp.directive('initToolbar', function(){
    return {
        restrict: 'A',
        link: function(scope, element, attrs)
        {
            $(element).qtip({
                content: {
                    ajax:
                    {
                        url: 'button.html'
                    }
                },
                position: {
                    my: 'bottom left',
                    at: 'bottom middle',
                    target: $(element)
                },
                hide: {
                    fixed : true,
                    delay : 1000
                }
            });
        }
    }
});

It uses the qTip2 plugin from here

My index.html looks like this (please note that in the actual file I have included all the sources in head, I am just not pasting it here to avoid clutter):

<body>
    <div initToolbar>
        <p>
            Hover over me. Hover over me. Hover over me.
        </p>
    </div>
</body>

and

button.html

<div ng-controller="myController">
    <button ng-click="someFunction()">Click me</button>
</div>

As you can see in the directive code. button.html is loaded into the tooltip, however this prevents angular from functioning properly-- The ng-click does not work when button.html is loaded into the popup. That is because angular does not know about it.

I also know that button.html is valid because simply adding

<ng-include src="'button.html'"> 

to index.html works fine (i.e clicking on the button executes someFunction())

So my question is:

How can I bind the actual content of the tooltip with angular? If not the content, is there a way to bind the tooltip so angular knows about it? I am familiar with $scope.$apply() but I am not quite sure how to use it here.


Solution

  • UPDATE 1 Make sure to go from snake-case to camelCase when going from HTML to javascript in angular. So init-toolbar in html translates to initToolbar in javascript.

    Here is a working sample: http://plnkr.co/edit/l2AJmU?p=preview

    HTML

    <div init-toolbar="">
      <p>
        Hover over me. Hover over me. Hover over me.
      </p>
    </div>
    

    Button.html

    <div>
      <button ng-click="someFunction()">Click me</button>
    </div>
    

    JAVACRIPT

    var app = angular.module('plunker', []);
    
    app.controller('MainCtrl', function($scope) {
      $scope.name = 'World';
      $scope.someFunction = function() {
        $scope.name = 'FOO BAR';
      };
    });
    
    app.directive('initToolbar', function($http, $compile, $templateCache){
        return {
            restrict: 'A',
            link: function(scope, element, attrs)
            {
              $http.get('button.html', {cache: $templateCache}).
                success(function(content) {
                  var compiledContent = $compile(content)(scope);
    
                  $(element).qtip({
                    content: compiledContent,
                    position: {
                      my: 'bottom left',
                      at: 'bottom middle',
                      target: $(element)
                    },
                    hide: {
                      fixed : true,
                      delay : 1000
                  }
                });
    
              });
    
            }
        }
    });
    

    ORIGINAL

    The reason the button does not work is because angular does not know it should bind to it. You tell angular to do that using $compile. I don't know much about that qTip2 pluggin, but if you load the template, then compile it $compile(template)(scope); then hand it over to qTip2, you will get the results you expect.