AngularJS - Display image using directive - javascript

Image Constants
angular.module('app-config', []).constant('imageConstant',
{
logoPath: 'assets/img/logo/',
faviconPath: 'assets/img/favicon/',
layoutPath: 'assets/img/layout/',
logoFileName: 'myLogo.png'
});
Directive
myApp.directive("streamingLogo", function () {
var linker = function (scope, element, attrs) {
//pass image constants here to append image url
//for ex: src = imageConstant.logoPath + imageConstant.logoFileName;
};
return {
restrict: "A",
link: linker
};
});
HTML
<img class="my-logo" id="my-logo" ng-src="{{src}}" streamingLogo/>
I have configured image url and file names in a constant file. How do
I pass it in a directive to append image path and name dynamically so
that the it gets displayed using above directive ?
The idea is to have a configuration file for image path and names so that in HTML, only ng-src="{{src}}" is passed instead of full absolute path.

Add imageConstant dependency to your directive and you are good to go, like this:
myApp.directive("streamingLogo", ['imageConstant', function(imageConstant) {
var linker = function (scope, element, attrs) {
scope.logoPath = imageConstant.logoPath;
scope.favIconPath = imageConstant.faviconPath;
scope.layoutPath = imageConstant.layoutPath;
scope.logoFileName = imageConstant.logoFileName;
};
return {
restrict: "A",
link: linker
};
}]);

Inject imageConstant to your directive and add app-config as module dependency.
myApp.directive("streamingLogo", function (imageConstant) {
var linker = function (scope, element, attrs) {
scope.src= imageConstant.logoPath;
};
return {
restrict: "A",
link: linker
};
});
then in linker function
Then in HTML
<img class="my-logo" id="my-logo" ng-src="{{src}}" streaming-logo/>
Note
Change streamingLogo to streaming-logo on HTML

You can inject your constant like any other angular provider:
myApp.directive("streamingLogo", ['imageConstant', function (imageConstant) {
var linker = function (scope, element, attrs) {
console.log(imageConstant.logoPath);
console.log(imageConstant.faviconPath);
console.log(imageConstant.layoutPath);
};
return {
restrict: "A",
link: linker
};
}]);

you have to inject constants as dependency for your directive
myApp.directive("streamingLogo", function (imageConstant) {
var linker = function (scope, element, attrs) {
};
return {
restrict: "A",
link: linker
};
});
notice that you need to inject your dependencies in other ways (check this) if you want to minifey your javascript files for production.
myApp.directive("streamingLogo", ['imageConstant',function (imageConstant) {
var linker = function (scope, element, attrs) {
};
return {
restrict: "A",
link: linker
};
}]);

You need to inject the imageConstant into the .directive function.
var myApp = angular.module('app-config', []);
myApp.directive("streamingLogo", ['imageConstant', function(imageConstant) {
return {
restrict: "A",
link: function (scope, elem, attrs) {
scope.logoPath = imageConstant.logoPath;
scope.favIconPath = imageConstant.faviconPath;
scope.layoutPath = imageConstant.layoutPath;
scope.logoFileName = imageConstant.logoFileName;
}
};
}]);
small change in Html code :
use streaming-logo instead of streamingLogo.
<img class="my-logo" id="my-logo" src="{{logoPath}}" streaming-logo/>

Related

ng-directive not working after setting compiled html to div

Before setting the compiled html to dynamic-html div, my dynamicHtml is working correctly. As you can see, there's a onClick function in directive.
But unfortunately, after setting compiled html to div, onClick is not called anymore.
var content = $compile(res)($scope);
$('dynamic-html').html(content);
My dynamicHTML directive looks like this:
.directive('dynamicHtml', function($compile, $timeout) {
return {
restrict: 'E',
transclude: true,
link: function($scope, $element) {
$scope.datePickers = {};
$scope.onClick = function (variable, $event) {
var currentTarget = $event.currentTarget;
$scope.$parent.$parent.highlight(variable, true, currentTarget);
};
I tried to add transclude on directive as you can see. But it's not working on this case.
Can you please guide me to solve this problem?
Check it out the following code,
angular.module("myApp", [])
.directive("compiled", function($compile){
return {
restrict: "AE",
scope: {},
link: function(scope, ele, attrs){
var compiled = $compile("<div><hello-world></hello-world></div>")(scope);
ele.replaceWith(compiled);
}
}
})
.directive("helloWorld", function(){
return {
restrict: "AE",
scope: {},
transculde: true,
link: function(scope, ele, attrs){
scope.sayhello = function(){
alert("Hello World");
}
},
template: '<button ng-click="sayhello()">Say Hello</button>'
}
})
Html
<compiled></compiled>

Pass an attribute directive to an element directive

I try to pass an attribute directive to an element directive, is it possible? I tried do it as in example but it doesn't work.
for example I have element directive:
<np-form-input
np-form-input-attrs="np-my-attr-directive"
>
</np-form-input>
JS:
.directive('npFormInput', [function () {
return{
restrict: 'E',
templateUrl: '/resources/view/common/form_input',
link: function(scope, element, attr){
scope.attributes= attr.npFormInputAttrs;
}
};
}])
And then in directive HTML
<input
{{attributes}}
>
Thanks in advance.
EDIT: My solution based on Micah Williamson answer:
.run(['$templateCache', '$http', function($templateCache, $http){
$http.get('/resources/view/common/form_input').success(function(data){
$templateCache.put('/resources/view/common/form_input', data);
});
}])
.directive('npFormInput', ['$templateCache', '$compile', function ($templateCache, $compile) {
return{
restrict: 'E',
compile: function (ele, attrs) {
var tpl = $templateCache.get('/resources/view/common/form_input');
tpl = tpl.replace('{{attributes}}', attrs.npFormInputAttrs);
var tplEle = angular.element(tpl);
ele.replaceWith(tplEle);
return function (scope, element, attr) {
$compile(tplEle)(scope);
};
},
};
}])
I've done something similar to what you're trying to do but I had to inject the attributes in the compile. You would need to add the template to $templateCache first though.
.directive('npFormInput', [function ($templateCache, $compile) {
return{
restrict: 'E',
compile: function(ele, attrs) {
var tpl = $templateCache.$get('/resources/view/common/form_input');
tpl = tpl.replace('{{attributes}}', attrs.npFormInputAttrs);
var tplEle = angular.element(tpl);
ele.replaceWith(tplEle);
return function(scope, element, attr){
$compile(tplEle)($scope);
};
}
};
}])

AngularJS - Directive wrapping without losing connection to controller

Is there a way for not losing connection to the current controller when you are wrapping data with a directive ?
My problem is, that the directive within the wrapped template has no connection to the outside controller any more and so I can not execute the function.
Wrapping Directive:
myApp.directive('wrapContent', function() {
return {
restrict: "E",
scope: {
model: "=",
datas: "="
},
templateUrl: "./any/template.php",
link: function(scope, element, attr) {
// any
}
};
});
Directive within the wrapped Template
myApp.directive('doAction', function() {
return {
restrict: "A",
link: function(scope, elem, attrs) {
$(elem).click(function(e) {
scope.$apply(attrs.doAction);
});
}
}
});
Conroller:
lmsApp.controller('OutsideController', function ($scope){
$sope.sayHello = function() {
alert("hello");
};
});
HTML where I want to execute the function (template.php):
<div>
<do-action="sayHello()"></do-action>
</div>
How I call the wrapContent directive which is outside (Updated):
<div ng-controller="OutsideController">
<wrap-content model="any" datas="data_any"></wrap-content>
</div>
How can I execute the sayHello() function?
Thank you for your help! I would appreciate every answer.
wrapContent directive will be processed with the scope of controller.
DoAction directive will be processed with the isolateScope of wrapContent directive.
Solution1:
Get a reference to the sayHello function in wrapContent using '&' and execute it in event handler.
Solution2:
Instead of using scope in your event handler, use scope.$parent.
You should pass sayHallo function to your parent directive using &
myApp.directive('wrapContent', function() {
return {
restrict: "E",
scope: {
model: "=",
datas: "=",
sayHallo: "&"
},
templateUrl: "./any/template.php",
link: function(scope, element, attr) {
// any
}
};
});
HTML
<div ng-controller="OutsideController">
<wrap-content model="any" datas="data_any" sayHallo="sayHallo()"></wrap-content>
</div>
Then in your child directive, you will have sayHallo in your scope, to call it just do it this:
myApp.directive('doAction', function() {
return {
restrict: "A",
link: function(scope, elem, attrs) {
scope.sayHallo();
}
}
});
And you dont need pass it again. So your child directive should looks like this:
<div>
<do-action></do-action>
</div>
UPDATE
If you want to use all your parent model functions,without passing each function. In your child directive,just use scope.model to have access to model attributes and functions.
myApp.directive('doAction', function() {
return {
restrict: "A",
link: function(scope, elem, attrs) {
scope.model.sayHallo();
}
}
});

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

Passing HTML to a template inside Angular directive

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

Categories

Resources