I don't think this is directly an issue but I don't know how to do this. I'm trying to dynamically load content that uses UI Bootstrap directives but when the content is loaded UI Bootsrap components don't work. Being more specific, tooltips don't work. Here is the important code:
<div ng-bind-html="trustSnippet(f.field.contentAfter)"></div>
The javascript
$scope.trustSnippet = function(snippet) {
return $sce.trustAsHtml(snippet);
};
The HTML I'm trying to inject is:
<i class="fa fa-exclamation-circle" tooltip-placement="right" tooltip="On the Right!"></i>
Any clues?
TY
This is because ng-bind-html doesn't compile the inserted elements, and so the UI Bootstrap directives - or any other directive or expression, for that matter, would not work.
If you are getting the HTML from a particular location, you could simply use ng-include.
For static location:
<div ng-include="'path/to/html'"></div>
Or, if the location is dynamic and stored in a scope-exposed variable: $scope.path = "path/to/html";:
<div ng-include="path"></div>
Otherwise, if the HTML itself with Angular expressions/directives is dynamically generated or imported (a rare case, which should make you re-examine your design to make sure that you are not offending any best practices), you would need to compile it using $compile service, and it is better done using a directive:
app.directive("ngBindHtmlCompile", function($compile, $sce){
return {
restrict: "A",
link: function(scope, element, attrs){
scope.$watch($sce.parseAsHtml(attrs.ngBindHtmlCompile), function(html){
var el = angular.element("<div>").html(html);
element.empty();
element.append(el.children());
$compile(element.contents())(scope);
})
}
};
});
Don't forget to add "ngSanitize" as a dependency. The usage is:
<div ng-bind-html-compile="html"></div>
I was facing the same problem. The following method worked for me.
In HTML,
<div ng-bind-html="f.field.contentAfter | unsafe"></div>
In Javascript,
app.filter('unsafe', function($sce) {
return function(val) {
return $sce.trustAsHtml(val);
};
});
Related
I am trying to create directive but my directive function is not getting called.
index.html
<div ng-repeat="que in questions.Cars">
<question-dir>print from direcetive</question-dir>
</div>
ConytrolDirective.js
(function () {
"use strict";
angular
.module("autoQuote")
.directive('questionDir',["questionDir"] );
function questionDir()
{
return {
template : "<h1>Made by a directive!</h1>"
};
}
}());
There are several mistakes in your code.
You should have function name instead of "questionDir"
.directive('questionDir',[questionDir] );
Use kebab case(- separated words) while using directive name
`<question-dir>print from direcetive</question-dir>`
Additionally you need to refer <script src="controlDirectives.js"></script> on your index.html page.
Demo here
I don't see many mistakes in your code but it would have helped many to stop assuming only if you had posted your code sample link too.
But one primary change you have to make is : Change your directive definition function invoking from
.directive('questionDir', ["questionDir"])
to
.directive('questionDir', questionDir)
See this working fiddle which has just added questions.Cars into $rootScope to make answer look more relevant to your query.
To preserve content of your directive element :
What i see in your question is : Element <question-dir> has child content / inner text print from direcetive in it and it gets overridden by Directive Element <h1>Made by a directive!</h1> completely.
That's the default nature of Angular : Element's (to which the directive is being applied) children will be lost to Directive Element. If you wanted to perserve the element's original content/children you would have to translude it.
Use transclude : true in Directive Definition Object and add <div ng-transclude></div> where you want directive Content / text print from direcetive to be included.
Code snippet :
function questionDir() {
return {
transclude : true,
template: "<div ng-transclude></div><h1>Made by a directive!</h1>"
};
}
Check this one for transclude changes.
Check these 2 links for more information on Transclude :
Understanding the transclude option of directive definition
Understanding transclude with replace
You had a few things wrong in you code:
In your IIFE closure you need to pass in angular
You need to normalize the directive name to kabab case in your html element name: `'
You need to include the reference to the directory factory in your directive registration: .directive('questionDir', questionDir);
Missing module dependencies array: .module("autoQuote", []) -- you should only have this defined once with the dependancies, [] so ignore this if you already have it elsewhere in your code.
Missing restrict in the Directive Definition Object: restrict: 'E',
If you click on Run code snippet you will see this directive now works.
(function (angular) {
"use strict";
angular
.module("autoQuote", [])
.directive('questionDir', questionDir);
function questionDir()
{
return {
restrict: 'E',
template: "<h1>Made by a directive!</h1>"
};
}
}(angular));
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="autoQuote">
<question-dir>print from direcetive</question-dir>
</div>
Finally, if you are using AngularJS 1.5 or greater you should consider using the component syntax for this.
I'm trying to find out if you can have more than one html file in a directive and then depending on what you pass through the html tag it shows a different HTML layout.
This is something that is required for a accordion that I am building. We want to be able to re-use the directive but sometimes the html will be of a different layout.
So far I believe this can be done by the following:
<accordion data-attr="layout('feedback')></accordion>
Then in the Js check what has been passed and point the accodion to a different view.
The bit I'm unsure about is pointing the accordion directive to a different html file.
You could simply use the ng-include directive in your template:
module.directive('accordion', function() {
return {
scope: { type: '&' },
template: '<div ng-include="type()"></div>'
};
});
Yes, in your directive you can set your template to be a function that accepts the element and attributes.
.directive('accordion', function() {
return {
templateUrl: function(elem, attr){
return 'layout-' + attr.type + '.html';
}
};
});
And use it like:
<accordion type="some-file"></accordion>
I am attempting to create a re-usable directive wrapper for ng-grid where I can apply the location of the ng-grid options through the use of an attribute.
Here is the skeleton of the code which gets very close to what I want:
angular.module('myApp').directive('grid', function() {
return {
restrict: 'E',
template: '<div class="gridStyle" ng-grid="someObject.gridOptions"></div>',
link: function(scope, element, attributes) {
// no code here necessary, to use the hard-coded ng-grid options
}
}
}]);
What I would like to do is supply the variable for ng-grid by using an attribute, similar to this:
<grid dataLocation="someObject.gridOptions"></grid>
I've tried using the compile and the link options with multiple methods, including reading the attributes, and then using the element.html() method to update the html to set the ng-grid attribute to "someObject.gridOptions", as well as using {{someScopeVariable}}, and setting scope.someScopeVariable to "someObject.gridOptions" in the linking function. I have verified using the chrome's html inspector that the div's attribute looks correct, but I have not been able to get the item to show up on my page.
I suspect I'm running into issues since the ng-grid is already a compiled directive. Is there any way I can pull this off? I've tried a large number of compile and linking methods with no success yet.
To access the original template's attributes, the template option of directive should be defined as a function as follows:
angular.module('myApp').directive('grid', function() {
return {
restrict: 'E',
template: function(element, attrs){
return '<div ng-grid="' + attrs.dataLocation + '"></div>';
}
};
});
Your HTML stays the same:
<grid dataLocation="someObject.gridOptions"></grid>
I am trying to render a text as html using ng-bind as the docs show
<div ng-bind-html="text"></div>
The problem is that Angular removes the style attribute and renders this:
"<mark style='background-color:#FF9DFF;'>APPLE</mark>."
to this:
<mark>APPLE</mark>
How to render as html and keep the styles?
I am using Angular version 1.2.6
You may try this function when you're doing ng-bind-html in your controller
$sce.trustAsHtml('myHTML'); //$sce would be the parameter with $scope in module
Hope this will work
$NgSanitizeDocs
First of all include angular-sanitize.js
<div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div>
Then in the controller, add this method
pk.controller("createBlog", function($scope, $sce){
//ace needs to be injected in the controller.
$scope.deliberatelyTrustDangerousSnippet = function() {
return $sce.trustAsHtml($scope.htmlcontent); //html content is th binded content.
};
})
I am storing html data in my database from the output of a WYSIWYG editor. The html also stores the html for some directives. One of them being the ui-bootstrap tooltip:
<span tooltip-placement="left" tooltip="On the Left!">Tooltip text here</span>
I am able to get any other html elements to work by using the binding:
<div ng-bind-html-unsafe="html.content"></div>
But the html with the directive's reference doesn't interact with the actual directive.
How can I get the directive to work?
Do I have to compile the html or something like that?
Yes, since the markup you are trying to render contains directives, you need to compile it so they are processed by Angular.
You could create a directive that does that for you:
app.directive('htmlRender', function($compile) {
return {
restrict: 'E',
scope: { html: '#' },
link: function(scope, element) {
scope.$watch('html', function(value) {
if (!value) return;
var markup = $compile(value)(scope);
element.append(markup);
});
}
};
});
Plunker here.
Do I have to compile the html or something like that?
Yes You need to complile the HTML as Angular will only consider as below as simple html
<div ng-bind-html-unsafe="html.content"></div>
Check below is documentation for $compile
$complie documenation