Filtro de pesquisa de grade Angular
Angular pesquisa em grade permite o processo de localização de valores na coleta de dados. Facilitamos a configuração dessa funcionalidade e ela pode ser implementada com caixa de entrada de pesquisa, botões, navegação por teclado e outros recursos úteis para uma experiência de usuário ainda melhor. Embora os navegadores forneçam nativamente a funcionalidade de pesquisa de conteúdo, na maioria das vezes o Grid virtualiza suas colunas e linhas que estão fora de exibição. Nesses casos, a pesquisa em grade nativa não consegue pesquisar dados nas células virtualizadas, pois elas não fazem parte do DOM. Estendemos a Ignite UI for Angular grade baseada em tabela com uma API de pesquisa que permite pesquisar o conteúdo virtualizado da Grid.
Angular Search Example
O exemplo a seguir representa Grid com caixa de entrada de pesquisa que permite pesquisar em todas as colunas e linhas, bem como opções de filtragem específicas para cada coluna.
Angular Search Usage
Grid setup
Vamos começar criando nossa grade e vinculando-a aos nossos dados. Também adicionaremos alguns estilos personalizados para os 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>
/* searchgrid.component.css */
.grid__wrapper {
margin: 15px;
}
.offset {
margin-bottom: 15px;
}
.resultsText {
font-size: 0.875rem;
}
.chips {
margin-left: 5px;
}
.searchButtons {
margin-left: 5px;
}
Ótimo, e agora vamos nos preparar para a API de pesquisa do nosso Grid! Podemos criar algumas propriedades, que podem ser usadas para armazenar o texto pesquisado no momento e se a pesquisa diferencia maiúsculas de minúsculas e/ou por uma correspondência exata.
// searchgrid.component.ts
public searchText: string = '';
public caseSensitive: boolean = false;
public exactMatch: boolean = false;
Angular search box input
Agora vamos criar nossa entrada de pesquisa! Ao vincular nosso searchText como ngModel à nossa entrada recém-criada e assinar o evento ngModelChange, podemos detectar todas as modificações de searchText pelo usuário. Isso nos permitirá usar os métodos Grid's findNext
and findPrev
para destacar todas as ocorrências do searchText e rolar para o próximo/anterior (dependendo de qual método invocamos).
Ambos os métodos e findNext
os findPrev
métodos têm três argumentos:
text
: string (o texto que estamos procurando)- (opcional)
caseSensitive
: booleano (se a pesquisa diferenciar maiúsculas de minúsculas ou não, o valor padrão é false) - (opcional)
exactMatch
: booleano (se a pesquisa for por uma correspondência exata ou não, o valor padrão é false)
Ao pesquisar por uma correspondência exata, a API de pesquisa destacará como resultados apenas os valores de célula que correspondem inteiramente ao searchText, levando em consideração também a diferenciação de maiúsculas e minúsculas. Por exemplo, as strings 'software' e 'Software' são uma correspondência exata com um desrespeito à diferenciação de maiúsculas e minúsculas.
Os métodos acima retornam um valor numérico (o número de vezes que o Grid contém a string fornecida).
<!--searchgrid.component.html-->
<input #search1 id="search1" placeholder="Search" [(ngModel)]="searchText" (ngModelChange)="grid.findNext(searchText, caseSensitive, exactMatch)" />
Display results count
Vamos também exibir a posição da ocorrência atual, juntamente com a contagem total de resultados! Podemos fazer isso usando a propriedade da lastSearchInfo
grade. Essa propriedade é atualizada automaticamente ao usar os métodos find.
- O
grid.lastSearchInfo.matchInfoCache.length
valor nos dará a contagem total de resultados. - O
grid.lastSearchInfo.activeMatchIndex
valor nos dará a posição do índice da ocorrência atual (correspondência).
<!--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>
Add search buttons
Para pesquisar e navegar livremente entre nossos resultados de pesquisa, vamos criar alguns botões invocando o findNext
e os findPrev
métodos dentro dos respectivos manipuladores de eventos de clique dos botões.
<!--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>
Add keyboard search
Também podemos permitir que os usuários naveguem pelos resultados usando as teclas de seta do teclado e a tecla Enter. Para conseguir isso, podemos lidar com o evento keydown de nossa entrada de pesquisa, impedindo o movimento de cursor padrão da entrada com o método preventDefault() e invocar os findNext
métodos / findPrev
, dependendo de qual tecla o usuário pressionou.
<!--searchgrid.component.html-->
<input #search1 id="search1" placeholder="Search" [(ngModel)]="searchText" (ngModelChange)="grid.findNext(searchText, caseSensitive, exactMatch)"
(keydown)="searchKeyDown($event)" />
// 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);
}
}
Case sensitive and Exact match
Agora vamos permitir que o usuário escolha se a pesquisa deve diferenciar maiúsculas de minúsculas e/ou por uma correspondência exata. Para esse propósito, podemos usar entradas de caixa de seleção simples, vinculando nossas propriedades caseSensitive e exactMatch às propriedades inputs'checked, respectivamente, e manipular seus eventos de alteração alternando nossas propriedades e invocando o findNext
método.
<!--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()">
// 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);
}
Persistence
E se quisermos filtrar e classificar nossa grade ou até mesmo adicionar e remover registros? Após essas operações, os destaques de nossa pesquisa atual são atualizados automaticamente e persistem sobre qualquer texto que corresponda ao searchText! Além disso, a pesquisa funcionará com paginação e manterá os destaques por meio de alterações na propriedade do perPage
Grid.
Adding icons
Usando alguns de nossos outros componentes, podemos criar uma interface de usuário enriquecida e melhorar o design geral de toda a nossa barra de pesquisa! Podemos ter um bom ícone de pesquisa ou exclusão à esquerda da entrada de pesquisa, alguns chips para nossas opções de pesquisa e alguns ícones de design de material combinados com belos botões de estilo ondulado para nossa navegação à direita. Podemos envolver esses componentes dentro de um grupo de entrada para um design mais refinado. Para fazer isso, vamos pegar os 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 {}
Por fim, vamos atualizar nosso modelo com os novos componentes!
Vamos encapsular todos os nossos componentes dentro de um IgxInputGroup. À esquerda, alternaremos entre uma pesquisa e um ícone de exclusão/limpeza (dependendo se a entrada de pesquisa está vazia ou não). No centro, posicionaremos a própria entrada. Além disso, sempre que o ícone de exclusão for clicado, atualizaremos nosso searchText e invocaremos o método do clearSearch
Grid para limpar os destaques.
<!--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>
// searchgrid.component.ts
public clearSearch() {
this.searchText = '';
this.grid.clearSearch();
}
À direita, em nosso grupo de entrada, vamos criar três contêineres separados com as seguintes finalidades:
- Para exibir os resultados da pesquisa.
<!--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>
- Para exibir alguns chips que alternam as propriedades caseSensitive e exactMatch. Substituímos as caixas de seleção por dois chips elegantes que mudam de cor com base nessas propriedades. Sempre que um chip é clicado, invocamos seu respectivo manipulador -updateSearch ou updateExactSearch, dependendo de qual chip foi clicado.
<!--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>
...
- Para os botões de navegação de pesquisa, transformamos nossas entradas em botões de estilo ondulado com ícones de materiais. Os manipuladores para os eventos de clique permanecem os mesmos - invocando os 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>
Known Limitations
Limitação | Descrição |
---|---|
Pesquisando em células com um modelo | Os destaques da funcionalidade de pesquisa funcionam apenas para os modelos de célula padrão. Se você tiver uma coluna com modelo de célula personalizado, os destaques não funcionarão, então você deve usar abordagens alternativas, como um formatador de coluna, ou definir osearchable propriedade na coluna como falsa. |
Virtualização Remota | A pesquisa não funcionará corretamente ao usar virtualização remota |
Células com texto cortado | Quando o texto na célula é muito grande para caber e o texto que estamos procurando é cortado pelas reticências, ainda rolaremos até a célula e a incluiremos na contagem de correspondências, mas nada será destacado |
API References
Neste artigo, implementamos nossa própria barra de pesquisa para o Grid com algumas funcionalidades adicionais quando se trata de navegar entre os resultados da pesquisa. Também usamos alguns componentes Ignite UI for Angular adicionais, como ícones, chips e entradas. A API de pesquisa está listada abaixo.
IgxGridComponent
methods:
IgxGridCell
methods:
IgxColumnComponent
properties:
Componentes e/ou diretivas adicionais com APIs relativas que foram usadas:
- Componente do grupo de entrada Igx
- Componente IgxIcon
- Diretiva IgxRipple
- Diretiva IgxButton
- Componente IgxChip
Styles:
- Estilos IgxGridComponent
- Estilos de IgxInputGroupComponent
- Estilos IgxIconComponent
- Estilos IgxRippleDirective
- Estilos de IgxButtonDirective
- Estilos IgxChipComponent
Additional Resources
- Visão geral da grade
- Virtualização e desempenho
- Filtragem
- Paginação
- Classificação
- Resumos
- Movimentação de Colunas
- Fixação de coluna
- Redimensionamento de colunas
- Escolha