I want to append the value as html in angular
<div class="storycontent" ng-class="{show: show}">
{{review.name}}: {{review.story}}
</div>
Here in the {{review.story}} I will have value like <b>hello</b><i>something</i> etc
The problem is its displaying the content as <b>hello</b><i>something</i> instead of hellosomething (ie the styling is not applied)
I have to use jQuery to do this
$(".content").each(function () {
$(this).html($(this).text())
});
How can i directly append as .html() instead of .text() in angular?
You don't even need Jquery for that. ng-bind-html can do the trick by himself.
<div class="storycontent" ng-class="{show: show}">
{{review.name}}:
<span ng-bind-html="review.story"></span>
</div>
Moreover, it's also better to add this on your controller when you get the value. Because without this, ng-bind-hmtl isn't safe.
$scope.review.story = $sce.trustAsHtml($scope.review.story);
Note : $sce have to be injected in your controller. It's not available directly with angularJS.
.controller('ControllerName', ['$scope', '$sce', function($scope, $sce) {...
You can use directive ngBindHtml, more info here: https://docs.angularjs.org/api/ng/directive/ngBindHtml
Also you have to remeber that before binding html you have to ensure Angular that it is safe. You can use ngSanitize for it and $sce.trustAsHtml function:
https://docs.angularjs.org/api/ng/service/$sce#trustAsHtml
use ng-bind-html="expression"
expression is your html here
You can use ng-bind-html in angular.
By Docs: ng-bind-html
Evaluates the expression and inserts the resulting HTML into the
element in a secure way. By default, the resulting HTML content will
be sanitized using the $sanitize service. To utilize this
functionality, ensure that $sanitize is available, for example, by
including ngSanitize in your module's dependencies (not in core
Angular). In order to use ngSanitize in your module's dependencies,
you need to include "angular-sanitize.js" in your application.
Use: ng-bind-html="review.story">
Refer docs
Related
i am not able to access Model for model in below plunkr, please find plunkr below.please help.
<div ng-controller="PersonCtrl">
<h2>Teens - using external HTML file as template</h2>
<iframe src="teen-external.html"></iframe>
</div>
Here's the Plunkr for any ref.
You have a couple of problems in your example, first the html source was loaded in iframe, which loads it as a simple html and renders it inside the iframe without angular parsing it to do all the mastache interpolation.
To correct this since you've already created a directive that renders the teen-external.html which would allow angular to parse the said html and interpolate the relevant fields. to do this simply use the directive inside your index.html file like.
<teen-internal> </teen-internal>
or
<div teen-internal></div>
Another problem is that you're trying to access a variable/model defined inside the parents $scope which is not possible without going via the $scope.$parent. Even if you do it using the $parent it is considered a really bad practice. To this a bit more elegantly angular provides a sort of model/variable passing from parent to the child, to do this you need to change both the index.html and the teensInternal directive code.
in your index.html
or
<div teens-internal teens="teens"></div>
This sets the teens property on the teensInternal's $scope to the teens from the parent's(PersonCtrl) $scope. Now in your directive code you must define how the binding works for teens property, here you can define it as a read only # also called one way binding (modification done inside teensInternal is not reflected inside the parent controller) or as writable = two way binding (both teensInternal and PersonCtrl share the same object, so the modifications are reflected in both sides) to do this change
scope: {
},
to
scope: {
teens: '=' // or "#" for one way binding
},
This tells the directive that whatever was passed to <teens-internal teens="teens"></teens-internal> through teens="<model's name>" can be used inside the directive's $scope.
Plunkr: plunkr source
I have a custom directive which holds a <textarea> element along with other HTML elements in its template using templateUrl. This directive should allow a user to type with any Indian Language (using any writing script like devanagri and others). The user will get to select the input language.
This directive will be used like this in my HTML:<keybuddy></keybuddy>
Now my problem is, in my main code, how should I retrieve the text entered in the textarea that is located in the template.html specified by templateUrl? I have the text available in the scope of my link function since I used ng-model on the textarea.
<textarea id="inputField"
placeholder="start typing....."
ng-model="inputText"
rows="5">
</textarea>
In my index.html, I should be able to do something like this:
<keybuddy></keybuddy>
<button onclick="printText()">Show Text</button>
<script>
var printText = function () {
console.log($("keybuddy").value);
}
</script>
How do I do it? Is there any other better way using the power of AngularJS? I went through these posts but wasn't helpful. Or might be I could not understand how to use it in my work. How to set a native attribute from AngularJS directive?, How to get evaluated attributes inside a custom directive
my complete code on github: keybuddy
Note:
I should be able to use this directive anywhere in the application, any number of times.
It should be portable; I should be able to use it in any of my project or any other developer should be able to use it without much
Go Angular :-)
You don't need the use of jQuery here. Angular is sufficient enough. You can change your code like this:
In your View:
<keybuddy model="myInputText"></keybuddy>
<button ng-click="showText()">Show Text</button>
In your View controller:
$scope.showText = function() {
console.log($scope.myInputText);
}
And update your directive to have scope like below (replace your `scope: true):
scope: {
inputText: '=model'
}
Read more on Isolating scope of a directive
You can setup a bi-directional binding to the directive scope. This will allow your directive to change a value in the parent scope, which you can then read from your controller.
In your directives configuration setup the scope property with the name of an attribute to use for the binding, such as:
scope: {
model: '='
}
In your directive's template then you can set the textarea's ng-model to that binding name.
<textarea ng-model="model"></textarea>
In the parent where you use the directive, pass the attribute you configured set to the name of a variable on the scope.
<keybuddy model="inputText"></keybuddy>
Then in your controller you can access the textarea's current content by reading $scope.inputText.
$scope.printText = function(){
alert($scope.inputText);
}
Template:
<button ng-click="printText();">Print text</button>
Since it's already in the scope, you could simply use
console.log($("keybuddy textarea").scope().inputText);
AngularJS version:
console.log(angular.element("keybuddy textarea").scope().inputText);
EDIT: Adapted to match the actual source code.
I found a problem in changing html of div:
document.getElementsByClassName("lab")[0].setAttribute("ng-bind-html", "binds");
$scope.binds="<h1>run</h1>";
I am setting attribute ng-bind-htmlin java script because I have have integrated some plugin in my code in which div of class="lab" is getting declared through JavaScript. The attribute binds is attached properly, I checked this in inspect element. In fact whenever I attached property of ng-bind-html in JavaScript then ng-bind-html does not work. What is the correct way to do it? There is no error in the code.
Basically you have added ng-bind-html attribute dynamically, which will add directive attribute to the DOM but ng-bind-html directive wouldn't get evaluated the html content. You need to recompile that DOM using
$compile(document.getElementsByClassName("lab")[0])($scope)
To making sure this should work you need to add ngSanitize module in your angular app.
Demo plunkr
The way you are doing is not a standard way of doing DOM manipulation
in AngularJS. The standard approach would be keep ng-bind-html attribute there itself in html rather than adding it dynamically.
Standard way
HTML
<h1>Cleaner way</h1>
<pre ng-bind-html="binds"></pre>
Code
(function(angular) {
'use strict';
angular.module('bindHtmlExample', ['ngSanitize'])
.controller('ExampleController', ['$scope', '$compile', function($scope, $compile) {
$scope.binds="<h1>run</h1>";
}]);
})(window.angular);
Plunkr
I want to show MathML DOM object dynamically with Angularjs.
This is what I wrote:
var mathML = angular.module('mathML', ['ngSanitize']);
mathML.controller('mathMLCtrl', ['$scope', function ($scope) {
$scope.result = function(){
return "<math xmlns='http://www.w3.org/1998/Math/MathML'><msup><msqrt><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></msqrt><mn>27</mn></msup></math>";
//return "<p>p tag</p>";
};
}]);
With ng-bind-html, I can insert text as a HTML text, but MathML's XML is not inserted properly. (All tags are deleted.)
It looks like necessary to insert MathML text as DOM Objects. But I don't know how to do it.
How can I show MathML with Angularjs?
ng-bind-html sanitizes the output by removing tags that are not listed as "safe". The math tag is not listed under the allowed tags. If you trust this html to never have exploits, you'll want to use the $sce service to mark the code as trusted. See this answer:
https://stackoverflow.com/a/19417443/1248889
Another alternative would be to save this text as a partial, in it's own separate file. Then in your html, use ng-include to load the partial into the dom.
I have a partial, which has a directive which renders a bunch of things in a loop, using compiled HMTL-as-a-string inside the directive. This HTML-as-a-string itself contains an ng-include, which doesn't render out.
Please see my jsfiddle example
Basically, this doesn't include template2.html:
element.html('<span>The name is ' + scope.content.name + '!</span><div ng-include src="template2.html"></div><br>');
Any pointers would be much appreciated.
Thanks!
WORKING DEMO
just needed to write as
src=" \'template2.html\'"
var linker = function(scope, element, attrs) {
element.html('<span>The name is ' + scope.content.name + '!</span><div ng-include src=" \'template2.html\'"></div><br>');
$compile(element.contents())(scope);
};
more info in DOCS
Vinod's answer above (replace src="template2.html" with src="\'template2.html\'") is correct, though I would recommend using an actual template instead of manually compiling the template yourself inside the link function. In your example, you aren't actually receiving the benefit of the two way binding. You are just taking the html output of the compile function, and it will never update if the underlying data changes. Here is your example modified to show the bindings (and Vinod's template fix):
http://jsfiddle.net/kf3vZ/5/
Notice how if you change the value of any of the checkboxes, the value in the directives do not change.
Now here is a version using the template argument to the directive:
http://jsfiddle.net/kf3vZ/7/
Now if you change the text fields, the directive values will change also.
Another note, since you are already using the script tags for your templates, you could replace template in your directive with templateUrl and provide the id of the script template.