Descripción general de la directiva de resaltado de texto de Angular

    LosIgxTextHighlightDirective yIgxTextHighlightService en Ignite UI for Angular se utilizan para resaltar partes de un texto, proporcionando opciones para búsquedas con 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 al Ignite UI for Angular, lea el tema de introducción.

    El siguiente paso es importarlosIgxTextHighlightModule en tu archivo app.module.ts.

    // app.module.ts
    ...
    import { IgxTextHighlightModule } from 'igniteui-angular/directives';
    // import { IgxTextHighlightModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        ...
        imports: [IgxTextHighlightModule],
        ...
    })
    export class AppModule {}
    

    Alternativamente,16.0.0 puedes importarlosIgxTextHighlightDirective como una dependencia independiente.

    // home.component.ts
    
    import { IgxTextHighlightDirective, IgxTextHighlightService } from 'igniteui-angular/directives';
    // 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 tienes importado el módulo o directiva de Resaltado de Texto Ignite UI for Angular, puedes empezar a usar eligxTextHighlight.

    Using the Angular Text Highlight Directive

    Vamos a crear un cuadro de búsqueda que podamos usar para resaltar diferentes partes del texto. Usaremos el componente InputGroup de Ignite UI for Angular 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. Además, tiene una etiqueta para 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

    PermiteigxTextHighlight buscar entre varios elementos que comparten un mismo resaltado activo. Esto se hace teniendo el mismogroupName valor entre varias directivas de TextRescente. Para configurar la muestra reutilizaremos el cuadro de búsqueda de la muestra anterior, pero esta vez añadiremos dos elementos div. Lascolumn entradas yrow son útiles cuando tienes varios elementos y, en nuestro caso, la segunda división 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 losfirstParagraph campos ysecondParagraph, que están vinculados a las respectivas entradas de valores de las directivas de resaltado de texto. Además, ahora usaremos ViewChildren en lugar de ViewChild para obtener todos los puntos destacados en 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

    LaIgxTextHighlight directiva puede estilizarse en términos de cambiar el color y el fondo de todas las ocurrencias de la cadena dada. Para empezar, necesitamos importar elindex archivo, donde están todas las funciones de tema y los componentes mezclados:

    @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 sencillo, creamos un nuevo tema que extiende loshighlight-theme y acepta los$resting-background parámetros.$resting-color$active-background$active-color

    $dark-highlight: highlight-theme(
      $resting-background: #ffcd0f,
      $resting-color: #292826,
      $active-background: #292826,
      $active-color: #ffcd0f,
    );
    

    Los$resting-background parámetros y$resting-color se aplicarán a todas las ocurrencias resaltadas, excepto a la cadena activa resaltada, que se estilizará en función de los$active-background$active-color parámetros y .

    El último paso es incluir el tema recién creado.

    :host {
      ::ng-deep {
        @include css-vars($dark-highlight);
      }
    }
    
    Note

    Si el componente utiliza unaEmulated ViewEncapsulation, es necesario quepenetrate esta encapsulación use::ng-deep para aplicar los estilos.

    Custom styles

    Supongamos que queremos ofrecer un estilo aún más rico a nuestras partes de texto resaltadas. Para ello, podemos aprovechar lascssClassactiveCssClass entradas y de laIgxTextHighlight directiva. Podemos combinar estas clases con los estilos de loshighlight-theme y ofrecer 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 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 obtener información más detallada sobre la API de la directiva TextHighlight, consulte el siguiente enlace:

    Componentes adicionales que se utilizaron:

    Additional Resources

    Nuestra comunidad es activa y siempre da la bienvenida a nuevas ideas.