Filtro de búsqueda de cuadrícula Angular
Angular La búsqueda en cuadrícula permite el proceso de búsqueda de valores en la recopilación de datos. Facilitamos la configuración de esta funcionalidad y se puede implementar con un cuadro de entrada de búsqueda, botones, navegación por teclado y otras características útiles para una experiencia de usuario aún mejor. Si bien los navegadores proporcionan de forma nativa la funcionalidad de búsqueda de contenido, la mayoría de las veces la cuadrícula virtualiza sus columnas y filas que están fuera de la vista. En estos casos, la búsqueda de cuadrícula nativa no puede buscar datos en las celdas virtualizadas, ya que no forman parte del DOM. Hemos ampliado la cuadrícula basada en tablas Ignite UI for Angular con una API de búsqueda que le permite buscar a través del contenido virtualizado de la cuadrícula.
Ejemplo de búsqueda Angular
El siguiente ejemplo representa una cuadrícula con un cuadro de entrada de búsqueda que permite buscar en todas las columnas y filas, así como opciones de filtrado específicas para cada columna.
¿Te gusta esta muestra? Obtenga acceso a nuestro kit de herramientas de Ignite UI for Angular completo y comience a crear sus propias aplicaciones en minutos. Descárgalo gratis.
Uso de la búsqueda Angular
Configuración de cuadrícula
Comencemos creando nuestra cuadrícula y vinculándola a nuestros datos. ¡También agregaremos algunos estilos personalizados para los componentes que usaremos!
<!--searchgrid.component.html-->
<igx-grid #grid1 id="grid1" [data]="data" [autoGenerate]="false" [allowFiltering]="true">
<igx-column [field]="'IndustrySector'" dataType="string" [sortable]="true"></igx-column>
<igx-column [field]="'IndustryGroup'" dataType="string" [sortable]="true"></igx-column>
<igx-column [field]="'SectorType'" dataType="string" [sortable]="true"></igx-column>
<igx-column [field]="'KRD'" dataType="number" [sortable]="true"></igx-column>
<igx-column [field]="'MarketNotion'" dataType="number" [sortable]="true"></igx-column>
<igx-column [field]="'Date'" dataType="date" [sortable]="true"></igx-column>
</igx-grid>
html
/* searchgrid.component.css */
.grid__wrapper {
margin: 15px;
}
.offset {
margin-bottom: 15px;
}
.resultsText {
font-size: 0.875rem;
}
.chips {
margin-left: 5px;
}
.searchButtons {
margin-left: 5px;
}
css
¡Genial, y ahora preparémonos para la API de búsqueda de nuestro Grid! Podemos crear algunas propiedades, que se pueden usar para almacenar el texto buscado actualmente y si la búsqueda distingue entre mayúsculas y minúsculas y/o por coincidencia exacta.
// searchgrid.component.ts
public searchText: string = '';
public caseSensitive: boolean = false;
public exactMatch: boolean = false;
typescript
Entrada del cuadro de búsqueda Angular
¡Ahora creemos nuestra entrada de búsqueda! Al vincular nuestro searchText como ngModel a nuestra entrada recién creada y suscribirnos al evento ngModelChange, podemos detectar cada modificación de searchText por parte del usuario. Esto nos permitirá usar los métodos findNext
y findPrev
de Grid para resaltar todas las apariciones de searchText y desplazarnos al siguiente/anterior (dependiendo del método que hayamos invocado).
Tanto el método findNext
como el findPrev
tienen tres argumentos:
text
: cadena (el texto que estamos buscando)- (opcional)
caseSensitive
: booleano (si la búsqueda distingue entre mayúsculas y minúsculas o no, el valor predeterminado es falso) - (opcional)
exactMatch
: booleano (si la búsqueda se realiza por coincidencia exacta o no, el valor predeterminado es falso)
Al buscar por coincidencia exacta, la API de búsqueda resaltará como resultados solo los valores de celda que coincidan completamente con el texto de búsqueda teniendo en cuenta también la distinción entre mayúsculas y minúsculas. Por ejemplo, las cadenas 'software' y 'Software' coinciden exactamente sin tener en cuenta la distinción entre mayúsculas y minúsculas.
Los métodos anteriores devuelven un valor numérico (el número de veces que Grid contiene la cadena dada).
<!--searchgrid.component.html-->
<input #search1 id="search1" placeholder="Search" [(ngModel)]="searchText" (ngModelChange)="grid.findNext(searchText, caseSensitive, exactMatch)" />
html
Mostrar recuento de resultados
¡Muestremos también la posición de la ocurrencia actual, junto con el recuento total de resultados! Podemos hacer esto usando la propiedad lastSearchInfo
de la cuadrícula. Esta propiedad se actualiza automáticamente cuando se utilizan los métodos de búsqueda.
- El valor
grid.lastSearchInfo.matchInfoCache.length
nos dará el recuento total de resultados. - El valor
grid.lastSearchInfo.activeMatchIndex
nos dará la posición del índice de la ocurrencia actual (coincidencia).
<!--searchgrid.component.html-->
<div class="resultsText" *ngIf="grid.lastSearchInfo">
<span *ngIf="grid.lastSearchInfo.matchInfoCache.length > 0">
{{ grid.lastSearchInfo.activeMatchIndex + 1 }} of {{ grid.lastSearchInfo.matchInfoCache.length }} results
</span>
<span *ngIf="grid.lastSearchInfo.matchInfoCache.length == 0">
No results
</span>
</div>
html
Agregar botones de búsqueda
Para buscar y navegar libremente entre nuestros resultados de búsqueda, creemos un par de botones invocando los métodos findNext
y findPrev
dentro de los respectivos controladores de eventos de clic de los botones.
<!--searchgrid.component.html-->
<div class="searchButtons">
<input type="button" value="Previous" (click)="grid.findPrev(searchText, caseSensitive, exactMatch)" />
<input type="button" value="Next" (click)="grid.findNext(searchText, caseSensitive, exactMatch)" />
</div>
html
Agregar búsqueda de teclado
También podemos permitir que los usuarios naveguen por los resultados utilizando las teclas de flecha del teclado y la tecla Intro. Para lograr esto, podemos manejar el evento de pulsación de tecla de nuestra entrada de búsqueda evitando el movimiento del cursor predeterminado de la entrada con el método preventDefault() e invocando los métodos findNext
/ findPrev
dependiendo de qué tecla haya presionado el usuario.
<!--searchgrid.component.html-->
<input #search1 id="search1" placeholder="Search" [(ngModel)]="searchText" (ngModelChange)="grid.findNext(searchText, caseSensitive, exactMatch)"
(keydown)="searchKeyDown($event)" />
html
// searchgrid.component.ts
public searchKeyDown(ev) {
if (ev.key === 'Enter' || ev.key === 'ArrowDown' || ev.key === 'ArrowRight') {
ev.preventDefault();
this.grid.findNext(this.searchText, this.caseSensitive, this.exactMatch);
} else if (ev.key === 'ArrowUp' || ev.key === 'ArrowLeft') {
ev.preventDefault();
this.grid.findPrev(this.searchText, this.caseSensitive, this.exactMatch);
}
}
typescript
Distingue entre mayúsculas y minúsculas y coincidencia exacta
Ahora permitamos que el usuario elija si la búsqueda debe distinguir entre mayúsculas y minúsculas y/o por una coincidencia exacta. Para este propósito, podemos usar entradas de casilla de verificación simples vinculando nuestras propiedades caseSensitive y exactitudMatch a las propiedades marcadas de las entradas respectivamente y manejar sus eventos de cambio alternando nuestras propiedades e invocando el método findNext
.
<!--searchgrid.component.html-->
<span>Case sensitive</span>
<input type="checkbox" [checked]="caseSensitive" (change)="updateSearch()">
<span>Exact match</span>
<input type="checkbox" [checked]="exactMatch" (change)="updateExactSearch()">
html
// searchgrid.component.ts
public updateSearch() {
this.caseSensitive = !this.caseSensitive;
this.grid.findNext(this.searchText, this.caseSensitive, this.exactMatch);
}
public updateExactSearch() {
this.exactMatch = !this.exactMatch;
this.grid.findNext(this.searchText, this.caseSensitive, this.exactMatch);
}
typescript
Persistencia
¿Qué pasa si quisiéramos filtrar y ordenar nuestro Grid o incluso agregar y eliminar registros? Después de tales operaciones, los aspectos más destacados de nuestra búsqueda actual se actualizan automáticamente y persisten en cualquier texto que coincida con searchText. Además, la búsqueda funcionará con paginación y mantendrá los aspectos destacados a través de cambios en la propiedad perPage
de Grid.
Agregar íconos
Al utilizar algunos de nuestros otros componentes, podemos crear una interfaz de usuario enriquecida y mejorar el diseño general de toda nuestra barra de búsqueda. Podemos tener un bonito icono de búsqueda o eliminación a la izquierda de la entrada de búsqueda, un par de chips para nuestras opciones de búsqueda y algunos iconos de diseño de materiales combinados con bonitos botones de estilo ondulado para nuestra navegación a la derecha. Podemos envolver estos componentes dentro de un grupo de entrada para un diseño más refinado. Para hacer esto, tomemos los módulos IgxInputGroup, IgxIcon, IgxRipple, IgxButton e IgxChip.
// app.module.ts
...
import {
IgxGridModule,
IgxInputGroupModule,
IgxIconModule,
IgxRippleModule,
IgxButtonModule,
IgxChipsModule
} from 'igniteui-angular';
// import {
// IgxInputGroupModule,
// IgxIconModule,
// IgxRippleModule,
// IgxButtonModule,
// IgxChipsModule
// } from '@infragistics/igniteui-angular'; for licensed package
@NgModule({
...
imports: [..., IgxInputGroupModule, IgxIconModule, IgxRippleModule, IgxButtonModule, IgxChipsModule],
})
export class AppModule {}
typescript
Finalmente, ¡actualicemos nuestra plantilla con los nuevos componentes!
Envolveremos todos nuestros componentes dentro de un IgxInputGroup. A la izquierda alternaremos entre una búsqueda y un icono de eliminar/borrar (dependiendo de si la entrada de búsqueda está vacía o no). En el centro posicionaremos la propia entrada. Además, cada vez que se haga clic en el icono de eliminación, actualizaremos nuestro texto de búsqueda e invocaremos el método clearSearch
de Grid para borrar los aspectos destacados.
<!--searchgrid.component.html-->
<igx-input-group type="search" class="offset">
<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" [(ngModel)]="searchText" (ngModelChange)="grid.findNext(searchText, caseSensitive, exactMatch)"
(keydown)="searchKeyDown($event)" />
<igx-suffix *ngIf="searchText.length > 0">
...
</igx-suffix>
</igx-input-group>
html
// searchgrid.component.ts
public clearSearch() {
this.searchText = '';
this.grid.clearSearch();
}
typescript
A la derecha de nuestro grupo de entrada, creemos tres contenedores separados con los siguientes propósitos:
- Para mostrar los resultados de la búsqueda.
<!--searchgrid.component.html-->
<igx-suffix *ngIf="searchText.length > 0">
<div class="resultsText" *ngIf="grid.lastSearchInfo">
<span *ngIf="grid.lastSearchInfo.matchInfoCache.length > 0">
{{ grid.lastSearchInfo.activeMatchIndex + 1 }} of {{ grid.lastSearchInfo.matchInfoCache.length }} results
</span>
<span *ngIf="grid.lastSearchInfo.matchInfoCache.length == 0">
No results
</span>
</div>
</igx-suffix>
html
- Para mostrar un par de chips que alternan las propiedades caseSensitive y exactitudMatch. Hemos reemplazado las casillas de verificación con dos chips elegantes que cambian de color según estas propiedades. Cada vez que se hace clic en un chip, invocamos su controlador respectivo: updateSearch o updateExactSearch dependiendo del chip en el que se haya hecho clic.
<!--searchgrid.component.html-->
...
<div class="chips">
<igx-chips-area>
<igx-chip (click)="updateSearch()" [color]="caseSensitive? 'lightgrey' : 'rgba(0, 0, 0, .04)'">
<span>Case Sensitive</span>
</igx-chip>
<igx-chip (click)="updateExactSearch()" [color]="exactMatch? 'lightgrey' : 'rgba(0, 0, 0, .04)'">
<span>Exact Match</span>
</igx-chip>
</igx-chips-area>
</div>
...
html
- Para los botones de navegación de búsqueda, hemos transformado nuestras entradas en botones de estilo ondulado con íconos de materiales. Los controladores para los eventos de clic siguen siendo los mismos: invocando los métodos
findNext
/findPrev
.
<!--searchgrid.component.html-->
<igx-suffix>
<div class="searchButtons">
<button igxIconButton="flat" igxRipple igxRippleCentered="true" (click)="grid.findPrev(searchText, caseSensitive, exactMatch)">
<igx-icon fontSet="material">navigate_before</igx-icon>
</button>
<button igxIconButton="flat" igxRipple igxRippleCentered="true" (click)="grid.findNext(searchText, caseSensitive, exactMatch)">
<igx-icon fontSet="material">navigate_next</igx-icon>
</button>
</div>
</igx-suffix>
html
Limitaciones conocidas
Limitación | Descripción |
---|---|
Buscando en celdas con una plantilla | Las funciones destacadas de búsqueda funcionan solo para las plantillas de celda predeterminadas. Si tiene una columna con una plantilla de celda personalizada, los resaltados no funcionarán, por lo que deberá utilizar enfoques alternativos, como un formateador de columnas, o configurar elsearchable propiedad en la columna a falso. |
Virtualización remota | La búsqueda no funcionará correctamente al utilizar la virtualización remota |
Celdas con texto cortado | Cuando el texto en la celda es demasiado grande para caber y el texto que estamos buscando está cortado por los puntos suspensivos, aún nos desplazaremos hasta la celda y la incluiremos en el recuento de coincidencias, pero no se resaltará nada. |
Referencias de API
En este artículo, implementamos nuestra propia barra de búsqueda para la cuadrícula con algunas funcionalidades adicionales cuando se trata de navegar entre los resultados de búsqueda. También utilizamos algunos componentes Ignite UI for Angular adicionales como iconos, chips y entradas. La API de búsqueda se enumera a continuación.
IgxGridComponent
methods:
IgxGridCell
methods:
IgxColumnComponent
properties:
Componentes adicionales y/o directivas con API relativas que se utilizaron:
- Componente IgxInputGroup
- Componente IgxIcon
- Directiva IgxRipple
- DirectivaBotónIgx
- Componente IgxChip
Styles:
- Estilos de componentes IgxGrid
- Estilos de componentes IgxInputGroup
- Estilos de componentes IgxIcon
- IgxRippleEstilos Directivos
- Estilos de directiva IgxButton
- Estilos de componentes IgxChip
Recursos adicionales
- Descripción general de la cuadrícula
- Virtualización y rendimiento
- Filtración
- Paginación
- Clasificación
- resúmenes
- Columna en movimiento
- Fijación de columnas
- Cambio de tamaño de columna
- Selección