angular to append a template on click of button - angularjs

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.

Related

multiple anchor tags click event using angularjs

I have multiple anchors tags in my document, I want to put only one function for every anchor tag click, For example in jQuery
$(document).on('click','a',function(){
window.location.href='/Home.html'
});
How I need to write in angularJs. can you please help me?
You can make a directive and add it to anchor tag
app.directive('myevent', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('click', function($event) {
$window..location.href = '/Home.html' //your link here
});
}
}
});
In your view you can this with anchor tag or normal div like
<div myevent class="click">click me</div>
OR
<a myevent href="#">click me</a>
It just a work around but I prefer you use JQuery that would be much more appropriate for this. Hope this helps. Thank you.
There are many other ways like using ng-click with a div tag to do the same.
<div ng-click="myEvent()"></div>
In controller you can use
$scope.myEvent() {
$window..location.href = '/Home.html' //your link here
}

Angular: ng-bind-html removing ng directives from HTML data fetched from Firebase

I am saving data in firebase from WYSIWYG editor using angularJS. This data will be in HTML format.
I am fetching HTML data from firebase and with the help of angular directive ng-bind-html this HTML content is sanitized and text saved on the editor will be shown to the user. This text could contain text, images, links.
<div ng-bind-html="newHTML" ng-model="cleanText1"></div>
The HTML coming for data with link is in the below format:
<p>This is text editor link<br></p>
Now if I click this link on the page it will redirect to the URL specified.But I want this link to open the page in a div which is to the right hand side of the page.
To prevent this behavior I replaced href with ng-href using code below:
$scope.newHtml=$scope.htmlcontent1.replace("href","ng-href");
$scope.newHTML=$sce.trustAsHTML($scope.newHtml);
Doing this ng-bind-html removed ng-href
<p>This is text editor <a>link</a><br></p> Which made it unclickable.
Also I have tried to add directive for a tag so that once user clicks this link I can give my own functionality instead of redirecting the user.
Directive looks like this:
app.directive('a', function ($compile) {
return {
restrict: 'AE',
link: function (scope, elem, attrs) {
var href = elem.children('a').attr('href');
console.log("href"+href);
elem.children('a').attr('href', null);
elem.children('a').attr('ng-click', 'open()');
$compile(elem.contents())(scope);
console.log("elem"+elem.children('a').attr('href'));
scope.open = function () {
alert('1');
}
}
}
})
But directive is being called once the user clicks and is redirected to the new page.
Any ideas how to make this link open in right hand side of the page?
Appreciate your help.
Let's make some tweaks in your code to get it in action.
Try this instead.
Make your own directive for sanitizing HTML in place of using ng-bind-html.
Replace
<div ng-bind-html="newHTML" ng-model="cleanText1"></div>
To
<div cleanHtml="newHTML" ng-model="cleanText1"></div>
cleanHTML will be a customized directive.
Make below directive in app.js to render HTML content.
app.directive('cleanHTML',['$compile',function ($compile) {
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
return scope.$eval(attrs.compile);
},
function(value) {
console.log(value)
// Here you can see your HTML is going to get sanitized below
element.html(value);
$compile(element.contents())(scope); // After this HTML will be sanitized.
}
)};
}])
Next is to suppress the behavior of href and apply a click function on the link so as to define your own functionality for the link.
Now replace this:
$scope.newHtml=$scope.htmlcontent1.replace("href","ng-href");
$scope.newHTML=$sce.trustAsHTML($scope.newHtml)
To
$scope.newHtml=$scope.htmlcontent1.replace
("<a ","<a ng-click=\"$event.preventDefault();open()\"");
$scope.open = function()
{
alert("Whoa! It worked :)");
//Write your code here
}
This replacement will add ng-click to Link.
For e.g. if your HTML is like this
link
It will become like this
<a ng-click="$event.preventDefault();open()" href="http://someLink">link</a>
$event.preventDefault() has been added to override href functionality so that ng-click functionality takes priority.
Now once you are able to make your link working after that comes the display part which is now a piece of cake.
You want that on click of that link content appears to the right hand side of the page.
You can fetch the content of the link and add in scope variable like this:
$scope.newHtml=$scope.htmlcontent1.replace("<a ","<a ng-click=\"$event.preventDefault();open()\"");
$scope.open = function()
{
alert("Whoa! It worked :)");
//Write your code here
//fetch the content in var content
$scope.linkContent= content;
}
use linkContent and add it to the right hand side of the DIV of HTML page where you want to display and it's done :)
<div>{{linkContent}}</div>
Hope it works.
Happy Coding !!!

Using Qtip2 inside an Angular Directive Template

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

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);

Binding HTML to the scope in Angular UI popup

I'm using the Angular UI Bootstrap directive to show a popover which functions as a dropdown menu. If I specify a HTML template for the content (using the attribute popover-template) I can use clickable links which call a function on my directive to change the value. Now, however, I need to be able to specify options on the fly so I've tried creating the HTML list and passing it to the "popover" attribute in my directive's link function. This works, in that it displays the HTML in the popover correctly, however the links aren't clickable because they're within a ng-bind-html unsafe container. I've tried compiling the HTML string I'm passing to the "popover" attribute but it prints [object Object].
Here's my directive:
MyApp.directive('dropDown', ['$compile', function($compile){
return{
restrict:'EA',
replace:true,
transclude:true,
scope:{
value : '#',
options : '='
},
controller: function($scope, $element) {
$scope.doSelect = function(option, text){
alert(option);
}
},
template: '<div>'+
'<button class="btn btn-dropdown" data-html="true" popover-append-to-body="true" popover-placement="bottom" popover-trigger="click">'+
'{{value}}'+
'<span class="icon-triangle-down"></span></button>' +
'</div>',
link: function (scope, elem, attrs) {
scope.list = '<ul class="dropdown">';
for (opt in scope.options){
if(scope.options.hasOwnProperty(opt)){
scope.list+='<li><a ng-click="doSelect(\''+opt+'\', \''+scope.options[opt]+'\');">'+scope.options[opt]+'</a></li>';
}
}
scope.list += '</ul>';
var but = elem.find("button");
var template = $compile(scope.list)(scope);
//$(but).attr('popover', template); // prints [object Object] instead of compiled html
$(but).attr('popover', scope.list); // prints html not bound to scope and therefore not clickable
$compile(elem.contents())(scope);
}
}}]);
I've created a fiddle to illustrate the problem:
http://jsfiddle.net/CaroD/7B5qB/3/
So: is there any way to compile this HTML so it can interact with the scope, or am I taking a completely wrong approach here?
All suggestions most welcome,
Thanks!
to do not a big directive like that, have you try to use the html-unsafe attribute of the tooltip provider? it gives you the possiblity to put html text into popover and so you surely interact with it.

Resources