Using Qtip2 inside an Angular Directive Template - angularjs

I am trying to use Qtip2 with Angular Directive Template.
Inside my Angular Directive Template are buttons and they are inside an angular ng-repeat loop.
And inside this ng-repeat loop, there is a unique variable called 'value' which is the name of each button.
So what I want is to use Qtip2 with this directive template that will display the 'value' tooltip.
The directive template looks something like this:
<button ng-mouseover="qtipping(value)"> {{value}} </button>
How do I implement this? I tried add an attribute to the button with a ng-mouseover="qtipping(value)" but it doesn't work.
The code inside my link function looks something like this:
link: function(scope,element,attrs){
scope.qtipping = function(value){
$("button").qtip({
content:{
text: value //This will appear the unique name of the button
}
})
}
}
When I run the code, basically nothing happens. I mouseover the buttons with nothing. No error too.
The code that works is:
link: function(scope,element,attrs){
$("button").qtip({
content:{
text: "TestMessage" //This will appear the unique name of the button
}
})
}
Without using a function. But I need a FUNCTION to extract the 'value' from the template dom. How do I go about doing this? I am also quite noob in Angular.

You should create a separate directive to show qtip on each button. Here is a directive to add qtip to an element:
.directive('qtip', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
$(element).qtip({
content: {
text: attrs.qtipText
}
});
}
};
}
use it like this:
<button qtip qtip-text="{{value}}"> {{value}} </button>
EDIT: The code had a missing brace. Fixed that, here is a working plunker: http://plnkr.co/edit/uVdpf5gLILd82dr62V03?p=preview

Related

Run 'ng-click' inside a directive's isolated scope

Thanks in advance for taking the time to look into this question
I have serverside generated code that renders a directive wrapped around pre-rendered content.
<serverside-demo color="blue">
<p><strong>Content from Server, wrapped in a directive.</strong></p>
<p>I want this color to show: <span ng-style="{color: color}">{{color}}</span></p>
<button ng-click="onClickButtonInDirective()">Click Me</button>
</serverside-demo>
This means that 1.) the directive tag, 2.) the content inside the directive tag, 3.)the ng-click and 4.) The curly braces syntax are all generated by the server.
I want AngularJs to pick up the generated code, recompile the template and deal with the scope.
The problem is that I am having trouble getting it working. I understand that because the ng-click is inside the controller block, it is picked up not by the directive isolated scope, but the parent controllers. Instead I want the opposite... to pick up the onClickButtonInDirective scope function inside the serversideDemo link
I have created a jsfiddle best explaining my problem, which aims to clearly demonstrate the working "traditional" way of loading the template separately (which works) comparing it to the server-side way.
https://jsfiddle.net/stevewbrown/beLccjd2/3/
What is the best way to do this?
Thank you!
There are two major problem in your code
1- directive name and dom element not matched, - missing in dom element
app.directive('serverSideDemo', function() {
use <server-side-demo color="blue"> instead of <serverside-demo color="blue">
2- you need to compile the html code of server-side-demo dom with directive scope in link function
$compile(element.contents())(scope);
Working jsfiddle
Use templateUrl instead of template to fetch the content of directive from server:
app.directive('serverSideDemo', function() {
return {
restrict: 'AE',
scope: {
color: '='
},
templateUrl: 'link/that/returns/html/content',
link: function(scope, element, attrs) {
scope.onClickButtonInDirective = function() {
console.log('You clicked the button in the serverside demo')
scope.color = scope.color === 'blue' ? 'red' : 'blue';
}
}
};
});
Have a look at angular docs for more details

angular to append a template on click of button

I am trying to append some html to the existing container through angular directives. here is the code what i have written for the same.
app.directive("addActivityRow", function($compile){
var template = "Some html template"
return{
restrict: 'A',
link: function(scope, element,attrs,controller){
element.on("click", function() {
console.log("clicked on add row");
element.parent().append(template);
});
}
}
});
here is the html markup
Can any one please help me in correcting the error what i have done ? When i click on anchor tag, nothing happens, nothing logs on console.
I am new to Angular please help ..
Replace this:
href="javascript:void(0);"
with this:
href=""
And use add-activity-row instead of addActivityRow as #PSL mentioned that directive names are used as dash-limited attributes in the view.

Dynamically add angular attributes to an element from a directive

I'm trying to build a directive that change loading status on buttons for slow ajax calls. Basically the idea is to set an attribute "ng-loading" to a button element, and let the directive add the rest of stuff.
This is the html code:
<button class="btn btn-primary" name="commit" type="submit" ng-loading="signupLoading">
Submit
</button>
And this is the directive code:
.directive('ngLoading', ['$compile', function($compile) {
return {
restrict: 'A',
replace: false,
terminal: true,
link: function(scope, element, attrs) {
element.attr('ng-class', '{loading:' + attrs['ngLoading'] +'}');
element.attr('ng-disabled', attrs['ngLoading']);
element.append(angular.element('<img class="loading-icon" src="/assets/images/loading-icon.gif"/>'));
$compile(element.contents())(scope);
}
};
}]);
It all looks correct in the rendered HTML, but the attributes added from the directive is not funcioning at all. I can move those attributes to the HTML code and everything works great, but that's quite some redundant code in many places.
I referenced the post Angular directive to dynamically set attribute(s) on existing DOM elements but it does not solve my problem.
Any comment/suggestion are welcome. Thanks in advance.
You don't need to recompile that directive if all you want is some DOM manipulation, you can add and remove class in regards to the changes of a scope property. You can use $watch instead.
JAVASCRIPT
.directive('ngLoading', function() {
return function(scope, element, attrs) {
var img = angular.element('<img class="loading-icon" src="/assets/images/loading-icon.gif"/>');
element.append(img);
scope.$watch(attrs.ngLoading, function(isLoading) {
if(isLoading) {
img.removeClass('ng-hide');
element.addClass('loading');
element.attr('disabled', '');
} else {
img.addClass('ng-hide');
element.removeClass('loading');
element.removeAttr('disabled');
}
});
};
});
Note: Your code doesn't work because it compiles the contents of the elements, not the element itself, where you attach the attributes you have implemented.
try $compile(elem)(scope); and it should work properly, but I don't recommend it because each element with such directive will have to re-compile again.
UPDATE:
before using $compile remove the attribute 'ngLoading' to the element to prevent infinite compilation.
elem.removeAttr('ng-loading');
$compile(elem)(scope);

Directive inside bs-tooltip is not evaluated

I am trying to have a <ul> element with its own directive (checkStrength) inside of an AngularStrap bs-tooltip title property, like this:
$scope.tooltip = {
title: '<ul id="strength" check-strength="pw"></ul>',
checked: false
};
The behavior I want is as follows: when a user clicks on the input textbox, a tooltip will appear showing the strength of the password as they enter it in the textbox.
This does not work, as shown in the two Plunkers below:
Custom "checkStrength" directive outside bs-tooltip works fine: Plunker
Custom "checkStrength" directive inside bs-tooltip does not work: Plunker
Ok, it doesn't appear that this is supported out of the box. You are going to have to create your own binding directive
Directive
.directive('customBindHtml', function($compile) {
return {
link: function(scope, element, attr) {
scope.$watch(attr.customBindHtml, function (value) {
element.html(value);
$compile(element.contents())(scope);
});
}
};
});
This go into Angular Straps code and make the follow modification on line 10 of tooltip.js in the plunker
Template
<div class="tooltip-inner" custom-bind-html="title"></div>
Then set the html property in the config to false.
Config
.config(function($tooltipProvider) {
angular.extend($tooltipProvider.defaults, {
html: false
});
})
Example: Plunker

angularJS directive with isolated scope, attribute binding doesn't work

Please see this jsfiddle: http://jsfiddle.net/viro/DK5pC/3/
What I did looks right compared to the tutorials and replies I've found, so I'm sure I'm overlooking something trivial.
I'm trying to do a directive on a html element, that will create a sibling div to display a message associated with the original element.
for example, for this html :
<input ng-model="inp" tst-msg="message" />
I would create as a sibling element:
<div class="msg">Msg:<span ng-bind="tstMsg"></span></div>
I was hoping that tstMsg in the div's scope would be bound to message in the input's scope.
Here's what the directive looks like :
angular.module('tst', [])
.directive('tstMsg', function(){
var template = "<div class='msg' >Msg:<span ng-bind='tstMsg'></span></div>";
var link = function(scope,element,attrs) {
element.parent().append(template);
console.log("link called");
};
return {
restrict: 'A',
scope: {
tstMsg: '='
},
link: link
};
});
Well that doesn't work and I can't figure out why.
You need to $compile the template you're adding to the DOM. Angular hasn't had a chance to add it's handlers, for instance the ng-bind directive to that part of the dom.
So instead of just adding the element like this:
element.parent().append(template);
These steps will let Angular process your template and then add it.
newe = angular.element(template);
$compile(newe)(scope);
element.parent().append(newe);
Updated fiddle

Resources