The IgxTextHighlightDirective and IgxTextHighlightService in Ignite UI for Angular are used to highlight parts of a text, providing options for case sensitive searches and to highlight only exact matches. They allow the developer to keep an active highlight, which can be any of the already highlighted parts.
Angular Text Highlight Directive Example
EXAMPLE
TS
HTML
SCSS
/* eslint-disable max-len */import { Component, OnDestroy, ViewChild } from'@angular/core';
import { IgxTextHighlightDirective, IgxTextHighlightService, IgxInputGroupComponent, IgxPrefixDirective, IgxIconComponent, IgxInputDirective, IgxSuffixDirective, IgxIconButtonDirective, IgxRippleDirective } from'igniteui-angular';
import { FormsModule } from'@angular/forms';
@Component({
selector: 'app-text-highlight-1',
styleUrls: ['./text-highlight-sample-1.component.scss'],
templateUrl: './text-highlight-sample-1.component.html',
imports: [IgxInputGroupComponent, IgxPrefixDirective, IgxIconComponent, FormsModule, IgxInputDirective, IgxSuffixDirective, IgxIconButtonDirective, IgxRippleDirective, IgxTextHighlightDirective]
})
exportclassTextHighlightSample1ComponentimplementsOnDestroy{
@ViewChild(IgxTextHighlightDirective, { read: IgxTextHighlightDirective, static: true })
public highlight: IgxTextHighlightDirective;
// tslint:disable max-line-lengthpublic html = `
Use the search box to search for a certain string in this text.
All the results will be highlighted in the same color with the exception of the
the first occurrence of the string, which will have a different color in order to tell it apart.
You can use the button in the searchbox to specify if the search will be case sensitive.
You can move the active highlight by either pressing the buttons on the searchbox or by using the Enter or the arrow keys on your keyboard.
`;
// tslint:enable max-line-lengthpublic searchText = '';
public matchCount = 0;
public caseSensitive = false;
public index = 0;
constructor(private highlightService: IgxTextHighlightService) { }
publicngOnDestroy() {
this.highlightService.destroyGroup('group1');
}
publicsearchKeyDown(ev) {
if (this.searchText) {
if (ev.key === 'Enter' || ev.key === 'ArrowDown' || ev.key === 'ArrowRight') {
ev.preventDefault();
this.findNext();
} elseif (ev.key === 'ArrowUp' || ev.key === 'ArrowLeft') {
ev.preventDefault();
this.findPrev();
}
}
}
publiconTextboxChange() {
this.index = 0;
this.find(0);
}
publicupdateSearch() {
this.caseSensitive = !this.caseSensitive;
this.find(0);
}
publicclearSearch() {
this.searchText = '';
this.find(0);
}
publicgetcanMoveHighlight() {
returnthis.matchCount > 1;
}
publicfindNext() {
this.find(1);
}
publicfindPrev() {
this.find(-1);
}
privatefind(increment: number) {
if (this.searchText) {
this.matchCount = this.highlight.highlight(this.searchText, this.caseSensitive);
this.index += increment;
this.index = this.index < 0 ? this.matchCount - 1 : this.index;
this.index = this.index > this.matchCount - 1 ? 0 : this.index;
if (this.matchCount) {
this.highlightService.setActiveHighlight('group1', {
index: this.index
});
}
} else {
this.highlight.clearHighlight();
}
}
}
ts
Like this sample? Get access to our complete Ignite UI for Angular toolkit and start building your own apps in minutes. Download it for free.
60+ components, flexible API, powerful theming and branding capabilities, and a rich feature set for building Angular apps with the speed and functionalities you require.
Getting Started with Ignite UI for Angular Text Highlight Directive
To get started with the Ignite UI for Angular Text Highlight directive, first you need to install Ignite UI for Angular. In an existing Angular application, type the following command:
ng add igniteui-angular
cmd
For a complete introduction to the Ignite UI for Angular, read the getting started topic.
The next step is to import the IgxTextHighlightModule in your app.module.ts file.
Now that you have the Ignite UI for Angular Text Highlight module or directive imported, you can start using the igxTextHighlight.
Using the Angular Text Highlight Directive
Let's create a search box that we can use to highlight different parts of the text. We will use Ignite UI for Angular's InputGroup component in which we will add a text input with buttons for clear matches, find next, find previous, and a button for specifying whether the search will be case-sensitive or not. Also it has a label for how many matches we have found.
Then, we will add a div with text and the IgxTextHighlight directive. Note that, since we need to bind the value input to the text in the div, we will also use interpolation for the div's text.
In the .ts file of our component first we need to add the following fields, that are used for bindings in our component's template:
@Component({
...
})
exportclassHomeComponent{
public html = '...';
@ViewChild(IgxTextHighlightDirective, {read: IgxTextHighlightDirective})
public highlight: IgxTextHighlightDirective;
public searchText: string = '';
public matchCount: number = 0;
public caseSensitive: boolean = false;
public index: number = 0;
publicgetcanMoveHighlight() {
returnthis.matchCount > 1;
}
}
typescript
Then we need to add the following methods which will allow the user to apply the highlights for the text they have typed in the search box and to move the active highlight around.
If the sample is configured properly, the final result should look like that:
EXAMPLE
TS
HTML
SCSS
/* eslint-disable max-len */import { Component, OnDestroy, ViewChild } from'@angular/core';
import { IgxTextHighlightDirective, IgxTextHighlightService, IgxInputGroupComponent, IgxPrefixDirective, IgxIconComponent, IgxInputDirective, IgxSuffixDirective, IgxIconButtonDirective, IgxRippleDirective } from'igniteui-angular';
import { FormsModule } from'@angular/forms';
@Component({
selector: 'app-text-highlight-1',
styleUrls: ['./text-highlight-sample-1.component.scss'],
templateUrl: './text-highlight-sample-1.component.html',
imports: [IgxInputGroupComponent, IgxPrefixDirective, IgxIconComponent, FormsModule, IgxInputDirective, IgxSuffixDirective, IgxIconButtonDirective, IgxRippleDirective, IgxTextHighlightDirective]
})
exportclassTextHighlightSample1ComponentimplementsOnDestroy{
@ViewChild(IgxTextHighlightDirective, { read: IgxTextHighlightDirective, static: true })
public highlight: IgxTextHighlightDirective;
// tslint:disable max-line-lengthpublic html = `
Use the search box to search for a certain string in this text.
All the results will be highlighted in the same color with the exception of the
the first occurrence of the string, which will have a different color in order to tell it apart.
You can use the button in the searchbox to specify if the search will be case sensitive.
You can move the active highlight by either pressing the buttons on the searchbox or by using the Enter or the arrow keys on your keyboard.
`;
// tslint:enable max-line-lengthpublic searchText = '';
public matchCount = 0;
public caseSensitive = false;
public index = 0;
constructor(private highlightService: IgxTextHighlightService) { }
publicngOnDestroy() {
this.highlightService.destroyGroup('group1');
}
publicsearchKeyDown(ev) {
if (this.searchText) {
if (ev.key === 'Enter' || ev.key === 'ArrowDown' || ev.key === 'ArrowRight') {
ev.preventDefault();
this.findNext();
} elseif (ev.key === 'ArrowUp' || ev.key === 'ArrowLeft') {
ev.preventDefault();
this.findPrev();
}
}
}
publiconTextboxChange() {
this.index = 0;
this.find(0);
}
publicupdateSearch() {
this.caseSensitive = !this.caseSensitive;
this.find(0);
}
publicclearSearch() {
this.searchText = '';
this.find(0);
}
publicgetcanMoveHighlight() {
returnthis.matchCount > 1;
}
publicfindNext() {
this.find(1);
}
publicfindPrev() {
this.find(-1);
}
privatefind(increment: number) {
if (this.searchText) {
this.matchCount = this.highlight.highlight(this.searchText, this.caseSensitive);
this.index += increment;
this.index = this.index < 0 ? this.matchCount - 1 : this.index;
this.index = this.index > this.matchCount - 1 ? 0 : this.index;
if (this.matchCount) {
this.highlightService.setActiveHighlight('group1', {
index: this.index
});
}
} else {
this.highlight.clearHighlight();
}
}
}
ts
The igxTextHighlight allows you to search across multiple elements which all share one active highlight. This is done by having the same groupName value across multiple TextHighlight directives. In order to setup the sample we will reuse the search box from the previous sample, but this time we will add two div elements. The column and row inputs are useful when you have multiple elements and in our case the second div has a different row value.
In the .ts file we have the firstParagraph and secondParagraph fields, which are bound to the respective value inputs of the text highlight directives. Also, we will now use ViewChildren instead of ViewChild to get all the highlights in our template.
public firstParagraph = "...";
public secondParagraph = "...";
@ViewChildren(IgxTextHighlightDirective)
public highlights;
typescript
All the rest of the code in the .ts file is identical to the single element example with the exception of the find method. Changes to this method are necessary since we now have multiple elements, but the code there can be used regardless of the number of TextHighlight directives you have on your page.
/* eslint-disable max-len */import { Component, OnDestroy, ViewChildren } from'@angular/core';
import { IgxTextHighlightDirective, IgxTextHighlightService, IgxInputGroupComponent, IgxPrefixDirective, IgxIconComponent, IgxInputDirective, IgxSuffixDirective, IgxIconButtonDirective, IgxRippleDirective } from'igniteui-angular';
import { FormsModule } from'@angular/forms';
@Component({
selector: 'app-text-highlight-2',
styleUrls: ['./text-highlight-sample-2.component.scss'],
templateUrl: './text-highlight-sample-2.component.html',
imports: [IgxInputGroupComponent, IgxPrefixDirective, IgxIconComponent, FormsModule, IgxInputDirective, IgxSuffixDirective, IgxIconButtonDirective, IgxRippleDirective, IgxTextHighlightDirective]
})
exportclassTextHighlightSample2ComponentimplementsOnDestroy{
@ViewChildren(IgxTextHighlightDirective)
public highlights;
// tslint:disable max-line-lengthpublic firstParagraph = `
Use the search box to search for a certain string in this text.
All the results will be highlighted in the same color with the exception of the
the first occurrence of the string, which will have a different color in order to tell it apart.
You can use the button in the searchbox to specify if the search will be case sensitive.
You can move the active highlight by either pressing the buttons on the searchbox or by using the Enter or the arrow keys on your keyboard.
`;
public secondParagraph = `
On top of the functionality from the previous sample, this sample demonstrates how to implement the text highlight directive
with several different elements. In this case, we have two div elements, each containing some text. You can see that
they share the same active highlight and the returned match count includes both elements. The find method in this
sample can be reused regardless of the number of elements you have in your application.
`;
public searchText = '';
public matchCount = 0;
public caseSensitive = false;
public index = 0;
constructor(private highlightService: IgxTextHighlightService) { }
publicngOnDestroy() {
this.highlightService.destroyGroup('group1');
}
publicsearchKeyDown(ev) {
if (this.searchText) {
if (ev.key === 'Enter' || ev.key === 'ArrowDown' || ev.key === 'ArrowRight') {
ev.preventDefault();
this.findNext();
} elseif (ev.key === 'ArrowUp' || ev.key === 'ArrowLeft') {
ev.preventDefault();
this.findPrev();
}
}
}
publiconTextboxChange() {
this.index = 0;
this.find(0);
}
publicupdateSearch() {
this.caseSensitive = !this.caseSensitive;
this.find(0);
}
publicclearSearch() {
this.searchText = '';
this.find(0);
}
publicgetcanMoveHighlight() {
returnthis.matchCount > 1;
}
publicfindNext() {
this.find(1);
}
publicfindPrev() {
this.find(-1);
}
privatefind(increment: number) {
if (this.searchText) {
let count = 0;
const matchesArray = [];
this.highlights.forEach((h) => {
count += h.highlight(this.searchText, this.caseSensitive);
matchesArray.push(count);
});
this.matchCount = count;
this.index += increment;
this.index = this.index < 0 ? this.matchCount - 1 : this.index;
this.index = this.index > this.matchCount - 1 ? 0 : this.index;
if (this.matchCount) {
let row;
for (let i = 0; i < matchesArray.length; i++) {
if (this.index < matchesArray[i]) {
row = i;
break;
}
}
const actualIndex = row === 0 ? this.index : this.index - matchesArray[row - 1];
this.highlightService.setActiveHighlight('group1', { index: actualIndex, row });
}
} else {
this.highlights.forEach((h) => {
h.clearHighlight();
});
this.matchCount = 0;
}
}
}
ts
The IgxTextHighlight directive can be styled in terms of changing the color and the background of all occurrences of the given string. To get started, we need to import the index file, where all the theme functions and component mixins live:
@use"igniteui-angular/theming" as *;
// IMPORTANT: Prior to Ignite UI for Angular version 13 use:// @import '~igniteui-angular/lib/core/styles/themes/index';scss
Following the simplest approach, we create a new theme that extends the highlight-theme and accepts the $resting-background, $resting-color, $active-background and the $active-color parameters.
The $resting-background and the $resting-color parameters will be applied to all highlighted occurrences, except for the active highlighted string, which will be styled based on the $active-background and the $active-color parameters.
The last step is to include the newly created theme.
If the component is using an Emulated ViewEncapsulation, it is necessary to penetrate this encapsulation using ::ng-deep to apply the styles.
Custom styles
Let's say we want to provide an even richer styling to our highlighted text parts. In order to do this, we can take advantage of the cssClass and the activeCssClass inputs of the IgxTextHighlight directive. We can combine these classes with the styles from the highlight-theme and provide an awesome experience to our users!
All we have to do is create a couple of css classes with some properties and attach them by using the inputs from above:
/* eslint-disable max-len */import { Component, OnDestroy, ViewChild } from'@angular/core';
import { IgxTextHighlightDirective, IgxTextHighlightService, IgxInputGroupComponent, IgxPrefixDirective, IgxIconComponent, IgxInputDirective, IgxSuffixDirective, IgxIconButtonDirective, IgxRippleDirective } from'igniteui-angular';
import { FormsModule } from'@angular/forms';
@Component({
selector: 'app-text-highlight-style',
styleUrls: ['./text-highlight-style.component.scss'],
templateUrl: './text-highlight-style.component.html',
imports: [IgxInputGroupComponent, IgxPrefixDirective, IgxIconComponent, FormsModule, IgxInputDirective, IgxSuffixDirective, IgxIconButtonDirective, IgxRippleDirective, IgxTextHighlightDirective]
})
exportclassTextHighlightStyleComponentimplementsOnDestroy{
@ViewChild(IgxTextHighlightDirective, { read: IgxTextHighlightDirective, static: true })
public highlight: IgxTextHighlightDirective;
public html = `
Use the search box to search for a certain string in this text.
All the results will be highlighted in the same color with the exception of the
the first occurrence of the string, which will have a different color in order to tell it apart.
You can use the button in the searchbox to specify if the search will be case sensitive.
You can move the active highlight by either pressing the buttons on the searchbox or by using the Enter or the arrow keys on your keyboard.
`;
public searchText = '';
public matchCount = 0;
public caseSensitive = false;
public index = 0;
constructor(private highlightService: IgxTextHighlightService) { }
publicngOnDestroy() {
this.highlightService.destroyGroup('group1');
}
publicsearchKeyDown(ev) {
if (this.searchText) {
if (ev.key === 'Enter' || ev.key === 'ArrowDown' || ev.key === 'ArrowRight') {
ev.preventDefault();
this.findNext();
} elseif (ev.key === 'ArrowUp' || ev.key === 'ArrowLeft') {
ev.preventDefault();
this.findPrev();
}
}
}
publiconTextboxChange() {
this.index = 0;
this.find(0);
}
publicupdateSearch() {
this.caseSensitive = !this.caseSensitive;
this.find(0);
}
publicclearSearch() {
this.searchText = '';
this.find(0);
}
publicgetcanMoveHighlight() {
returnthis.matchCount > 1;
}
publicfindNext() {
this.find(1);
}
publicfindPrev() {
this.find(-1);
}
privatefind(increment: number) {
if (this.searchText) {
this.matchCount = this.highlight.highlight(this.searchText, this.caseSensitive);
this.index += increment;
this.index = this.index < 0 ? this.matchCount - 1 : this.index;
this.index = this.index > this.matchCount - 1 ? 0 : this.index;
if (this.matchCount) {
this.highlightService.setActiveHighlight('group1', {
index: this.index
});
}
} else {
this.highlight.clearHighlight();
}
}
}
ts