Angular: Replacing text with Templates
want to replace certain letters (A,B,C,...) of a larger text with span tags which i css into nice symbols. Since I later reuse these tags I created an angular template directive
HTML
<div ng-app="foo">
<div ng-controller="bar">
<h1 ng-class="{A:'blue'}['A']">Text</h1><!-- Should be blue -->
<div bind-html-compile="text2"></div><!-- Removing this line lets the rest work -->
<h3>Legend</h3>
<symbol kind="kind" ng-repeat="kind in ['A', 'B', 'C', 'D']"></symbol>
</div>
</div>
CSS
span.symbol {
display: inline-block;
margin: 0;
height: 14px;
width: 14px;
border: 1px solid black;
line-height: 13px;
text-align: center;
}
.blue {
background: blue;
}
.red {
background: red;
}
.green {
background: green;
}
.yellow {
background: yellow;
}
JavaScript
angular.module('foo', [])
// the directive with template
.directive('symbol', function() {
return {
restrict: 'E',
replace: true,
template: '<span class="symbol" ng-class="{A:\'blue\',B:\'red\',C:\'green\',D:\'yellow\'}[kind]">{{{A:1,B:2,C:3,D:4}[kind]}}</span>',
scope: {
kind: '='
}
};
})
// the filter
.filter('symbolify', ['$sce', function($sce) {
return function(text) {
text = text.replace(/[ABCD]/g, '<symbol kind="\'$&\'"></symbol>');
return $sce.trustAsHtml(text);
}
}])
// provider of text with symbols A, B, C, D
.controller('bar', ['$scope', 'symbolifyFilter', function($scope, symbolifyFilter) {
$scope.text = "Lorem ipsum dolor sit amet, A consectetur adipiscing elit. Nullam pretium B tellus a nisl blandit tristique. Vestibulum laoreet D pulvinar ante ac finibus. Fusce nisi mauris, pharetra B imperdiet dui eget, C rutrum tincidunt libero. Quisque pharetra nisl dictum, egestas sem sed, malesuada ex. D Suspendisse placerat faucibus tempor. donec pulvinar risus nunc, id venenatis tortor A sodales ac."
$scope.text2 = symbolifyFilter($scope.text);
}])
// bind-html-compile from https://github.com/incuna/angular-bind-html-compile
.directive('bindHtmlCompile', ['$compile', function($compile) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.$watch(function() {
return scope.$eval(attrs.bindHtmlCompile);
}, function(value) {
// In case value is a TrustedValueHolderType, sometimes it
// needs to be explicitly called into a string in order to
// get the HTML string.
element.html(value && value.toString());
// If scope is provided use it, otherwise use parent scope
var compileScope = scope;
if (attrs.bindHtmlScope) {
compileScope = scope.$eval(attrs.bindHtmlScope);
}
...