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>
Related
I have the following <td> element
<td translate="Price-{{product-op}} {{product-np}}" translate-values=GetVal()></td>
Now, GetVal() function is potentially dangerous because it is in a third party app.
So, I have decided to strip off any malicious elements. Decided to use ng-bind
The problem is how to ng-bind and then translate in the above code?
I came up with something like,
<td ng-bind translate="Price-{{product-op}} {{product-np}}" translate-values=GetVal()></td>
but it throws angular exception.
Any ideas ?
If you are using the Angular Translate library (https://angular-translate.github.io), the translate directive should bind the value automatically. If you remove the ng-bind, it should work.
But I am not sure what library you are using for your translations, so my suggestion might not help you. You might have to provide more information.
Also ng-bind requires a value in the $scope - for example put $scope.myValue = 'My Value' in your controller and then use this in your HTML <td ng-bind="myValue"></td>. But again, I do not know what the translate directive is supposed to do.
I don't understood exactly what do you want to do, But I imagine that the exception is because the 'ng-bind' prop needs a value to do a bind like this:
<script>
angular.module('bindExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.name = 'Whirled';
}]);
</script>
<div ng-controller="ExampleController">
<label>Enter name: <input type="text" ng-model="name"></label><br>
Hello <span ng-bind="name"></span>!
</div>
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>
Suppose that I've written a web page that requires the user to key in data into forms. Suppose that there are two parts of the page that are completely separate in the DOM, yet are logically related. I need to bind them to a single model.
The first (bad) solution I can think of is to completely restructure the page so that everything to be bound to the model is contained in a single <div> element (or perhaps even put the controller on the <body> element).
Another solution might be to bind the inputs to a object that could be made a member of two different controllers, but that sounds like a bit of a kludge.
Suppose the HTML looks like this:
<input ng-model='data1' />
<div>
<!-- something complicated -->
</div>
<input ng-model='data2' />
You can create a shared service and inject into both controllers. This can be achieved by either the factory or service pattern. See SO post angular.service vs angular.factory for some insight on the difference/similarity between the two.
This is the Angular way to do this. See the AngularJS services docs for more information. A simple example may include...
<div ng-app="app">
<div ng-controller="ctrlA"></div>
<div ng-controller="ctrlB"></div>
</div>
app.service('sharedService', [function () {
this.someValue = 'yo!'
}]);
app.controller('ctrlB', ['$scope', 'sharedService', function($scope, sharedService) {
console.log(sharedService.someValue) // yo!
}]);
app.controller('ctrlA', ['$scope', 'sharedService', function($scope, sharedService) {
console.log(sharedService.someValue) // yo!
}]);
JSFiddle Link
I built something in angular using ng-repeat
<ul class="messages">
<li ng-repeat="e in enquiries">
<img src="/img/avatar.jpg" alt="">
<div>
<div>
<h5>{{e.user}}</h5>
<span class="time"><i class="fa fa-clock-o"></i> {{e.created_at}}</span>
</div>
<p>{{e.post}}</p>
<div ng-if="e.is_replied == 'no'">Delete</div>
</div>
</li>
</ul>
This is to display the inputs by users. However i did not htmlentities to encode the user input but directly insert the user input into database such as Hack However i notice when i display this message using above code. it will still display the message as Hack instead of display a "hack" link. can i say in this case angular will auto sanitize the input? Should i still need to use "ng-bind-html"?
If your post content is HTML you will need to change to ng-bind-html:
<p ng-bind-html="e.post | to_trusted"></p>
Also you will need a filter to sanitize:
app.filter('to_trusted', ['$sce', function ($sce) {
return function (text) {
return $sce.trustAsHtml(text);
};
}])
Your best bet is the $sanitize service, part of the ngSanitize module. Use the ng-bind-html directive, which automatically uses $sanitize. ng-bind-html will insert your text as raw HTML, but only if it's in the ngSanitize white list of safe HTML. If you're absolutely sure the HTML is safe (e.g., if you sanitize it on the back end), there's a way to tell Angular to stuff it in as is, regardless of the white list.
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.