0

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.)

2
  • 2
    Don't understand what exactly you're asking - Can't you just add white-space:pre; ? Commented Jun 11, 2016 at 21:45
  • This is something that can be corrected by using the sce (strict contextual escaping) library (docs.angularjs.org/api/ng/service/$sce#!), but the more pressing question is why you are storing HTML inside angular variables in the first place. Commented Jun 11, 2016 at 21:54

2 Answers 2

1

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>

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

4 Comments

I think Alon Eitan's advice from the comments should work as expected. I've added it to the fiddle and I would use this.
@Alon Eitan You're right, however this doesn't work inside an option element inside select and that's where I need it.
Thanks. I had the $sce part worked out but without using ng-bind-html and apparently that's crucial. Now I want to apply that in ng bound select-options. I had figured out <select ng-model="leerlingController.currentLeerling" ng-options="leerlingOption.$id as leerlingController.myReplace(leerlingOption.leerlingdropdown) for leerlingOption in leerlingController.leerlingen> </select> but how to use a ng-bind-html directive in that construction?
@Claies I need to get a ng-bound select-option list with each option consisting of three element that vary in length. That shouldn't look messy but with each element in its own 'column'. Any ideas to achieve that are welcome.
0

Found a way to get the job done:

<select name='Leerling' id='Leerling' size='1'>
    <option value='Maak een keuze...' selected disabled>Maak een keuze...</option>
    <option ng-repeat="leerlingOption in leerlingController.leerlingen"
            ng-bind-html="leerlingController.myReplace(leerlingOption.leerlingdropdown)"
            value={{leerlingOption.leerlingdropdown}}></option>
</select>

with myReplace being (as answered by AWolf):

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

Comments

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.