MrProgram
MrProgram

Reputation: 5242

Add html element before content by in ng-bind

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

Answers (5)

Rorschach120
Rorschach120

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

dfsq
dfsq

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

MarkoCen
MarkoCen

Reputation: 2324

When binding html template, you should use $sce service with ngBindHtml directive

see:Updated Plunker

Upvotes: 0

user2033671
user2033671

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>

Plunker

Upvotes: 0

Kalhan.Toress
Kalhan.Toress

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

Related Questions