Search code examples
angularjsangularjs-bindings

How to make HTML markup show correctly in AngularJS binding using a function?


I have following code, to illustrate an issue I have:

<p>{{'This&nbsp;&nbsp;&nbsp;&nbsp;is&nbsp;&nbsp;spaced'}}</p>
<p>This&nbsp;&nbsp;&nbsp;&nbsp;is&nbsp;&nbsp;spaced</p>
<p>{{leerlingController.myReplace('This    is  spaced')}}</p>

The first and second line appear as intended, showing spaces instead of codes. The third line however shows the & nbsp; codes instead of the spaces.

the function is in a controller, simply:

vm.myReplace = function(item) {
    return item.replace(/ /g, '&nbsp;');
}

How to make this function work as intended? (I need it to modify text in select-options attached to a ngRepeater.)


Solution

  • This is a security restriction from Angular, see docs here.

    You could use ng-bind-html and load ngSanitize module. Or use $sce.trustAsHtml(value) in your method if you don't want to load ngSanitize.

    Then it would look like this ($sce is dep. injected into controller):

    vm.myReplace = function(item) {
        return $sce.trustAsHtml(item.replace(/ /g, '&nbsp;'));
    };
    

    Please have a look at the demo below or this fiddle.

    Update 12.06.2016:

    I'm not sure if there is an easier way of doing this. But you could check each column and calculate the required padding. For adding the padding I've used underscore.string.

    Also use ng-repeat so you can use ng-bind-html and to have the correct spacing you should use a monospaced font e.g. Lucida Console or Courier (see css style in the fiddle).

    Here you can find a fiddle for this.

    Another way of doing this would be to create a directive that is styled like a select-tag then you could use a table inside of the dropdown to have the correct spacing.

    Update 12.06.2016 - 21:25 (UTC):

    Please have a look at this fiddle. It's using the directive approach and I think that's the best solution to the problem.

    angular.module('demoApp', ['ngSanitize'])
    	.controller('mainCtrl', MainCtrl);
        
    function MainCtrl() {
    	var vm = this;
        
        vm.myReplace = function(item) {
        	return item.replace(/ /g, '&nbsp;');
    	};
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-sanitize/1.5.6/angular-sanitize.js"></script>
    <div ng-app="demoApp" ng-controller="mainCtrl as ctrl">
        <span ng-bind-html="ctrl.myReplace('This    is  spaced')"></span>
    </div>