Passing HTML to a template inside Angular directive - javascript

I need the HTML in newValue to work but it seems to just spit out escaped charaters
.directive('ngLookup', function () {
return {
restrict: 'A',
scope : {
text : '='
},
template: '{{newValue}}',
link: function (scope, elem, attrs) {
scope.newValue = scope.text.replace(/test/g,'test');
}
}
})
My solution using the answer below:
.directive('ngLookup', function ($compile) {
return {
restrict: 'EA',
scope : {
text : '='
},
link: function (scope, elem, attrs) {
var txt = '<span>'+scope.text.replace(/test/g,'test')+"</span>";
var newElement = $compile(txt)(scope);
elem.replaceWith(newElement);
}
}
})

You will have to compile the HTML yourself with the $compile-Service.
Do something like:
.directive('ngLookup', function ($compile) {
return {
restrict: 'A',
scope : {
text : '='
},
link: function (scope, elem, attrs) {
var newElement = $compile('test')(scope);
elem.replaceWith(newElement);
}
}
})

Related

AngularJS - Why I cannot get element class name in directive's link function?

I got below code. I expect it will show me true. However, it show me false.
Can anyone explain it to me and provide me a solution to check if the class existed in the element? Thanks in advance.
// HTML
<tit-txt class="{{editable}}" ng-model="mdEnt.phone"></tit-txt>
//JS
.directive('titTxt', function () {
return {
restrict: 'E',
scope: {
ngModel: '=',
},
link: function (scope, element, attrs) {
console.log(element.hasClass('editable'));
},
template: '<input ng-model="ngModel" />',
};
})
Use a watcher to detect when the class is updated:
app.directive('titTxt', function () {
return {
restrict: 'E',
scope: {
myModel: '=',
},
link: function (scope, element, attrs) {
scope.$watch(hasClassEditable, function() {
console.log(element.hasClass('editable'));
});
function hasClassEditable() {
return element.hasClass('editable');
}
},
template: '<input ng-model="myModel" />',
};
})
Interpolated bindings such as class={{editable}} update each digest cycle. The directive needs to wait for a binding to update before using the value.
The DEMO
angular.module("app",[])
.run(function($rootScope,$timeout) {
$rootScope.$timeout = $timeout;
})
.directive('titTxt', function () {
return {
restrict: 'E',
scope: {
myModel: '=',
},
link: function (scope, element, attrs) {
scope.$watch(hasClassEditable, function(value) {
console.log("has class 'editable'", value);
});
function hasClassEditable() {
return element.hasClass('editable');
}
},
template: '<input ng-model="myModel" />',
};
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
<input type="checkbox" ng-model="editable" ng-change="$timeout()"
ng-true-value="'editable'" ng-false-value="''" />
add class "editable"
<br>
<tit-txt class="{{editable}}" my-model="inputTxt"></tit-txt>
<br>
editable="{{editable}}"
<br>
inputTxt="{{inputTxt}}"
</body>
Try to do it like this:
// HTML
<div ng-app="myApp" ng-controller="myController">
<tit-txt custom-class="customClass"
cust-var="myVal"></tit-txt>
<div ng-bind="myVal"></div>
</div>
//JS
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.customClass = "editable";
$scope.myVal = "this";
});
app.directive('titTxt', function () {
return {
restrict: 'AE',
replace: true,
scope: {
customClass: '=',
custVar: '='
},
link: function (scope, element, attrs) {
console.log(scope);
console.log((scope.customClass === "editable"));
},
template: '<input class="myClass" ng-Model="custVar"/>',
};
})
EDIT: Edited the code to include the working code. Here is the link for plunker
Try this instead:
link: function (scope, element, attrs, controller) {
console.log(angular.element(element).hasClass('editable'));
}
Try with pre function,
link: {
pre: function(scope, element, attr, controllers) {
console.log(element.hasClass('editable'));
},
post: function(scope, element, attr, controllers) {
},
}

Angular js : How to use link function to set value in directives

I created directives for form input controls.
function textControlDir()
{
return {
transclude: true,
restrict: 'E',
scope: {
data: '=data',
default: '=default'
},
template: "<div ng-transclude></div><label>{{data._text}} </label><input ng-model='answer.PC' type='text' name='{{data._attributeName}}' id='{{data._attributeName}}' value='{{default}}' >"
,
link: function (scope, element, attrs)
{
console.log('default');
console.log(scope.default);
}
};
}
Html
<div ng-if="que.QuestionData._fieldType === 'text'" >
<text-control-dir data="que.QuestionData" default="{{answers[que.QuestionData._attributeName]}}"></text-control-dir>
</div>
Here for input box I want to set value. that would be as per condition.
In link function of directive i am trying to write like
link: function (scope, element, attrs)
{
if(scope.default == ''){
scope.default = que.QuestionData._pageAttributes.defaultValue
}
}
As you have suggested that you have a E element directive, so you can make use of attrs param of link function:
link: function (scope, element, attrs){
if(attrs.default == ''){
attrs.default = que.QuestionData._pageAttributes.defaultValue
}
}
(function() {
var app = angular.module('demoApp', []);
app.controller('demoController', [demoController])
.directive('textControlDir', [textControlDirective])
function demoController() {}
function textControlDirective() {
return {
restrict: 'E',
template: "<div ng-transclude>::::textControlDirective::::</div>",
link: function(scope, element, attrs) {
console.log(attrs.default);
}
};
}
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.1/angular.min.js"></script>
<div ng-app='demoApp' ng-controller='demoController'>
<text-control-dir data="dataAttr" default="defaultAttr"></text-control-dir>
</div>

Angular directive event not triggered in compile function

I have tried alot but didn't got success, how can i trigger ng-click in such scenario where it is bind in compile function?
function() {
return {
restrict: 'EA',
compile: function(element, attr) {
return function(scope, element, attr) {
element.html('<div ng-click="save()"></div>');
}
},
controller : function($scope){
$scope.save = function(){
console.log('save');
}
}
};
}
])
Use the link and $compile to produce the results you require:
return {
restrict: 'EA',
link: function (scope, element) {
element.html('<div ng-click="save()">save</div>');
$compile(element.contents())(scope);
},
controller: function ($scope) {
$scope.save = function () {
console.log('save');
}
}
}

Adding a class to a trustedValue AngularJS

I have the following html:
<li class="editor" ng-model="post.text" ng-bind-html="post.text" add-class="post.text"></li>
where post.text is a wrapped trustedValue, that looks like this:
after I unwrap it, it looks like this:
Now, I want to make a directive, that searches that trustedValue, and adds a class to the img tags. So far I have this:
function AddClassToImg($sce) {
return {
restrict: 'A',
scope: {
addClass: '='
},
link: function (scope, elem, attrs) {
var content = scope.addClass.$$unwrapTrustedValue();
$(content).find('img').addClass('test');
}
}
};
angular.module('UserProfile')
.directive('addClass', ['$sce', AddClassToImg]);
How can I get the post.text from the html, two-way-bind to it, and add to all images in post.text that class?
I am just copying your code and adding logic to compile. Their might be slight modifications you might be required to do:
function AddClassToImg($sce,$compile) {
return {
restrict: 'A',
scope: {
addClass: '='
},
link: function (scope, elem, attrs) {
var content = scope.addClass.$$unwrapTrustedValue();
var imgElement = angular.element(content.querySelector('img'));
imgElement.addClass('test');
$compile(content)(scope);
}
}
};
angular.module('UserProfile')
.directive('addClass', ['$sce', AddClassToImg]);
I solved it, for everyone wondering the same thing, here is the code:
function AddClassToImg($sce, $compile){
return {
restrict: 'A',
scope:{
addClass: '='
},
link: function (scope, elem, attrs){
var content = scope.addClass.$$unwrapTrustedValue();
var newContent = $("<div>").append($(content).find('img').addClass('col-md-12 col-xs-12').end()).html();
scope.addClass = $sce.trustAsHtml(newContent);
}
}
};

How to Replace an Angular Attribute

How do I replace an Angular attribute that already has a value in it? For example:
angular.module('app', [])
.directive('edit', function(){
return {
template: '<a ng-href="{{data}}">Link Text</a>',
replace: true,
link: function(scope, elm, attr){
scope.data = 'http://www.example.com';
}
};
});
HTML:
<a edit ng-href="test"></a>
That just appends the link url to the "test" href. I tried using
elm.attr('ng-href', '{{data}}');
and many variations on that idea, but it didn't work.
You can use compile function in directive, and redeclare this attribute in it:
.directive('edit', ['$timeout', function($timeout) {
return {
template: '<a ng-href="{{data}}">Link Text</a>',
replace: true,
restrict:'A',
compile:function(elm, attr){
return {
pre: function preLink(scope, iElement, iAttrs, controller) {
iAttrs.ngHref = "{{data}}";
},
post: function postLink(scope, iElement, iAttrs, controller) {
scope.data = 'http://www.example.com';
}
}
}
}
}])
http://plnkr.co/edit/lBA9xR1VbWHqHbc5KG7w?p=preview

Categories

Resources