Reputation: 15631
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
Reputation: 1027
What is the correct way to pass an attribute's value to a template?
Values are bound to templates through the compilation process. You can compile code in the link function of your directive using the $compile
service 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();
});
}
}
});
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>
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
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;
}
}
});
You can just use your own template and insert {{helpAttr}} binding wherever you need it.
Upvotes: 1