Visão geral da diretiva de destaque de texto Angular
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
Getting Started with Ignite UI for Angular Text Highlight Directive
Para começar a usar a diretiva Ignite UI for Angular Text Highlight, primeiro você precisa instalar Ignite UI for Angular. Em um aplicativo Angular existente, digite o seguinte comando:
ng add igniteui-angular
Para obter uma introdução completa ao Ignite UI for Angular, leia o tópico de introdução.
O próximo passo é importar issoIgxTextHighlightModule no seu arquivo app.module.ts.
// app.module.ts
...
import { IgxTextHighlightModule } from 'igniteui-angular';
// import { IgxTextHighlightModule } from '@infragistics/igniteui-angular'; for licensed package
@NgModule({
...
imports: [IgxTextHighlightModule],
...
})
export class AppModule {}
Alternativamente,16.0.0 você pode importar comoIgxTextHighlightDirective uma dependência independente.
// home.component.ts
import { IgxTextHighlightDirective, IgxTextHighlightService } from 'igniteui-angular';
// import { IgxTextHighlightDirective, IgxTextHighlightService } from '@infragistics/igniteui-angular'; for licensed package
@Component({
selector: 'app-home',
template: `
<div
igxTextHighlight
[value]="html"
[groupName]="'group1'"
[containerClass]="'search-text'"
class="search-text"
>
{{ html }}
</div>
`,
styleUrls: ['home.component.scss'],
standalone: true,
imports: [IgxTextHighlightDirective],
})
export class HomeComponent {
constructor(public textHighlightService: IgxTextHighlightService) {}
}
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
Vamos criar uma caixa de pesquisa que podemos usar para destacar diferentes partes do texto. Usaremos o componente InputGroup do Ignite UI for Angular no qual adicionaremos uma entrada de texto com botões para limpar correspondências, encontrar próximo, encontrar anterior e um botão para especificar se a pesquisa fará distinção entre maiúsculas e minúsculas ou não. Também tem um rótulo para quantas correspondências encontramos.
<div class="search-container">
<igx-input-group type="search" class="input-group">
<igx-prefix>
<igx-icon *ngIf="searchText.length == 0">search</igx-icon>
<igx-icon *ngIf="searchText.length > 0" (click)="clearSearch()"
>clear</igx-icon
>
</igx-prefix>
<input
#search1
id="search1"
igxInput
placeholder="Search"
autocomplete="off"
[(ngModel)]="searchText"
(ngModelChange)="onTextboxChange()"
(keydown)="searchKeyDown($event)"/>
<igx-suffix>
<div class="caseSensitiveButton">
<button
igxIconButton="flat"
igxRipple
igxRippleCentered="true"
(click)="updateSearch()"
[style.background]="caseSensitive ? 'rgb(73, 180, 254)' : 'transparent'">
<igx-icon class="caseSensitiveIcon" fontSet="material">text_fields</igx-icon>
</button>
</div>
<ng-container *ngIf="searchText.length > 0">
<span>
<ng-container *ngIf="matchCount > 0">
{{ index + 1 }} of {{ matchCount }} results
</ng-container>
<ng-container *ngIf="matchCount == 0"> No results </ng-container>
</span>
</ng-container>
<div class="searchButtons">
<button
igxIconButton="flat"
igxRipple
igxRippleCentered="true"
(click)="findPrev()"
[disabled]="!canMoveHighlight">
<igx-icon fontSet="material">navigate_before</igx-icon>
</button>
<button
igIconButton="flat"
igxRipple
igxRippleCentered="true"
(click)="findNext()"
[disabled]="!canMoveHighlight">
<igx-icon fontSet="material">navigate_next</igx-icon>
</button>
</div>
</igx-suffix>
</igx-input-group>
</div>
Então, adicionaremos um div com texto e a diretiva IgxTextHighlight. Note que, como precisamos vincular o valor de entrada ao texto no div, também usaremos interpolação para o texto do div.
<div
igxTextHighlight
[value]="html"
[groupName]="'group1'"
[containerClass]="'search-text'"
class="search-text">
{{html}}
</div>
No arquivo .ts do nosso componente, primeiro precisamos adicionar os seguintes campos, que são usados para vinculações no modelo do nosso componente:
@Component({
...
})
export class HomeComponent {
public html = '...';
@ViewChild(IgxTextHighlightDirective, {read: IgxTextHighlightDirective})
public highlight: IgxTextHighlightDirective;
public searchText: string = '';
public matchCount: number = 0;
public caseSensitive: boolean = false;
public index: number = 0;
public get canMoveHighlight() {
return this.matchCount > 1;
}
}
Então precisamos adicionar os seguintes métodos que permitirão ao usuário aplicar os destaques ao texto digitado na caixa de pesquisa e mover o destaque ativo.
@Component({
...
})
export class HomeComponent {
constructor(public textHighlightService: IgxTextHighlightService) {}
public searchKeyDown(ev) {
if (this.searchText) {
if (ev.key === 'Enter' || ev.key === 'ArrowDown' || ev.key === 'ArrowRight') {
ev.preventDefault();
this.findNext();
} else if (ev.key === 'ArrowUp' || ev.key === 'ArrowLeft') {
ev.preventDefault();
this.findPrev();
}
}
}
public onTextboxChange() {
this.index = 0;
this.find(0);
}
public updateSearch() {
this.caseSensitive = !this.caseSensitive;
this.find(0);
}
public clearSearch() {
this.searchText = '';
this.find(0);
}
private findNext() {
this.find(1);
}
private findPrev() {
this.find(-1);
}
private find(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.textHighlightService.setActiveHighlight('group1', {
columnIndex: 0,
index: this.index,
page: 0,
rowIndex: 0
});
}
} else {
this.highlight.clearHighlight();
}
}
}
Se a amostra estiver configurada corretamente, o resultado final deverá ser semelhante a este:
Search across multiple elements
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.
<div
igxTextHighlight
[groupName]="'group1'"
[row]="0"
[containerClass]="'search-text'"
[value]="firstParagraph"
class="search-text">
{{firstParagraph}}
</div>
<div
igxTextHighlight
[groupName]="'group1'"
[row]="1"
[containerClass]="'search-text'"
[value]="secondParagraph"
class="search-text">
{{secondParagraph}}
</div>
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;
Todo o restante do código no arquivo .ts é idêntico ao exemplo de elemento único, com exceção do método find. Alterações nesse método são necessárias, pois agora temos vários elementos, mas o código ali pode ser usado independentemente do número de diretivas TextHighlight que você tem na sua página.
@Component({
...
})
export class HomeComponent {
constructor(public textHighlightService: IgxTextHighlightService) {}
private find(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.textHighlightService.setActiveHighlight('group1', {
index: actualIndex,
rowIndex: row
});
}
} else {
this.highlights.forEach((h) => {
h.clearHighlight();
});
this.matchCount = 0;
}
}
}
Styles
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';
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.
$dark-highlight: highlight-theme(
$resting-background: #ffcd0f,
$resting-color: #292826,
$active-background: #292826,
$active-color: #ffcd0f,
);
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.
O último passo é incluir o tema recém-criado.
:host {
::ng-deep {
@include css-vars($dark-highlight);
}
}
Note
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!
Tudo o que precisamos fazer é criar algumas classes CSS com algumas propriedades e anexá-las usando as entradas acima:
<div
igxTextHighlight
[cssClass]="'custom-highlight'"
[activeCssClass]="'custom-active-highlight'">
{{html}}
</div>
// cssClass
.custom-highlight {
border: 1px solid #ffcd0f;
}
// activeCssClass
.custom-active-highlight {
box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.75);
}
Como mencionado anteriormente, podemos até combiná-los com um tema:
:host {
::ng-deep {
@include css-vars($dark-highlight);
.custom-highlight {
border: 1px solid #ffcd0f;
}
.custom-active-highlight {
box-shadow: 0 0 3px 0 rgba(0,0,0, .5);
}
}
}
Demo
API References
Para obter informações mais detalhadas sobre a API da diretiva TextHighlight, consulte o seguinte link:
Componentes adicionais que foram usados: