Reputation: 5242
I have a table that is rendered by an ng-repeat and bind to a model using ng-bind. I would like to add a html element on the first column depending on a condition. How can I do that?
<!doctype html>
<html ng-app="plunker">
<head>
<script data-require="angular.js@*" data-semver="1.2.0" src="http://code.angularjs.org/1.2.0/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng:controller="MainCtrl">
<table border="1">
<thead style="font-weight: bold;">
<tr>
<th class="text-right" ng-repeat="column in columnsTest" ng-if="column.checked" ng-bind="column.id"></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rows">
<td ng-repeat="column in columnsTest" ng-if="column.checked" ng-bind="formatValue(row[column.id], column.id == 'Value1')"></td>
</tr>
</tbody>
</table>
</div>
<script>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $filter) {
$scope.formatValue = function(value, addIcon) {
if (addIcon) {
var htmlElement = '<span>This is a SPAN</span>'
value = htmlElement + value;
}
return value;
}
$scope.columnsTest = [{
id: 'Value1',
checked: true
}, {
id: 'Value2',
checked: true
}, {
id: 'Value3',
checked: true
}];
$scope.rows = [{
id: 1,
"Value1": 911,
"Value2": 20,
"Value3": 20
}, {
id: 2,
"Value1": 200,
"Value2": 20,
"Value3": 20
}];
});
I would like my html element to be rendered before the value. I've tried using $scope but that didn't work. The span still comes out as a text.
Here is a Plunker
Upvotes: 1
Views: 1516
Reputation: 1210
You can use ng-if to show the span depending on the '$first' boolean provided by ng-repeat.
<tr ng-repeat="row in rows">
<td ng-repeat="column in columnsTest" ng-if="column.checked">
<span ng-if="$first">This is a SPAN</span>
{{row[column.id]}}
</td>
</tr>
http://plnkr.co/edit/Dy2nA7m53GUdnlQG1JAW?p=preview
edit: Use ng-if for better rendering performance with long lists
Upvotes: 0
Reputation: 193261
You don't want controller to know anything about HTML. So don't do that. Instead, use ngIf directive to conditionally add span:
<tr ng-repeat="row in rows">
<td ng-repeat="column in columnsTest" ng-if="column.checked">
<span ng-if="column.id == 'Value1'">ICON</span>
{{ row[column.id] }}
</td>
</tr>
Demo: http://plnkr.co/edit/oUtzD2lQoF29PyOgs2k4?p=info
Upvotes: 1
Reputation: 2324
When binding html template, you should use $sce
service with ngBindHtml
directive
see:Updated Plunker
Upvotes: 0
Reputation:
Include ngSanitize and use ngBindHTML
<script data-require="angular.js@*" data-semver="1.2.0" src="https://code.angularjs.org/1.2.0/angular-sanitize.js"></script>
...
var app = angular.module('plunker', ['ngSanitize']);
...
<td ng-repeat="column in columnsTest" ng-if="column.checked" ng-bind-html="formatValue(row[column.id], column.id == 'Value1')"></td>
Upvotes: 0
Reputation: 21901
you need to use ng-sanitize
, with ng-bind-html
ng-bind-html
will
.. inserts the resulting HTML into the element in a secure way. By default, the resulting HTML content will be sanitized using the $sanitize service..
var app = angular.module('plunker', ['ngSanitize']);
$scope.formatValue = function(value, addIcon) {
if (addIcon) {
var htmlElement = '<span>This is a SPAN</span>'
value = htmlElement + value;
}
//note that value is wrapped by a span because `ng-bind-html` needs the html with root html.
return "<span>"+value+"</span>";
}
here is the updated PLUNKER
Upvotes: 0