I'm having some trouble getting an iframe to work through using ng-bind-html. I have all my data inside an array. I've been mainly using ng-bind-html to keep it all in one place. I can't seem to get it to work with iframe's though.
Here is an example of what I'm trying to do.
xPlunker
As you can see it isn't really doing anything.
You need to use $sce:
$sce ("Strict Contextual Escaping") is a built-in angular service that automatically sanitize content and internal sources in templates.
injecting external sources and raw HTML into the template requires manual wrapping of$sce.
In this example we'll create a simple $sce sanitation filter:.
Demo
.filter('sanitizer', ['$sce', [function($sce) {
return function(content) {
return $sce.trustAsResourceUrl(content);
};
}]);
Usage in template
<div ng-repeat="item in items">
<!-- Sanitize external sources -->
<iframe ng-src="{{item.youtube_url | sanitizer}}">
<!-- Sanitaize and render HTML -->
<div ng-bind-html="{{item.raw_html_content| sanitizer}}"></div>
</div>
Related
Currently i am trying to build an community page in which user can contribute there articles in well text format. My backend is cakephp and front-end is angular-js
How can i store text in well formatted html style for example input text which i want to store in Mysql is
<b> hello </b><br/>
<em>world </em>
and when i fetch text from table output must be like
hello
world
update:-
and it should also work for inline CSS if it is possible then it is great.
<div style="color:#D2691E">hiiii</div>
i don't need to implement fancy animation-css tag but it should support basic css.
thank you in advance
You can use the ngBindHtml directive, but before you must include the $sanitize service and put ngSanitize as a dependency of your application module.
Also implemented a trusted filter with the use of $sce which is a service that provides Strict Contextual Escaping services to AngularJS.
Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain contexts to result in a value that is marked as safe to use for that context.
Code:
angular
.module('myApp', ['ngSanitize'])
.filter('trusted', ['$sce', function($sce) {
return function(str) {
return $sce.trustAsHtml(str);
};
}])
.controller('myController', function($scope) {
$scope.myHTML = '<b>hello</b><br/><em>world</em>';
$scope.myHTMLStyled = '<div style="color: #D2691E">hiiii</div>';
});
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-sanitize.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<div ng-bind-html="myHTML"></div>
<div ng-bind-html="myHTMLStyled | trusted"></div>
</div>
What easy way to insert html item to exists template HTML in angularjs?
For example there is template generated in PHP:
<div id="block">
<!-- Insert here template from Angularjs-->
<div class="item"></div>
<div class="item"></div>
</div>
I can Use Jquery like as:
$('#block').prepend('<div class="item"></div>');
How I can same in Angularjs?
You can use jquery to add HTML but you'll need to compile it first using
var compiledHTML = $compile(html)($scope);
and then pass it on to jquery's method
$('#block').prepend(compiledHTML);
But as #cerad mentioned definitely this is not the best way.
You should use angular's data binding, you can also treat is as a template engine.
eg:
your html code is this
<ul>
<li ng-repeat="msg in allMsgs">{{msg}}</li>
</ul>
your controller code is this
app.controller($scope){
$scope.allMsgs = [];
// i dont know socket.io well, so this part may not work :)
// and it's better to separate it to a service and use $rootScope.$apply()
soceket.on('msg',function(msg){
$scope.$apply(function(){
$scope.allMsgs.push(msg);
});
});
}
Note you need to use $apply in order to make the data binding work when data is
changed by events that angular doesn't control.
Some useful links
a blog about angular socket-io
$apply doc
here is my testing page :
<div ng-controller="test">
<input ng-keyup="asIwrite($event)" />
<p id="entityContent"></p>
</div>
and my controller :
EntitiesApp.controller('test', ['$scope', function ($scope) {
$scope.asIwrite = function ($event) {
$('#entityContent').html($event.srcElement.value);
}
}]);
this is actually working, if i write click in the input, the paragraph will hold the clickable url (processed html).
I am using jQuery to update the content of the paragraph as to show html element as they render in the page..
But using jQuery is a work-around in my opinion.
I want to achieve that using just Angular. How can I do ?
note : sure I can sweep jQuery off my project and use innerHTML of the
element but I want to know the way of doing that in Angular with
bindings. I used ng-bind on a paragraph element but that just
render the value of the textarea as is, no html process is performed.
See working example below.
You are right by doubting using jQuery is the right thing to do, and as you would expect it is not. The angular way to do that is register your input into the scope using ng-model, and the way to display it is using the ng-bind-html directive. (or simply ng-bind if it was simple text with no HTML)
However, Angular will not allow HTML binding by default as it could be a security issue. If you are sure about what you write, you can use $scope.trustAsHtml as showed in my example.
angular.module('test', [])
.controller('test', ['$scope', '$sce', function ($scope, $sce) {
$scope.trust = function(content) {
return $sce.trustAsHtml(content);
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="test">
<input ng-model="content"/>
<p ng-bind-html="trust(content)"></p>
</div>
You probably have tried to do something like this but the content doesn't come out as html
<input ng-model="input" />
<p id="entityContent" ng-bind-html="input"></p>
You need to ensure strict context escaping as described here:
https://docs.angularjs.org/api/ng/service/$sce
Please keep in mind what you're saying you want to do is explicitly prevented by angular developers as a way to mitigate XSS attacks
You don't need to do that, angular is simplier than that.
<div ng-controller="test">
<input ng-model="variable1" />
<p id="entityContent">{{variable1}}</p>
</div>
Angular binds variables automatically. When the input's value change, the new value will be printed.
I am experimenting with the AngularJS approach for PhoneJS. So far I am really enjoying both frameworks.
Current issues:
Using a dx-gallery or dx-list with a datasource and a template will cause the initial un-bound template to be rendered when the view is navigated.
I found this out once I started using the dx-gallery widget and specifying a template. The console will show a network request for the initial template (not bound) being requested.
Code
<div dx-gallery="{ dataSource: imagesDataSource, height:'60%' }">
<div data-options="dxTemplate: { name: 'item' }">
<img src="http://somehostingcompany.com/{{public_id}}.jpg">
</div>
Question:
How can I not have the initial HTML template rendered when using a PhoneJS dx-gallery widget and a template?
Use ns-src binding instead of specifing src directly:
<img ng-src="http://somehostingcompany.com/{{public_id}}.jpg" />
Check out link https://docs.angularjs.org/api/ng/directive/ngSrc
I want to bind tag name to variable in AngularJs. Direct way doesn't work:
<div ng-app ng-init="list=['pre', 'div', 'em']">
Check the list: {{list}}
<div data-ng-repeat="item in list">
{{item}}: <{{item}}>content</{{item}}>
</div>
</div>
How to do it right?
You're going to want to make a Directive and use the $compile service module.
Angular template system works on DOM tree, not on strings, so template must be valid HTML and usage of {{}} for tagname is impossible. We can write own directive for it (see Max answer) or if here is small set of options it can be more easy to use ng-include and set of templates for options.