How to bind html to an external component? (Angular) - javascript

We have consumed an external library with components we would like to use, one of the components is an alert modal, that is represented as so:
<alert dismissible="false">Enter your text here</alert>
It renders out:
<alert dismissible="false" initialized="true">
<div class="alert-inside alert-type-info" aria-hidden="false" role="alert">
<div region-container="content">
<span>
<span class="ng-binding ng-scope">Enter your text here</span>
</span>
</div>
</div>
</alert>
The way we have built our angular app we are using config variables to hold our content
AppConfig.EnterText= "Enter your text here";
In which case we would call alert as so
<alert dismissible="false">{{AppConfig.EnterText}}</alert>
The problem is we actually want to use some html markup to be put into the alert...
AppConfig.EnterText= "<strong>Notice:</strong> Enter your text here";
In which case, if we include the content between the tags, it will render the tags instead of processing them. I have tried
<alert dismissible="false" ng-bind-html="AppConfig.EnterText"></alert>
This results in the inner tags being replaced with the content...
<alert dismissible="false" initialized="true">
<strong>Notice:</strong> Enter your text here
</alert>
Anyone have suggestions?

To solve this problem, I believe you need to use ng-bind-html directive in conjunction with the $sce service. Have you tried injecting the $sce service into your controller? Once you do that, you can set your variable like this:
AppConfig.EnterText= $sce.trustAsHtml("<strong>Notice:</strong> Enter your text here");

I was able to resolve the issue with the following:
<alert dismissible="false">
<span ng-bind-html="AppConfig.EnterText"></span>
</alert>

Related

Format <p> tags in Angular in desired way

I was working on a personal project where, I came across a situation where I have to take a large text input from user [Kind of like a reddit post or stackoverflow post].
I found out that by default tags do not preserve line breaks.
I solved this issue by using css [white-space: pre;]
Thanks to this post :
But what i need is to format the user entered text in a certain way , such that it would fit into a mat-card and also will be able to format code like ``` tags in stackOverflow.
<div class="zorroWrap">
<nz-card style="width:410px;" nzTitle="{{ article.title }}" [nzExtra]="extraTemplate" [nzActions]="[actionEllipsis , voteDisplay]">
<div class="angular-with-newlines">
<p align="justify">{{ article.desc }}</p>
</div>
</nz-card>
<ng-template #extraTemplate>
More
</ng-template>
<ng-template #actionEllipsis>
<i nz-icon nzType="ellipsis"></i>
</ng-template>
<ng-template #voteDisplay>
<i nz-icon [nzType]="'heart'" (click)="upVoteArticle()" [nzTheme]="'twotone'" [nzTwotoneColor]="'#eb2f96'"></i>
<i nz-icon nzType="ellipsis"> {{ article.votes }}</i>
</ng-template>
<div>
I am using ng-zorro.
I need the <p> tag's text formatted with preserved new lines [also an option to format code maybe like ``` or something] and the entire text should stay inside the card [should not overflow (I know i can do this using css, but would love to know if there is any better way)]
Thank You!
Edit:
Using css preserve's the new lines, as below:
I also found this post , which had sources of external libraries to pre format.
Any other Angular way? (which is maybe better)

filter user input in angularjs

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.

How to use if construction for controller vars in angularjs

Prompt, as if working in angularjs. I try to do so:
var goods = angular.module ('goods', []);
goods.controller('Cart', function ($scope) {
$scope.goodsCount = 1,
});
In html I have tried many things:
<div ng-app="goods" ng-controller="Cart">
<span ng-if="goodsCount> 1"> 1 </span>
<div>
And it did not work
<div ng-app="goods" ng-controller="Cart">
<span> {{goodsCount > 1 ? goodsCount: 'null'}} </ span>
<div>
And it is also
So how does it work?
So there's a few issues that were corrected by other comments. Once those are actually fixed in your code it will work. Double check your working code for typos as well. Here is an example of this working with your code that you have supplied without typos.
plunker
http://plnkr.co/edit/t4yAKgTdYzt18YUZmX5M?p=preview
In the script file you can change the value to see the different things appear or change.
Oh and yes forgot to mention, the comma after your $scope.goodsCount was breaking it. That is also fixed in the plunker
Your controller is called Cart and you're putting ng-controller="Basket" on the scope. Also, you are probably wanting to use ng-show.
Try:
<div ng-app="goods" ng-controller="Cart">
<span ng-show="goodsCount > 1"> {{ goodsCount }} </ span>
<div>

Load angular template on some event

I'm quite new to angular and frontend in general, but what i'd like to see is something similar to what routing with ngView gives, but without routing, i.e just load a template on some event. To be more specific, let's say i have an input field somewhere in the header and when i click/focus on this field a special panel with different input options shows up. The trick is that this input field and other elements are already a part of a template which is loaded into ngView, so as i understand i can't use another ngView for options pane.
use ngIf, ngShow, ngHide, ngSwitch for stuff like that
<button ng-click="showStuff = true">Show Stuff</button>
<button ng-click="showStuff = false">Hide Stuff</button>
<div ng-show="showStuff">Showing Stuff</div>
<div ng-hide="showStuff">Hiding Stuff</div>
Have a look at this plunker for a quick and dirty, working example.
Note that the showStuff variable is just magically created by angular on the root scope, since I'm not using a controller.
You can load templates with ng-if and ng-include like this example:
<body ng-app="app">
<div class='container'>
<button ng-click='tmpl = true' class='btn btn-info'>Load template!</button>
<div ng-if='tmpl'>
<div ng-include="'template.html'"></div>
</div>
</div>
</body>
The ngIf directive will add element to the DOM when the argument expression is true. Then, the angular will compile the inner directive ngInclude, loading the template.

scope issue caused ng-click don't trigger

I uses angular ui tab (http://angular-ui.github.io/bootstrap/) and I added a delete btn inside the the js file. I can't do it with my markup because the js generate the template on the js side.
my ng-click doesn't work when I put this
<span ng-click="deleteTab()" >dlt</span>
js
$scope.deleteTab = function(){
//$scope.tabs.splice(this, 1);
alert('d');
}
within my controller. I tried to include the js on the topest and before the , nothing work. Until I try onClick. I wonder why I can't use ng-click in my situation?
If you add new HTML to the DOM without using angular, you need to $compile the HTML to let angular to bind the content and $watch changes. See the docs
$compile(element.contents())(scope);
Edit:-
Ah you can give the title as a HTML template as well,see the tabs definition
<tab ng-repeat="workspace in workspaces"
active=workspace.active>
<tab-heading>{{workspace.name}}<span ng-click="deleteTab()" >dlt</span></tab-heading>
<div ng-controller="TabsChildController" >
<div>
{{workspace.id}} : {{ workspace.name}}
</div>
<input type="text" ng-model="workspace.name"/>
</div>
</tab>
and here is the solution
that's a plunker that could solve your problem.plunker the only doubt is what workspace would you want to close, i imagine it is the last, otherwise you only need to modify the delete method.
EDIT
in this version you can delete the selected workspace, you have to controll the css, but i thin it could be a good solution
new plunker

Categories