Show user input as HTML - angular1 - angularjs

I have in my controller a variable, which is defined on the $scope, which contains an html input.
function init() {
$scope.message = params.message;
}
Where params.message could be for example something like this:
<h1>Hellow world</h1><p>Hi again</p><br><br> <b> End </b>
in the html I use it like this:
<div ng-show="showTab == 'EN'">
<div class='library-padding'>
<p>{{message}}></p>
</div>
</div>
I want it to be shown as parsed html, meaning that the tags themselves will not appear, but it's displayed as plain text, including all tags.
How can I make this input text parsed and behaving like html?
Thanks!

You're looking for the ngBindHtml directive:
https://docs.angularjs.org/api/ng/directive/ngBindHtml
<div ng-show="showTab == 'EN'">
<div class='library-padding'>
<p ng-bind-html="message"></p>
</div>
</div>

Related

AngularJS - template from variable

Tried to read about $compile, $parse and $eval however cannot get understand how to store a template in a variable then use it during rendering processes.
What I would like to achieve:
code:
const data = {
template: 'test {{foo}} some text {{bar}}',
}
html:
<p> some text </p>
<h1> <included in here: data.template> </h1>
result:
<p> some text </p>
<h1> test ... some text ... </h1>
Any ideas how to achieve this ?
By simple way you can create an html file for your template and use ng-include directive, so ng-include directive will the thing for you out of the box
my-template.html
<div>
<p> some text </p>
<h1> <included in here: data.template> </h1>
</div>
Or you can also create an ng-template on html page itself like shown below
<script type="text/ng-template" id="my-template.html">
<div>
<p> some text </p>
<h1> <included in here: data.template> </h1>
</div>
</script>
Usage:
Your consumer page
<ng-include
src="'my-template.html'">
</ng-include>
I understand by this solution you can end up creating multiple template html file or script templates. So other way around to solve this problem you can create your own directive and compile the content manually and render it inside a DOM manually.
Directive
.directive("dynamicContent", function($compile, $parse){
return{
link: function(scope, element, attrs) {
var linkFn = $parse(attrs.template);
var content = linkFn(scope)
// creating template wrapper around
var wrapper = `<div>${content}</div>`
var tempate = $compile(wrapper)(scope)
element.append(tempate);
}
}
});
Demo Plunker

How to add Spinner-Gif before ng-include is fully loaded

I have a div-layer which dynamically loads html-partials from the server. The template variable is changed when a link in the navigation is clicked.
<div id="ajaxwrapper" ng-include="template">
</div>
This works fine. But the templates need a short time to load and during that time the user doesn't get any kind of response. Thats why I want to display a spinner until the template is load. Sadly I don't know how.
My links look something like this:
<a ng-click="navi($event)" href="www.someurl.de">Text</a>
The navi-function looks like this:
$scope.navi = function (elem) {
elem.preventDefault();
var urlstring = "";
if (typeof elem.target.href !== 'undefined') {
urlstring = elem.target.href;
$location.path(elem.target.pathname).search({ knt: $scope.aktuellesVertragskonto.nr });;
} else {
urlstring = elem.target.baseURI
$location.path("/");
}
$scope.template = $location.absUrl();
};
I need some pointers on how to implement a spinner. Thank you :)
The spinner-template would look like this:
<script type="text/ng-template" id="loader">
<div class="text-center">
<img src="~/images/spinner/ajax-loader.gif" /><br />
Loading
</div>
The ng-include directive includes an onload expression (reference), so you can do something like this:
<div id="ajaxwrapper"
ng-show="loaded"
ng-include="template" onload="loaded = true">
</div>
<div class="text-center"
ng-hide="loaded">
<img src="~/images/spinner/ajax-loader.gif" /><br />
Loading
</div>
There is another way as well, as ng-include override inside div html so you can show loader till template loads.
You can put loader inside the div as below.
<div id="ajaxwrapper" ng-include="template">
// Show loader image or css
</div>

How to bind array with ng-bind-html directive in angularJS?

I want to show for every item different description.
This is the controller:
todoApp.controller('todos',function($scope,todoFactory){
todoFactory.getTodos().success(function (data) {
courses = x2js.xml_str2json(data);
$scope.todos = courses.rss.channel.item;
for(var i = 0 ; i < $scope.todos.length ; i++){
item = $scope.todos[i];
console.log(item.description);
$scope.message = item.description;
}
});
this is the html:
<div ng-controller="todos" class="list" style="padding-top: 8%">
<div class="list card" ng-repeat="todo in todos | filter:search" >
<div class="item item-avatar" ng-click="openLink(todo.link)" >
<img src="Bla-Bla-Logo-1.png">
<h2>{{todo.title}}</h2>
<p>{{todo.pubDate | limitTo:25 }}</p>
</div>
<div class="item item-body">
<p ng-bind-html="message"></p>
<p>
1 Like
5 Comments
</p>
</div>
</div>
<!--end list card-->
</div>
<!--end todos-->
Just to explain the code I get xml and convert into json so todos is array of objects.
Message is entering every object and get the description (but in the description has tags so i use ng-bind-html directive to show it properly).
I understand that $scope.message will hold just the last description. How to make it to belong in the ng-repeat so I can get different description for different item?
Thanks.
replace
<p ng-bind-html="message"></p>
with
<p ng-bind-html="todo.description"></p>
please provide the data which is you want to displayed repeatedly.
How data is represented.You are getting last one because it is overriding.
The "ngBind" attribute tells Angular to replace the text content of the specified HTML element with the value of a given expression, and to update the text content when the value of that expression changes.
Typically, you don't use "ngBind" directly, but instead you use the double curly markup like {{ expression }} which is similar but less verbose.

AngularJS Expression Not Working Correctly in ng-src with JSF

The angularjs module. the products array contains 2 product objects that will be added as a property of the controller.
(function () {
var app = angular.module('myApp', []);
var products = [
{
title: "Dummy Title 1",
description: "Dummy Description 1",
image: "dummy_image_1.jpg"
},
{
title: "Dummy Title 2",
description: "Dummy Description 2",
image: "dummy_image_2.jpg"
}
];
app.controller('myController', function () {
this.products = products;
});
})();
The JSF Page, if I remove images/{{product.image}} with the actual image file name such as images/dummy_image_1.jpg, the images are displayed, but if I use angularjs expression instead, then nothing is shown. Please note that other expressions in the loop work besides {{product.image}}. If I add {{product.image}} somewhere else, then it displays the filename correctly, but used in ng-srs, it prints nothing if I view the html. I don't know why it is.
<h:form>
<div class="container" ng-controller="myController as controller">
<div class="row">
<div class="col-sm-offset-10">
Hello <b><h:outputText value="#{user.userName}"/></b><br/>
<h:commandLink action="cart" value="Cart"/>
</div>
</div>
<hr/>
<div ng-repeat="product in controller.products">
<div class="row">
<div class="media">
<div class="media-left">
<img class="media-object" ng-src="images/{{product.image}}"/> <!--If I replace that expression with a the image file name, it shows the image -->
</div>
<div class="media-body">
<h4 class="media-heading">{{product.title}}</h4>
<span class="caption">{{product.description}}</span><br/>
<h:commandLink action="cart" value="Add to cart"/>
</div>
</div>
</div>
</div>
</div>
</h:form>
Sometimes using interpolation {{}} won't evaluate & update value of attribute (most often this happens in IE). The way to do this is using ng-src directive with interpolation {{}} this will add src to the img tag after evaluation interpolation directive.
Markup
<div class="media-left">
<img class="media-object" ng-src="{{'images/'+product.image}}"/>
<!--If I replace that expression with a the image file name, it shows the image -->
</div>
Alternative
The other way would be using ng-attr directive which add attribute with evaluated value. This will ensure you everytime that the interpolated value has been assigned to the attribute mentioned it in ng-attr (the part after ng-attr is considered as attribute to be added, suppose we have ng-attr-value="{{someVar}}" then angular will evaluate someVar and then assign that value to value attribute on that element.
Markup
<div class="media-left">
<img class="media-object" ng-attr-src="{{'images/'+product.image}}"/>
<!--If I replace that expression with a the image file name, it shows the image -->
</div>

AngularJS: Best practice displaying static text based on a state/variable

I have small text portions like
<div>
<h4>Why Register?</h4>
<p>As candidate...</p>
</div>
opposed to
<div>
<h4>Why Register?</h4>
<p>As company...</p>
</div>
Based on a variable in my controller I insert the correct partial with:
<div ng-switch on="role">
<div ng-switch-when="candidate">
<div ng-include="'candidate.html'"></div>
</div>
<div ng-switch-when="company">
<div ng-include="'company.html'"></div>
</div>
<div ng-switch-default>
<div ng-include="'candidate.html'"></div>
</div>
</div>
This does the job but it looks awful. Is there any way I could do it better?
You could always hold your string vars in javascript or external json file and use markup which is tied to a model like this:
<div ng-controller="something">
<h4>Why Register?</h4>
<p>{{who}}</p>
</div>
and then inside your "something" controller provide code:
if(role == "company")
$scope.who = "As company...";
else
$Scope.who = "As candidate...";
If you have many places in code that use such feature, you could consider holding variables in external json and then reading them in javascript/controller.
You can use:
<div ng-include="(role || 'candidate') + '.html'"></div>
If the parts are not that big you can put them all up there and use ng-show to filter which gets actually shown. This takes up the least markup.
<h4>Why register?</h4>
<p ng-show="isCompany">Company targeted content...</p>
<p ng-show="isCandidate">Candidate targeted content...</p>

Resources