I had this project where search results coming from a API service needed to be highlighted.
This was my template, containing a long string (a search snippet):
<div [innerHTML]="child.contents"></div>
I figured out the best way to do this was to use a Pipe. This is good practice to transform output in your Angular template.
In my app/pipes/ folder I created highlight.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
import {DomSanitizer, SafeHtml} from '@angular/platform-browser';
@Pipe({
name: 'highlight'
})
export class HighlightPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {}
transform = (text: string, search: string): SafeHtml => {
if (search && text) {
let pattern = search.replace(
/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
'\\$&'
);
pattern = pattern
.split(' ')
.filter((t: string) => t)
.join('|');
const regex = new RegExp(pattern, 'gi');
return this.sanitizer.bypassSecurityTrustHtml(
text.replace(
regex,
match => `<span style="background:yellow;">${match}</span>`
)
);
} else {
return text;
}
}
}
Make sure you declare or import the pipe in your module:
declarations: [
HighlightPipe
],
exports: [
HighlightPipe
],
providers: [
HighlightPipe
],
Now in your mypage.page.ts:
<div [innerHTML]="child.contents | highlight:search.value"></div>
Done!
This code was based on an example on this example, which I updated it to work properly with Strict TypeScript and Angular 13.