Reputation: 3098
Given this markup:
<a href="/" myDirective="Text 1 2 3 Foo">Link</a>
How can I end up with this output using a directive?
<a class="tooltip" style="left:<the left pos of the original element>; top:<the top pos of the original element>;">Text 1 2 3 Foo</a>
<a href="/">Link</a>
Thanks.
EDIT (another example):
<div myDirective="Text 1 2 3 Foo">
<ul>
<li>Bar</li>
</ul>
</div>
Gives:
<a class="tooltip" style="left:<the left pos of the original element>; top:<the top pos of the original element>;">Text 1 2 3 Foo</a>
<div myDirective="Text 1 2 3 Foo">
<ul>
<li>Bar</li>
</ul>
</div>
So I essentially want to insert the tooltip element before the given element, but preserve the given element upon output and not replace it.
Upvotes: 4
Views: 614
Reputation: 313
.directive('myDirective', function() {
return {
template: "<a class="tooltip" >{{txt}}</a><a href="/">Link</a>",
restrict : 'A',
scope: { txt : "@myDirective" },
replace: true,
link: function(scope,elm,attrs) {
}
}
})
Although I'm pretty sure that Angular requires to have one element replacing another. So if the code above shouldn't work use this (wrap it with a span):
.directive('myDirective', function() {
return {
template: "<span><a class="tooltip" >{{txt}}</a><a href="/">Link</a></span>",
restrict : 'A',
scope: { txt : "@myDirective" },
replace: true,
link: function(scope,elm,attrs) {
}
}
})
Cheers, Heinrich
UPDATE: Generic way as requested:
.directive('myDirective', function() {
return {
template: '<span bind-html-unsafe="{{tmp}}"></span>',
restrict : 'A',
scope: { txt : "@myDirective" },
replace: true,
link: function(scope,elm,attrs) {
scope.tmp = '<'+attrs.tag+' class="tooltip" >{{txt}}</'+attrs.tag+'><a href="/">Link</a>'
}
}
})
your html:
<legend myDirective="A Text" tag="legend"></legend>
I see you are new to angular so pay attention to the new scope created here. You can access the parent vars with {{$parent.var}} if you need to. But you shouldn't. Better to pass em as attributes if there aren't too much of them.
FINAL UPDATE
tryout @ http://plnkr.co/edit/JSOH0cGcYiJIWsVkB8cP
what you can do is to use $compile to do custom templating.
.directive('directive', function($compile) {
return {
restrict : 'A',
scope: { txt : "@directive" },
replace: true,
compile: function compile(elm, attrs, transclude) {
var e = elm;
e.removeAttr("directive");
elm.replaceWith('<span directive="'+attrs.directive+'"><a class="tooltip" href="">{{txt}}</a>'+e[0].outerHTML+'</span>');
elm.append(e);
return {
pre: function preLink(scope, iElement, iAttrs, controller) {
},
post: function postLink(scope, elm, iAttrs, controller) {
$compile(elm.contents())(scope);
}
}
}
}
});
your HTML template:
<div directive="{{text}}">
<ul><li>list element</li></ul>
</div>
good luck. Cheers, Heinrich
Upvotes: 2