Reputation: 28496
Currently I'm reading data from an input field that gets pushed into an object in the controller, the data is then displayed in the view as following:
<ul class="status_list">
<li data-ng-repeat="comment in comments" class="status">
{{ comment.data }}
</li>
</ul
I want to make it so if comment.data
contains #word
, it's replaced with <span class='x'>#word</span>
. But I'm not quite sure how to:
1) search through the data in the view
2) append html to it
Upvotes: 2
Views: 3319
Reputation: 19098
For anyone stumbling upon this question more recently, here is an updated version of @mikel's answer (ng-bind-html-unsafe
has been deprecated since angular v 1.2.0). Instead, you have to mark the html as trusted and use ng-bind-html
.
The following custom filter will add a span to all hashtags (coffeescript):
angular.module('myApp', ['ngSanitize'])
.filter('pxnHashtagHighlight', ($sce)->
(value)->
hashtags = /(?:^|\s)(#(\w+))/gm
$sce.trustAsHtml(value.replace(hashtags, ' <span class="tag">$1</span>'))
)
Which can be used with the following markup (jade):
div.example(ng-bind-html="comment.data | pxnHashtagHighlight")
Notes
ng-bind
or the {{ }}
shorthand.$sce
to mark the html as trusted. In newer android versions this has been removed from core into the ngSanitise
module, so you'll have to download that and add it as a dependency for your app.Upvotes: 0
Reputation: 3538
I'd use a filter. {{ comment.data | mkSpan }}
angular.module('myapp.filters', [])
.filter('mkSpan', function () {
return function (input,klass) {
if(angular.isDefined(input)){
return (angular.isDefined(klass)) ? '<span class="' + klass + '">' + input + '</span>' : '<span>' + input + '</span>';
}
return input;
}
}); // end mkSpan / myapp.filters
angular.module('myapp',['myapp.filters']);
{{ comment.data | mkSpan:myCssClass }}
Upvotes: 0
Reputation: 24506
You can do this using a custom filter.
app.filter("AddSpan", function() {
return function(item) {
if (item.indexOf("#word") > -1) {
return "<span class='x'>" + item + "</span>";
} else {
return item;
}
}
});
Because you're adding HTML dynamically you also need to tell Angular to bind it 'unsafely' rather than escaping the HTML as it will do by default.
<li data-ng-repeat="comment in comments" class="status" ng-bind-html-unsafe="comment.data | AddSpan"></li>
IMO this is a cleaner solution than adding a method to $scope - I don't think HTML belongs in the controller, and filters are designed for cases just like this when you just want to modify the appearance of the data.
Upvotes: 2
Reputation: 21244
Consider dynamically adding the spans via Javascript, then using ng-bind-html-unsafe
to bind that value to your view.
1) Create a method on $scope to do the text replacement.
$scope.GetDataWithHtml = function() {
return $scope.comment.data.replace(/\#word/gi, '<span>$1</span>');
};
2) In your <ul>
, bind as follows:
<dul class="status_list">
<li data-ng-repeat="comment in comments" class="status" ng-bind-html-unsafe="GetDataWithHtml()"></li>
</ul>
Upvotes: 0