Naor
Naor

Reputation: 24113

Get the template element in AngularJS directive

I am using AngularJS and I want to create a button that does an action only if the user is registered. If the user is not registered, it opens a signup tooltip with a specific message. Here is the button markup:

<button signup-tooltip="submitForm()" signup-message="Please sign in to submit the form">submit form</button>

The signup tooltip template looks like this:

<div class="signup-tooltip-view">
    ....Many elements
    ....
</div>

Important thing is that the signup tooltip must opened above the button.
My signupTooltip looks like that:

module.directive('signupTooltip', function() {
    return {
        scope: {
            action: '&signupTooltip',
            message: '@signupMessage'
        },
        templateUrl: 'path/to/signup/tooltip.html',
        link: function(scope, element, attrs) {
            function calculatePosition() {
                // This method calculates the position of the tooltip (above element)
                var top, left;
                ....
                ....
                ....
                return {
                    top: top,
                    left: left
                };
            }

            element.click(function() {
                if (user.isRegistered) {
                    scope.action();
                } else {
                    var tooltipPosition = calculatePosition();

                    // Here I need a reference for the template element <------PROBLEM
                    var tooltipTemplate = ..... HOW TO GET THE TOOLTIP ELEMENT

                    tooltipTemplate
                        .appendTo(element.parent())
                        .css(tooltipPosition);
                }
            });
        }
    };
});

Inside the directive I need a reference for the compiled element (the element that created from). How can I get it (keep in mind that I need signupMessage to be compiled with the template)??
What is the angular way for such use case (tooltips)?

Upvotes: 1

Views: 1501

Answers (2)

friedi
friedi

Reputation: 4360

You should work more with the framework, not around it.

This is the "Angular Way" of doing things:

JS:

var template = '<button ng-click="onClick()">submit form</button>\
<div class="signup-tooltip-view" ng-bind="message" ng-show="!!position" style="top:{{ top }}px;left: {{ left }}px">';

module.directive('signupTooltip', function() {
    return {
        restrict: 'E',
        scope: {
            action: '&',
            message: '@'
        },
        template: template,
        link: function(scope, element, attrs) {
            function calculatePosition() {
                // This method calculates the position of the tooltip
                var top, left;
                return {
                    top: top,
                    left: left
                };
            }

            scope.onClick = function() {
                if (user.isRegistered) {
                    scope.action();
                } else {
                    scope.position = calculatePosition();
                }
            };
        }
    };
});

Of course you can put the template in a separate file and reference it with the templateUrl attribute instead of providing a string.

HTML:

<signup-tooltip action="submitForm()" message="Please sign in to submit the form">


Here is the jsFiddle-demo

Upvotes: 1

Shomz
Shomz

Reputation: 37711

Bearing in mind that element refers to your directive, this should do it (uses jQuery's find function):

var tooltipTemplate = element.find(".signup-tooltip-view");

If you're using only angular's jqLite, you'd have to go with the children() method because it doesn't support find for classes. Of course, you can always use plain JS to select it by iterating over its childNodes.

Upvotes: 0

Related Questions