AngularJS - ngBindHtml and 'unsafe' html - javascript

I am trying to render some unsafe HTML (basically a HTML snippet with some inline styling) and have the following code in my view:
<div ng-repeat="snippet in snippets">
<div ng-bind-html="snippet.content"></div>
</div>
All my styling gets removed...
I've heard of people using ngBindHtmlUnsafe however I couldn't find a reference to it and simply putting ng-bind-html-unsafe doesn't render anything.
Any help would be appreciated.

The ng-bind-html-escape was removed in AngularJs 1.2.
To achieve the same effect I would advise you to create a filter to trust the resource (you should include the $sce module ):
app.filter('unsafe', function($sce) {
return function(val) {
return $sce.trustAsHtml(val);
}; });
Usage:
<ELEMENT ng-bind-html="htmlValue | unsafe"></ELEMENT>
You shouldn't forget to include the ngSanitize as the app dependency:
angular.module('app', ['ngSanitize'])
Cheers.

You can bypass it using $sce.trustAsHtml . See documentation
self.snippet.content = $sce.trustAsHtml('some html');

Related

Angularjs convert string to html in view

I am currently trying to add links in my view. I do have links which basically contains html tags as strings.
I tried:
<p data-ng-repeat='i in links' >{$ i.link $}</p>
which basically just deploy in my view : mylink
So I did try:
<p data-ng-repeat='i in links' ><span data-ng-bind-html="i.link"></span></p>
It doesn't work though, any idea how could I achieve this ?
Thanks.
Add the $sce as a dependancy of the module
angular.module('myApp', ['$sce']);
When getting the links
angular.forEach($scope.links, function(value){
value.link = $sce.trustAsHtml(value.link);
});
Using Safe Contextual Escaping (docs.angularjs.org/api/ng/service/$sce) and using trustAs delegate you're telling Angular that this value is safe to use within that context. In this example. $sce.trustAsHtml returns an object that angular can trust is safe to as HTML.
In the first case, you'll actually want to use:
<p data-ng-repeat='i in links' >{{ i.link }}</p>
Double braces, not brace-dollar. In the second case, ng-bind-html will require that you have added "ngSanitize" to your module's dependency list.
angular.module('yourAppNameHere', ['ngSanitize'])
Edit:
If you really do want clickable links on the page, then do pretty much what #sreeramu suggested (Though I'd see if you can't find a way to add a nice description):
<p data-ng-repeat='i in links' ><a ng-href="{{i.link}}">{{i.desc}}</a></p>
(Notice that he suggested using ng-href, instead of href. He's right.)
Insert ngSanitize as a dependency to you app:
angular.module('myApp', ['ngSanitize'])
But before be ensure that you are including the script angular-sanitize.js.
Good luck!
It might be that your links have already got the a tags with it so in this case you do not need to re-add the a tags...
In this case do this...
Add this to you scripts (include acc. to your angular version)
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-
sanitize.min.js"></script>
Add this to your app.js
var app = angular.module('modulename', [ 'ngSanitize']);
And than in your view do this
If it is the div that you want the link to attach to...
<div ng-bind-html="i.link"></div>
The above would give you something as this
<div><a href='your link'></a></div>

converting Jquery to angular or making Jquery work in angular

I am new to angular and we are converting a set of screens based on jsp to angular. Initially we have written lot of code in Jquery. Converting them to angular is tedious task and thought of trying to see if we can make jquery work with angular. Here is teh code snippet that i am trying to make it work while it in Jquery.
$(document).ready(function() {
$("#ClickTask2").click(function() {
$(".ClickTask1").hide();
$(".ClickTask2").show();
});
});
Above is the piece of code I have in JQuery and i tried to make it work.
angular.element(document).ready(function() {
$("#ClickTask2").click(function() {
$(".ClickTask1").hide();
$(".ClickTask2").show();
});
});
Can anyone tell me how i could make it work with minimal changes to the above one and rest of the jqueries?
You can convert many jquery features over to Angular by simply changing the $() method to angular.element() e.g.
$('#output').html('<h1>Title</h1>');
You could convert this to:
angular.element('#output').html('<h1>Title</h1>');
However not all function work, and some are renamed e.g.
$("#output").click(function() { console.log('Hi'); });
Would need to be changed to:
angular.element('#output').on('click', function() { console.log('Hi'); });
You can find a full list of the supported functions here:
https://docs.angularjs.org/api/ng/function/angular.element
like said Luis Masuelli on the comments read the basis of Angular. a quick lesson
app.js
function TaskCtrl($scope) {
$scope.selectedTask = null;
$scope.tasks = [/* ... */];
$scope.onClickTask = function(task) {
$scope.selectedTask = task;
}
$scope.isSelected = function (task) {
return task === $scope.seletectedTask;
}
}
$scope it is a special variable, it is injected by Angular to controllers and serves to communicate the controller with the view among other things. A controller can be any function and the name does not matter.
main HTML
<ul data-ng-controller="TaskCtrl">
<li data-ng-repeat="task in tasks" data-ng-click="onClickTask(task)">
{{task.title}}
<div data-ng-show="isSelected(task)">{{task.description}}</div>
</li>
</ul>
data-ng-controller tells to Angular "this is the controller" for this tag and her children. The other directives are pretty explanatory, but the documentation you left it more clearly.
Of course I am assuming that your tasks has the following structure:
{
title: "...",
description: "..."
}
in your html you need include the angular.js, the previous js and a directive to tell angular that this is a application
<!DOCTYPE html>
<html>
<head></head>
<body data-ng-app>
<!-- main HTML -->
<script src="angular.js"><script/>
<script src="app.js"><script/>
</body>
</html>
the data- prefix on each directive is not necessary but as angular "extend" HTML and these are not native attributes, I use them to place custom attributes as "ng-repeat", "ng-controller", "ng-app" etc. They are called directives
Remember, with Angular you need not manipulate the DOM directly as is done with jQuery, except for some special exceptions

Change specific words of string to bold

I have a a single span element in my page. I am concatenating words to a single variable in AngularJS and then referencing the variable to the span element in the page.
$scope.abc = "Downstream";
$scope.abc.concat('<b>','Upstream',</b>);
When the page is viewed, it displays Downstream<b>Upstream</b>
How to display the word Upstream alone in Bold?
according to this https://docs.angularjs.org/api/ng/directive/ngBindHtml
You need to include the ngBindHtml and $sanitize service
In your js file, it should be
angular.module('App', ['ngSanitize'])
.controller('Ctr', ['$scope', function($scope) {
$scope.abc = "Downstream";
$scope.abc2 = $scope.abc.concat('<b>','Upstream','</b>');
}]);
In your html file, it should be
<div ng-controller="Ctr">
<p ng-bind-html="abc2"></p>
</div>
Seems a duplicate to angular variable generating html.
I don't know angular, but reading that post it's easy. Just do:
$scope.abc = $scope.trustAsHtml($scope.abc);
HTML
<div data-ng-bind-html="abc "></div>
Also check your Angular version, for version 1.2 or lower you could use the ng-bind-html-unsafe binding.
<div class="post-content" ng-bind-html-unsafe="abc"></div>
This does not work anymore at Angular 1.2+ According to comment of TheSharpieOne:
"It has been replaced with Strict Contextual Escaping. See docs.angularjs.org/api/ng.$sce"

Add <object> with custom attributes using AngularJS controller

I'm attempting to add an <object></object>into my html using a controller. When I load a <div> or a <p>, it works properly, but when I add an <object> it doesn't appear, nor do any custom attributes.
HTML:
<html ng-app="myAngularSite">
...
...
<div ng-controller="MyController">
<div id="myloader" ng-bind-html="myObject"></div>
</div>
JS:
var app = angular.module('myAngularSite', ['ngRoute']);
angular.module('myAngularSite', ['ngSanitize'])
.controller('MyController', ['$scope',function($scope) {
$scope.myObject =
'<object id="my_object" data="mysite.html" width="99.5%" height="400px" style="overflow:auto;border:3px ridge gray"/>';
}]);
How can I add the custom attributes and the object into my site? I noticed that attributes won't appear when I try to load a <div id"with_attribut></div> with attributes, although the divs appear by themselves.
Thanks!
The custom directive is probably the good solution, you can always add more custom behaviours. With ngBindHtml you will be limited. Here is link which can help you:
angular ng-bind-html and directive within it

AngularJS: initialize ZURB Foundation JS

I am using both AngularJS and Foundation.
To initialize Foundation JS, you have to make the following call:
$(document).foundation();
What would be the best way to make this call in an AngularJS application? Code examples would be appreciated.
Also, if I were to write a directive around a Foundation JS component, how could I ensure that Foundation is initialized?
Here is my take, in app.js:
.run(function($rootScope) {
$rootScope.$on('$viewContentLoaded', function () {
$(document).foundation();
});
});
which will re-initialize Foundation when a new view is loaded (so that the components contained in the new view are also initialized). This way, your controllers do not need to be aware of this.
You could $apply the code in order to bring it into the Angular framework. Here is an example using $rootScope with run and this could also be done inside a controller/directive with any $scope:
app.run(function($rootScope){
$rootScope.$apply($(document).foundation());
});
Another option::
$compile($(document).foundation())($scope);
Be sure to include the $compile service in your controller/directive to use it this way. E.g.:
app.directive('mydirective', function($compile) {
return {
link: function(scope, element, attrs) {
$compile($(document).foundation())(scope);
}
}
});
There is a native angularJs support for foundation. Check out Angular Foundation.
Angular Foundation is a port of the AngularUI team's excellent angular-bootstrap project for use in the Foundation framework.
It has no dependencies but angular library itself and foundation CSS only.
One method that I've been using is to just include a <script> tag at the end of my partial / template.
This way, I can target just the new content of each partial -- instead of making foundation js re-parse the whole DOM.
for example, in my header.html:
<header id="app-header">
<h1>Logo</h1>
<dl class="accordion" data-accordion>
<dd>
Panel 1
<div id="panel1" class="content">
Loren Ipsum blah blah blah....
</div>
</dd>
</dl>
</header>
<!-- add this tag on bottom of template / partial -->
<script>$('#app-header').foundation();</script>
Especially if your app has a lot of DOM elements on the page, this can improve perfomance considerably.
Try the following code:
app.run(function($timeout){
$timeout(function() {
$(document).foundation();
}, 500);
});
It solved my issue trying to get Foundation reveal working.
For TypeScript Angular 4 (or 2) projects using Components:
According to the given blog post, declare $ as a variable in the component and then call $(document).foundation(); in ngOnInit() worked for me!
With Angular, components are injected into the DOM after Foundation
has loaded. When you load up a new component, and inject it,
Foundation doesn’t know it’s there. We need to tell Foundation to
reinitialize and bind again, so these attributes will get wired up. http://justindavis.co/2017/06/15/using-foundation-6-in-angular-4/
{ import Component } from '#angular/core';
declare let $: any; // TO ACCESS JQUERY '$' FUNCTION
#Component({
selector: 'my-component',
templateUrl: './my-component.html'
// other stuff here
});
export class MyComponent implements OnInit {
constructor() {}
ngOnInit() {
$(document).foundation(); // CALL foundation() INITIALIZATION FUNCTION FROM HERE
}
}

Categories

Resources