Descripción general de la directiva de resaltado de texto Angular
Los IgxTextHighlightDirective
y IgxTextHighlightService
en Ignite UI for Angular se utilizan para resaltar partes de un texto, proporcionando opciones para búsquedas que distinguen entre mayúsculas y minúsculas y para resaltar solo coincidencias exactas. Permiten al desarrollador mantener un resaltado activo, que puede ser cualquiera de las partes ya resaltadas.
Angular Text Highlight Directive Example
Getting Started with Ignite UI for Angular Text Highlight Directive
Para comenzar con la directiva Ignite UI for Angular Text Highlight, primero debe instalar Ignite UI for Angular. En una aplicación Angular existente, escriba el siguiente comando:
ng add igniteui-angular
Para obtener una introducción completa a la Ignite UI for Angular, lea el tema de introducción.
El siguiente paso es importar IgxTextHighlightModule
en su archivo 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, a partir de 16.0.0
puede importar IgxTextHighlightDirective
como una dependencia independiente.
// 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) {}
}
Ahora que tiene importado el módulo o la directiva Ignite UI for Angular Text Salt, puede comenzar a usar el igxTextHighlight
.
Using the Angular Text Highlight Directive
Creemos un cuadro de búsqueda que podamos usar para resaltar diferentes partes del texto. Usaremos Ignite UI for Angular Grupo de entrada componente en el que agregaremos una entrada de texto con botones para borrar coincidencias, buscar siguiente, buscar anterior y un botón para especificar si la búsqueda distinguirá entre mayúsculas y minúsculas o no. También tiene una etiqueta que indica cuántas coincidencias hemos encontrado.
<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>
Luego, agregaremos un div con texto y la directiva IgxTextHighlight. Tenga en cuenta que, dado que necesitamos vincular la entrada del valor al texto en el div, también usaremos la interpolación para el texto del div.
<div igxTextHighlight
[value]="html"
[groupName]="'group1'"
[containerClass]="'search-text'"
class="search-text">
{{html}}
</div>
En el archivo .ts de nuestro componente, primero debemos agregar los siguientes campos, que se utilizan para los enlaces en la plantilla de nuestro 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;
}
}
Luego, debemos agregar los siguientes métodos que permitirán al usuario aplicar resaltados al texto que ha escrito en el cuadro de búsqueda y mover el resaltado activo.
@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();
}
}
}
Si la muestra está configurada correctamente, el resultado final debería verse así:
Search across multiple elements
igxTextHighlight
le permite buscar en múltiples elementos que comparten un resaltado activo. Esto se hace teniendo el mismo valor groupName
en varias directivas TextHighlight. Para configurar el ejemplo reutilizaremos el cuadro de búsqueda del ejemplo anterior, pero esta vez agregaremos dos elementos div. Las entradas column
y row
son útiles cuando tienes varios elementos y, en nuestro caso, el segundo div tiene un valor de fila diferente.
<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>
En el archivo .ts tenemos los campos firstParagraph
y secondParagraph
, que están vinculados a las respectivas entradas de valor de las directivas de resaltado de texto. Además, ahora usaremos ViewChildren en lugar de ViewChild para obtener todos los aspectos destacados de nuestra plantilla.
public firstParagraph = "...";
public secondParagraph = "...";
@ViewChildren(IgxTextHighlightDirective)
public highlights;
Todo el resto del código en el archivo .ts es idéntico al ejemplo de elemento único con la excepción del método de búsqueda. Los cambios en este método son necesarios ya que ahora tenemos varios elementos, pero el código allí se puede usar independientemente de la cantidad de directivas TextHighlight que tenga en su 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
A la directiva IgxTextHighlight
se le puede aplicar estilo en términos de cambiar el color y el fondo de todas las apariciones de la cadena dada. Para comenzar, necesitamos importar el archivo index
, donde se encuentran todas las funciones del tema y los mixins de componentes:
@use "igniteui-angular/theming" as *;
// IMPORTANT: Prior to Ignite UI for Angular version 13 use:
// @import '~igniteui-angular/lib/core/styles/themes/index';
Siguiendo el enfoque más simple, creamos un nuevo tema que extiende el highlight-theme
y acepta los parámetros $resting-background
, $resting-color
, $active-background
y $active-color
.
$dark-highlight: highlight-theme(
$resting-background: #FFCD0F,
$resting-color: #292826,
$active-background: #292826,
$active-color: #FFCD0F
);
Los parámetros $resting-background
y $resting-color
se aplicarán a todas las ocurrencias resaltadas, excepto a la cadena resaltada activa, cuyo estilo se diseñará según los parámetros $active-background
y $active-color
.
El último paso es incluir el tema recién creado.
Si $legacy-support
está configurado en true
, incluya el tema del componente así:
@include highlight($dark-highlight);
Note
Si el componente utiliza una ViewEncapsulation Emulated
, es necesario penetrar esta encapsulación usando::ng-deep
:
:host {
::ng-deep {
@include highlight($dark-highlight);
}
}
Si $legacy-support
está configurado en false
(predeterminado), incluya las variables CSS del componente así:
@include css-vars($dark-highlight);
Note
Tenga en cuenta que, de forma predeterminada, $legacy-support
está configurado en false
Custom styles
Digamos que queremos proporcionar un estilo aún más rico a nuestras partes de texto resaltadas. Para hacer esto, podemos aprovechar las entradas cssClass
y activeCssClass
de la directiva IgxTextHighlight
. ¡Podemos combinar estas clases con los estilos del highlight-theme
y brindar una experiencia increíble a nuestros usuarios!
Todo lo que tenemos que hacer es crear un par de clases CSS con algunas propiedades y adjuntarlas usando las entradas anteriores:
<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 mencionamos anteriormente, incluso podemos combinarlos con un tema:
:host {
::ng-deep {
@include highlight($dark-highlight);
// cssClass
.custom-highlight {
border: 1px solid #FFCD0F;
}
// activeCssClass
.custom-active-highlight {
box-shadow: 0 0 3px 0 rgba(0,0,0,0.75);
}
}
}
Demo
API References
Para obtener información más detallada sobre la API de la directiva TextHighlight, consulte el siguiente enlace:
Componentes adicionales que se utilizaron: