Levi Fuller
Levi Fuller

Reputation: 15631

Passing Attribute Value to Directive Template

End Goal

We'd like to have an attribute we can add to any element which we would associate to a contextual help dialog so that when we hover the mouse cursor over an element, a pop-up will show the help information. Here's an example of what we want to do:

<label help-info="This is what will be displayed in the help dialog">Help Example</label>

I'm having some trouble correctly passing the string parameter to the template though.

Here's what I've tried:

Index.html

<html ng-app="myApp">
  <head>
    <script data-require="angular.js@*" data-semver="2.0.0-alpha.20" src="https://code.angularjs.org/2.0.0-alpha.20/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="HelpInfoDirective.js"></script>
  </head>

  <body ng-controller="myCtrl">
    <div help-info="test"></div>
  </body>
</html>

HelpInfoTemplate.html

<div>
  {{'this is a' + _attrs.help-info}}
</div>

HelpInfoDirective.js

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

  app.directive('helpInfo', function(){
    return{
      restrict: 'A',
      scope: true,
      templateUrl: function(_elements, _attrs){
        'HelpInfoTemplate.html'
      }
    //  link: function(_scope, _elements, _attrs){
     //   _scope.helpAttr = _attrs.help-info;
     // }
    }  
  });
})();

First, I tried passing the parameter by using the link parameter and it didn't work so I tried placing the template into a function with no luck.

What is the correct way to pass an attribute's value to a template?

Also, once we have the value, how can we modify the returned template so we can use ng-show to show the pop-up (we'll place it into a modal eventually). I'm open to suggestions.

Link to the Plunk

Upvotes: 0

Views: 2329

Answers (2)

jake
jake

Reputation: 1027

What is the correct way to pass an attribute's value to a template?

Binding values to templates

Values are bound to templates through the compilation process. You can compile code in the link function of your directive using the $compileservice and providing the scope that the template needs to bind to:

app.directive('helpInfo', function($compile){
    return{
      restrict: 'A',
      scope: {title : '@'},
      link: function(scope, el){
        var newElement = $compile('<div>{{title}}</div>')(scope); 
        el.hover(function(){
          el.after(newElement); 
        }); 

        el.mouseout(function(){
          el.nextAll().first().remove(); 
        }); 

      }
    }  
  });

Defining the scope for your directive

You'll need to setup an isolated scope for the directive an specify the name of the attribute where you'll define the text shown in your popup. I've used 'title' as the attribute in this example.

You can then use the directive like this:

<div help-info title="I am a title">Click me</div>

Demo

Here's a Plunker that shows this in action.

http://plnkr.co/edit/VwdHC3l9b3qJ4PF6cGV1?p=preview

Also, once we have the value, how can we modify the returned template so we can use ng-show to show the pop-up

In the example I provided I used the jQuery hover() and mouseout() events to respond to users hovering over and away from the DOM element. If you want to take this further, here's a tutorial that shows how to put popups or alerts into services.

Upvotes: 1

tpie
tpie

Reputation: 6221

You need to assign it like this:

  app.directive('helpInfo', function(){
    return{
      restrict: 'A',
      scope: true,
      template: '<div>{{helpAttr}}</div>',
      link: function(_scope, _elements, _attrs){
       _scope.helpAttr = _attrs.helpInfo;
     }
    }  
  });

Demo

You can just use your own template and insert {{helpAttr}} binding wherever you need it.

Upvotes: 1

Related Questions