Rendering text to html with Angular - javascript

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

Related

Angular js : Unable to create directive

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.

ng-bind-html with UI Bootstrap directives

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

Calling controller functions from the view in AngularJS

I have a function in my BlogController which changes the height of a div.
$scope.setTopBackgroundHeight = function (screenProportion, targetDiv) {
globalService.setTopBackgroundHeight(screenProportion, targetDiv);
};
I am using this controller on a few pages, but only want to call this function on one page. So I put the call in my view as follows.
<div id="primary"
class="content-area blog-page"
ng-controller="blogCtrl">
{{$scope.setTopBackgroundHeight("half", ".background-container");}}
</div>
Now, this works. But is calling a function from within curly braces in the view ok to do style wise? I've tried to find examples of doing something like this in the angular way, but can't see anything. Should it be in some ng directive?
Yes, all DOM manipulation should be done inside directives. So In this case it'd be better if you had a directive attached to the div that called that service method.
HTML:
<div id="primary"
class="content-area blog-page"
ng-controller="blogCtrl"
setBGHeight>
</div>
JS:
app.directive('setBGHeight', function(globalService) {
return {
link: function() {
globalService.setTopBackgroundHeight("half", ".background-container");
}
}
));
This is what directives are for. Make sure to prefix them like angular does with "ng-click" but don't use ng.

AngularJS- How to call controller's function on click of checkbox which is created in directive template

I am new to angularJS. I want to create checkboxes dynamically using templates in directives. I created controller and directives in separate files. I am creating checkbox in template in directive and want to invoke controller's function on ng-click of check box but I am unable to do so.
Here is my code sample.
Controller:
var app=angular.module('abc',[]);
app.controller('DemoCtrl', function($scope) {
$scope.ctrlFn = function(test) {
alert("hi "+test);
console.log(test);
}
});
I referred the https://github.com/iVantage/angular-ivh-treeview to create checkboxes tree view. I inlcuded all the css and js files in my sample. From the link I got the following js file which is creating the checkboxes in template in directive as shown below:
ivh-treeview.min.js:
angular.module("ivh.treeview",[]),
angular.module("ivh.treeview").directive("ivhTreeviewCheckbox",[function(){
"use strict";
return{restrict:"A",
scope:{node:"=ivhTreeviewCheckbox"},
require:"^ivhTreeview",
link:function(a,b,c,d){
var e=a.node,f=d.opts(),g=f.indeterminateAttribute,h=f.selectedAttribute;
a.isSelected=e[h],
a.ctrl=d,
a.$watch(function(){return e[h]},function(b){a.isSelected=b}),
a.$watch(function(){return e[g]},function(a){b.find("input").prop("indeterminate",a)})},
template:['<input type="checkbox"','ng-model="isSelected"','ng-change="ctrl.select(node, isSelected)" />'].join("\n")}
}]);
View:
<div class="col-sm-8" ng-controller="DemoCtrl as demo">
<div ivh-treeview="demo.bag"
ivh-treeview-selected-attribute="'isSelected'"
ivh-treeview-id-attribute="'uuid'"
ivh-treeview-expand-to-depth="0">
</div>
</div>
I want to call ctrlFn() on click of checkbox created in directive template. Please suggest a way to do the same.
Thanks In Advance
Sounds like you are looking for a two-way binding between directive and parent $scope.
// parent controller scope
$scope.person = { name:'coldstar', class:'sexy beast' };
// directive declaration
<div a-person='person'></div>
// directive code
scope: {
// the = sign is the key. could also be a function instead of object
innerPerson: "=aPerson"
},
link: function (scope, elm, attr){
// now this change will be reflect in the parent controller also
scope.innerPerson.name = "not coldstar anymore";
}
Edit:
I also noticed "'isSelected'" which should be "isSelected" if isSelected is a $scope.* entity

Rendering html in Angular with Directive

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

Categories

Resources