0

I want to create a directive that shows Tooltip (from AngularJs Bootstrap UI) based on user is authorized or not.

It does the job well and add the required attributes tooltip and tooltip-position but the tooltip doesn't show up.

If i compare the element generated by my code and element that has a tooltip as normal html, its identical except class="ng-scope", adding this class manually doesn't help.

Here is my directive code:

proGamersApp.directive('registered', ['$rootScope', 'authService', function ($rootScope, authService) {
    return {
        restrict: 'A',
        scope: true,
        link: function ($scope, element, attrs) {
            element.addClass('faded');

            $rootScope.$watch('user.role', function (role) {
                $scope.$apply(function () {
                    var accessLevel = routingConfig.accessLevels[attrs.accessLevel];
                    if (!authService.authorize(accessLevel)) {
                        element.attr('tooltip-placement', 'bottom');
                        element.attr('tooltip', 'Avaiable for registered users.');
                    } else
                        element.attr('tooltip-placement', 'bottom');
                    element.attr('tooltip', 'Avaiable for registered users.');
                });
            });
        }
    };
}]);

Any idea anyone?

Update 3 removed the '$compile(element) since it says its undefined function, and changed the use of the $apply function. still getting '$digest already in progress' error.

New Code:

proGamersApp.directive('registered', ['$rootScope', 'authService', function ($rootScope, authService, $compile) {
    return {
        restrict: 'A',
        scope: true,
        link: function ($scope, element, attrs) {
            element.addClass('faded');

            $rootScope.$watch('user.role', function (role) {
                var accessLevel = routingConfig.accessLevels[attrs.accessLevel];
                if (!authService.authorize(accessLevel)) {
                    element.attr('tooltip-placement', 'bottom');
                    element.attr('tooltip', 'Avaiable for registered users.');
                } else {
                    element.attr('tooltip', 'Avaiable for registered users.');
                }

                $scope.$apply(element);
            });

        }
    };
 }]);
3
  • Try to $compile() your element. Commented Sep 25, 2013 at 13:01
  • Not sure if I did it right, but I added it (see update) and nothing changed. Commented Sep 25, 2013 at 16:25
  • I've added it as it suppose to be, have a look at the updated post. Commented Sep 28, 2013 at 22:08

2 Answers 2

1

Try using $compile like this:

proGamersApp.directive('registered', ['$rootScope', 'authService', '$compile', 
function ($rootScope, authService, $compile) { 
    return { 
        restrict: 'A', 
        scope: true, 
        link: function ($scope, element, attrs) { 
            element.addClass('faded');
            $rootScope.$watch('user.role', function (role) {
                var accessLevel = routingConfig.accessLevels[attrs.accessLevel];
                if (!authService.authorize(accessLevel)) {
                    element.attr('tooltip-placement', 'bottom');
                    element.attr('tooltip', 'Avaiable for registered users.');
                } else {
                    element.attr('tooltip', 'Avaiable for registered users.');
                }
                $compile(element.parent().contents())($scope);
            });
        }
    };
}]);
Sign up to request clarification or add additional context in comments.

2 Comments

My code needed some code modification in order to work properly, but your attitude did solve the problem. I would be grateful if you will explain why you used 'element.parent().contents()' instead of 'element'.
I guess that is because we want to compile the element itself while contents() returns the child elements. Not too sure though :D
1

Another way to handle this kind of thing would be to just have a controller that makes available in it's scope a variable or function that determines access, then use ng-hide and ng-show in the dom to setup your tooltips, or whatever.

<div data-ng-controller="SessionCtrl">
    <div data-ng-hide="session.active()">
        put your logged in user stuff here
    </div>
    <div data-ng-hide="session.active()">
        put your non logged in user stuff here
    </div>
</div>

5 Comments

Thanks, but I prefer the way I did since its more cleaner having 'accessLevel' directive using an 'authService'. My problem is making the tooltip visible, since there seem to be problem in the way it bootstrap tooltip works with my code (note the element itself is the same, but the tooltip don't show up).
Ok, then look at what the other guy was saying, you could inject the $compile service into your directive, not create a compile function. Then $compile the element after you have added the bootstrap directive attributes.
Thanks for the help. I've added it at the place you said, I get 'Error: $digest already in progress', have a look at the updated post.
You are doing it in the $apply function, don't do that. Do what you need to do and call $apply afterwards.
I've used it as you said, still getting '$digest already in progress' error. have a look in my new code, maybe I missed something

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.