0

I am having trouble putting a tag into my AngularJS web app. It loads data from a JSON file just fine. It also recognizes my HTML tags such as <em> and <br />. I achieved this through the $sce trustAsHtml. But it does not work for <input> tags. I have tried for two days but I could not find a solution that works. Help and explanations are appreciated!

index.html

<div ng-bind-html="myName.name"></div> <!-- The Test from the data.json file shows up in italic but the input does not show up in the DOM -->

app.js

var myApp = angular.module('myApp', [
    'ngRoute',
    'ngSanitize',
    'ngAnimate',
    'QuizController'
]);

myApp.filter('trustAsHtml', [
    '$sce',
    function($sce) {
        return function(value) {
            return $sce.trustAsHtml(value);
        }
    }
]);

data.json

"name" : "<em>Test</em> <input type='text' name='Hello'>"
7
  • Let me know if this duplicate doesn't answer your question. Commented Apr 6, 2018 at 19:21
  • An exact duplicate? Can you link to the question? Commented Apr 6, 2018 at 19:22
  • This one: stackoverflow.com/questions/24461603/…. You can just click on the text above. Commented Apr 6, 2018 at 19:23
  • No, I've gone through that solution and as I said in my question I call my data and strings and HTML fine, it's the input specifically that won't work. It's not a duplicate of that question. Commented Apr 6, 2018 at 19:26
  • 1
    Sorry mate. I have reopened the question. Good luck with answers. :) Commented Apr 6, 2018 at 19:34

2 Answers 2

2

You have defined a filter (trustAsHtml), which you don't apply to your value. Therefore the contents of ng-bind-html is not run through the filter and is not, actually, trusted.

As pointed out by georgeawg in the comments below, a number of safe tags are, in fact, allowed through ng-bind-html without the need to be run through $sce.trustAsHtml() and <em> is one of those tags.

But <input> is not.

Therefore, you need to apply your filter to allow unsafe tags through ng-bind-html, by changing the markup to:

<div class="txt" ng-bind-html="myName.name | trustAsHtml"></div>

It should work, though I haven't actually tested it in AngularJS environment. To do it, I'd first need to know what version you're using.

See it working here:

(function(){
  // Declare App
  var app = angular.module('testApp',[]);
  
  
  app.controller('testCtrl', ['$scope','$timeout', function($scope, $timeout){
    $scope.waiting = true;
    $timeout(() => {
      $scope.waiting = false;
      $scope.name = "<em>Test</em> <input type='text' name='Hello'>";
    }, 1000);
  }]).filter('trustAsHtml', [
    '$sce',
    function($sce) {
        return function(value) {
          return $sce.trustAsHtml(value);
        }
    }
  ]);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.7/angular.min.js"></script>

<div ng-app="testApp">
 <div ng-controller="testCtrl">
  <div ng-bind-html="name | trustAsHtml"></div>
  <div ng-show="waiting">let's wait a second...</div>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

11 Comments

The txt class is not adding the italic, it does indeed work as I am looking at the italic text and can change it to use <br> <b> and other tags. I did try the actual filter at one point but I got this error message in the console: Error "<div class="txt" ng-bind-html="myName.name | trustAsHtml">" angular.min.js:125
To answer your question I am using AngularJS v1.6.7
If the text is italic is not proof <em> passes ng-bind-html. The only proof it does is if you inspect the source and you see the <em> tag inside <div class="txt"></div> in the live page. Even so, I'm telling you, you're not running the contents of myName.name through the filter you defined. Ok, I'll try to recreate using 1.6.7. I haven't worked with 1.6 much.
I believe you, I am unsure why it works. I checked the DOM tree and I can confirm Test is wrapped in <em></em> tags
In that case ng-bind-html allows harmless tags in 1.6 (which is nice, but totally unexpected - therefore not used by many users coming from older versions). It didn't use to work this way up to 1.5 - any HTML had to be run through $sce). I'll fiddle your example and see if I run into any probs.
|
1

From you example it's unclear how do you use trustAsHtml filter.

Anyway, seems like $sce.trustAsHtml() is getting the job done:

(function(angular) {
  'use strict';
angular.module('bindHtmlExample', ['ngSanitize'])
  .controller('ExampleController', ['$scope', '$sce', function($scope, $sce) {
    $scope.myHTML = $sce.trustAsHtml(
       "<em>Test</em> <input type='text' name='Hello'>");
  }]);
})(window.angular);

/*
Copyright 2018 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example - example-ng-bind-html-production</title>

  <script src="//code.angularjs.org/snapshot/angular.min.js"></script>
  <script src="//code.angularjs.org/snapshot/angular-sanitize.js"></script>
  <script src="script.js"></script>
  
 
</head>
<body ng-app="bindHtmlExample">
  <div ng-controller="ExampleController">
    <p ng-bind-html="myHTML"></p>
  </div>
</body>
</html>

But keep in mind that you won't be able to use ng-model with an input rendered like that because you need to compile it first. You'll need a $compile service for that.

3 Comments

This doesn't work as I am calling the <input> tag from a JSON file and using a .filter to apply it. It is true, in my current HTML I am not calling it, for some odd reason I get a error message when I try using the filter. The error I get: Error "<div class="txt" ng-bind-html="myQuestion.question | trustAsHtml">" angular.min.js:125
@user5854648 okay, this might be because you didn't register trustAsHtml filter correctly.
This is the instance I use filter in the app: myApp.filter('trustAsHtml', [ '$sce', function($sce) { return function(value) { return $sce.trustAsHtml(value); } } ]);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.