AngularJs - html rendering - html

We use elastic search highlighter and get the below code from the highlighter.
<span style='font-weight:bold;color:red;'>Baskar</span> Test
We display the result in html as follows.
<tr
ng-repeat="result in searchModelResult">
<td><p ng-bind-html="result.name"></p></td>
</tr>
I have included sanitize.js and have ngSanitize in the angular module. Still i dont see the html effect like red color font and bold font.
Am i missing anything here?
Thanks,
Baskar.S

You need to do 2 things, first remove
{{result.name}}
as Daniel said... then you need to say to angular to trust in that html in your controller:
myApp.controller('MyCtrl', function ($scope, $sce) {
$scope.result.name = $sce.trustAsHtml('<span style="font-weight:bold; color:red;">Baskar</span> Test');
});
You can see the full documentation of $sce here
If you need to iterate inside a ng-repeat you can create a filter:
myApp.filter('unsafe', function($sce) { return $sce.trustAsHtml; });
And then use it in the view:
<tr ng-repeat="result in searchModelResult">
<td><p ng-bind-html="result.name | unsafe"></p></td>
</tr>

You need to remove the second binding expression:
{{result.name}}
It looks like that is overriding the binding from ng-bind-html, and the default binding will HTML escape the string.

Related

Manipulate Html table with Angular

very simple
what is the equivalent of this jQuery code
$('#message tr').eq(index).addClass('negative') in angular,
or how can i achieve the same result with angular
can't use [class.bind] the above job should be done in by clicking the button.
the button will pass some data to the function and based on some condition and checking the negative class will be added to the related row not to all of them.
You have not added any code, so I imagine you have something like:
<table>
<tr *ngFor="let data of arrayData;let i=index" [class.negative]="indexSelected==i">
<td>{{data?.prop1}}</td>
<td>{{data?.prop2}}</td>
<td><button
(click)="indexSelected=(indexSelected==i)?-1:i;
indexSelected!=-1 && diifer(data)">
select
</button>
</td>
</tr>
</table>
(or instead use a button add the "click" to the <tr>)
You can also pass the "index" to the function diifer like
(click)="diifer(data,i)"
And
diifer(data:any,index)
{
this.indexSelected=this.indexSelected==index?-1:index
if (this.indexSelected!=-1)
{
...do something..
}
}
NOTE: See that you check if indexSelected is the "row" you select. If true, you "unselect" making indexSelected=-1
NOTE2: remember that index goes from 0 to arrayData.length-1

ng-bind-html not working with my $scope.variable

I am trying to add something like dynamic HTML using ng-bind-html but its not working with $scope variable
Here is my Angular code
1)My controller
$scope.name = "Parshuram"
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml("<div>{{name}}</div>");
Also that my string is dynamic
"<div><table class=" + "\"table table - bordered table - responsive table - hover add - lineheight table_scroll\"" + "><thead><tr><td>Name</td><td>Age</td></tr></thead><tbody><tr ng-repeat=" + "\"tr in dyna\"" + "><td>{{tr.name}}</td><td>{{tr.age}}</td></tr></tbody></table></div>"
So i cant replace every variable with $scope
2)- My HTML
<div ng-app="mymodule" ng-controller="myModuleController">
<div ng-bind-html="thisCanBeusedInsideNgBindHtml"></div>
</div>
I got this output
{{name}}
My expected output is
Parshuram
Please can anyone help i am stuck at this point,does that $sce does not bind scope variable?? ..
I've created a working plnkr here: https://plnkr.co/edit/uOdbHjv1B7fr0Ra1kXI3?p=preview
the problem is that ng-bind-html is not bound to the scope.
you should manually compile the content.
a valid and reusable solution should be creating a directive, whitout using any external modules.
function compileTemplate($compile, $parse){
return {
link: function(scope, element, attr){
var parsed = $parse(attr.ngBindHtml);
function getStringValue() { return (parsed(scope) || '').toString(); }
scope.$watch(getStringValue, function() {
$compile(element, null, -9999)(scope);
});
}
}
}
<div ng-app="mymodule" ng-controller="myModuleController">
<div ng-bind-html="thisCanBeusedInsideNgBindHtml" compile-template></div>
</div>
ng-bind-html does what it says on the tin: it binds html. It doesn't bind angular template code into your dom.
You need to do this instead:
$scope.thisCanBeusedInsideNgBindHtml =
$sce.trustAsHtml("<div>"+$sanitize(name)+"</div>");
To do this you'll want to include the module ngSanitize from the javascript angular-sanitize.js. See https://docs.angularjs.org/api/ngSanitize
If you want to insert some html that includes angular directives then you should write your own custom directive to do it.
In your html just use
{{name}}
The {{var}} notation is to be used in the HTML code to evaluate that variable.
You can do :
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml('<div ng-bind="name"></div>');
Sorry I make another answer.
If you have
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml("<div>{{name}}</div>");
Then you can do
var str = "<div>{{name}}</div>";
var output = str.replace('{{name}}', $scope.name);
It seems to be the only option.

convert string to Number in angularjs

I am showing an array which contains JSON and am directly showing this with HTML, here you can find elem.fc + elem.cpc. It's giving NaN as an output.
Here is my HTML:
<tr ng-show="table.table1loaded" ng-repeat="elem in filteredcampaignslist" ng-init="initializepopover()">
<td ng-show="app.ostype=='iOS'"><div class="text-center">{{elem.fc+elem.cpc}}</div></td>
</tr>
Please check this: How to parseInt in Angular.js
According to the Angular docs within that post, you cannot, as of the moment, perform such operations within expressions.
The best way to go around this is to create a function that does so within a controller and then bind it to your HTML.
HTML:
<tr ng-show="table.table1loaded" ng-repeat="elem in filteredcampaignslist" ng-init="initializepopover()">
<td ng-show="app.ostype=='iOS'"><div class="text-center">{{ Total() }}</div></td>
</tr>
Inside AngularJS Controller:
$scope.Total = function() { return parseInt(elem.fc) + parseInt(elem.cpc); };
Change {{elem.fc+elem.cpc}} to {{+elem.fc + +elem.cpc}}
That should do the trick.
This is the answer for versions 2 and above of angular:
Number('1234') // 1234
Number('9BX9') // NaN

Angular.js Directive to display in bold a piece of the string

I have a table in angular that is displayed this way:
<table class="row">
<tr ng-repeat="x in myWelcome | filter :search">
<td>{{$index}}</td>
<td>{{x._id}}</td>
<td>{{x.email}}</td>
<td ng-bold-number>{{x.phone}}</td>
<td>{{x.latitude}}</td>
<td>{{x.longitude}}</td>
<td><input type="button" value="Remove" ng-click="removeRow(x._id)"/></td>
</tr>
</table>
The phone column is displayed like this : +1(210)22158765.
I want to create a directive "ng-bold-number" so that the number inside the parenthesis (that is 210 here) would be displayed in bold style like this +1(210)22158765
So I made this directive in Angular :
app.directive('ngBoldNumber', [function() {
return {
restrict: 'A',
link: function($scope, iElement, iAttrs) {
var x = $scope.x.phone.substring(0, $scope.x.phone.indexOf('(')+1)
var y = $scope.x.phone.substring($scope.x.phone.indexOf('(')+1, $scope.x.phone.indexOf(')')+1)
$scope.x.phone=x+y;
}
};
}])
which I am able to cut down the string but I didn't find a way to display it in bold. Can you help me please?
Suppose you would want to go with a directive, you can do it like this : check my plunker here
the directive function itself looks like this:
function boldNumber(){
return {
restrict:"A",
template:"{{pre}} <b>{{bold}}</b> {{post}} ",
replace:false,
scope:{
inBold:"#"
},
link: function(scope, element, attr){
console.log(scope.inBold);
scope.pre = scope.inBold.substring(0, scope.inBold.indexOf('(')+1);
scope.bold = scope.inBold.substring(scope.inBold.indexOf('(')+1, scope.inBold.indexOf(')')+1);
scope.post = scope.inBold.substring(scope.inBold.indexOf(')')+1);
}
};
Basically, what I have added is a template, showing the cuts you made. I had to make one more cut (the final part after the closing ')' ). You have to set replace: false, so your template is appended into the directive element.
Then i have an isolated scope, containing the text that needs to be cut, the phone number. I did simplify the example in my plunker a bit.
The html looks like this then:
<table class="row">
<tr>
<td bold-number in-bold="{{x.phone}}">tryout</td>
<td><input type="button" value="Remove" ng-click="removeRow(x._id)"/></td>
</tr>
</table>
as you can see, the attribute in-bold contains the value for the isolated scope in the directive function. if you need more information, or if something is not clear, please ask.
EDIT: the part about inBold:"#"
in your directive function, when u add the option 'scope', you create a scope that only counts for the directive. The directive itself can no longer reach the scope of the controller. That is why it is called an 'isolated scope'. It exists for your protection. In large single page apps, you might accidentally change scope variables from the controller which you did not want, if you don't have an isolated scope.
However, we do want to be able to pass variables from the controller to the directive, right? So there is the possibility to build in 'border control' for passing variables from controller to directive. In your html, you pass an extra attribute which is called: in-bold. it has a value. This is your 'border control'. The name 'in-bold' gets transformed to camel case (inBold) for use in javascript.
So what it basically means is that the isolated scope of the directive now has a variable called inBold. The value of this variable is passed to the directive from the controller by the attribute "in-bold". This is important that they have the "same" name. For us humans, in-bold is not the same as inBold, but for angular it is. Everything in angular-html connected with a dash (-) gets transformed in javascript to camel case. So for angular in-bold(html) = inBold(javascript). In the directive, you can now access that passed variable as scope.inBold or {{inBold}}.
Then what is the "#" about? well, the "#" tells the directive that we are dealing with a String value, which is only single-bound. That means that if we change the value of inBold in the directive, the changes will not be visible in the controller! This is important. If you would want two way binding, you would need to use the following:
scope:{
inBold:"="
}
I hope that was a bit clear to you...
This is part of working solution to demonstrate how you can make it bold style. Now you can format the rest part of number
angular.module("myApp", [])
.controller('myController', ['$scope', '$log',
function($scope, $log) {
$scope.phone = '+1(210)22158765';
$scope.isBold = false;
$scope.countryCode = null;
}
])
.directive('ngBoldNumber', [
function() {
return {
restrict: 'A',
template: '<span ng-class="{bold: isBold}">{{countryCode}}</span><span>{{phone}}</span>',
link: function($scope, iElement, iAttrs) {
//debugger;
var x = $scope.phone.substring(0, $scope.phone.indexOf('(') + 1);
var y = $scope.phone.substring($scope.phone.indexOf('(') + 1, $scope.phone.indexOf(')') + 1);
if (x && y) {
$scope.countryCode = x + y;
$scope.isBold = true;
}
}
};
}
]);
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.8/angular.js" data-semver="1.4.8"></script>
<script src="script.js"></script>
<style>
.bold {
font-weight: bold;
}
</style>
</head>
<body ng-app="myApp" ng-controller="myController">
<table class="row">
<tr>
<td ng-bold-number>{{phone}}</td>
</tr>
</table>
</body>
</html>

Accessing page or module level functions from a razor view

I'm currently using razor to render some views in DotNetNuke and everything is working fine except for one thing I'm missing. I'm trying to get access to some module level methods such as EditUrl etc. but can't seem to figure out how to go about it.
This is what I have for my view, although it errors on EditUrl. I'm using RazorEngine.Render to render the view. There are some helpers that are including for basic DNN info but I can't seem to find anything like NavigateUrl or EditUrl.
Any ideas?
#inherits DotNetNuke.Web.Razor.DotNetNukeWebPage<dynamic>
<div id="items-panel">
<table>
<thead>
<tr>
<th>Title</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Items)
{
<tr>
<td>
#item.Title
</td>
</tr>
}
</tbody>
</table>
</div>
I found a way that seems to work for EditUrl by creating a helper method in the razor view shown below. It's a shame I have to do this because the ModuleInstanceContext is actually passed into the constructor of the RazorEngine but not exposed to the view. If anyone else finds a way around this I'd appreciate a comment.
#helper EditUrl(string keyName, string keyValue, string controlKey)
{
#DotNetNuke.Common.Globals.NavigateURL(Dnn.Tab.TabID, controlKey, "mid="+Dnn.Module.ModuleID, keyName + "=" + keyValue)
}
Edit: The following method also worked well for me. I added a property to the model named ItemViewUrl with a placeholder token for the ItemId and then just did a replace in the view.
In the calling page:
dynamic model = new ExpandoObject();
model.Items = ItemRepository.List();
model.ViewItemUrl = EditUrl("ItemId", "[ITEMID]", "ViewItem");
and then in the Razor view:
<td>#item.Title</td>