Angular Edição e validação de grade hierárquica
A edição da Grade Hierárquica expõe um mecanismo de validação integrado da entrada do usuário ao editar células/linhas. Ele estende a funcionalidade de validação de formulário Angular para permitir uma integração mais fácil com uma funcionalidade bem conhecida. Quando o estado do editor é alterado, os indicadores visuais são aplicados à célula editada.
Configuração
Configure via template-driven configuration
Estendemos algumas das diretivas do validador do Angular Forms para trabalhar diretamente com oIgxColumn. Os mesmos validadores estão disponíveis como atributos a serem definidos declarativamente em.igx-column Os seguintes validadores são suportados de fábrica:
- obrigatório
- mínimo
- máx.
- comprimento mínimo
- comprimento máximo
- padrão
Para validar que uma entrada de coluna será definida e o valor será formatado como um e-mail, você pode usar as diretivas relacionadas:
<igx-column [field]="email" [header]="User E-mail" required email></igx-column>
The following sample demonstrates how to use the prebuilt required, email and min validator directives in a Hierarchical Grid.
Configure via reactive forms
Expomos oFormGroup que será usado para validação quando a edição começar em uma linha/célula via eventoformGroupCreated. Você pode modificá-lo adicionando seus próprios validadores para os campos relacionados:
<igx-hierarchical-grid (formGroupCreated)='formCreateHandler($event)' ...>
public formCreateHandler(args: IGridFormGroupCreatedEventArgs) {
const formGroup = args.formGroup;
const orderDateRecord = formGroup.get('OrderDate');
const requiredDateRecord = formGroup.get('RequiredDate');
const shippedDateRecord = formGroup.get('ShippedDate');
orderDateRecord.addValidators(this.futureDateValidator());
requiredDateRecord.addValidators(this.pastDateValidator());
shippedDateRecord.addValidators(this.pastDateValidator());
}
Você pode decidir escrever sua própria função validadora ou usar uma das funções validadoras integradas Angular.
Validation service API
A grade expõe um serviço de validação via avalidation propriedade. Esse serviço possui as seguintes APIs públicas:
valid- retorna se o estado de validação da grade for válido.getInvalid- retorna registros com estados inválidos.clear- Libera o estado para registro por ID ou elimina todo o estado se nenhum ID for fornecido.markAsTouched- marca o registro/campo relacionado como tocado.
Os estados inválidos persistirão até que os erros de validação neles sejam corrigidos de acordo com a regra de validação ou sejam limpos.
Validation triggers
A validação será acionada nos seguintes cenários:
- Enquanto edita via o editor de células baseado na grade
validationTrigger. Ou ligadochangeenquanto digita no editor, ou quandobluro editor perde o foco ou fecha. - Ao atualizar células/linhas via API -
updateRow,updateCelletc. - Ao usar edição em lote e a/
undoredoAPI do serviço de transação.
Nota: A validação não será acionada para registros que não foram editados via entrada do usuário ou via API de edição. Indicadores visuais na célula só serão mostrados se a entrada relacionada for considerada tocada – seja por interação do usuário ou pela
markAsTouchedAPI do serviço de validação.
Angular Hierarchical Grid Validation Customization Options
Set a custom validator
Você pode definir sua própria diretriz de validação para usar no<igx-column> modelo.
@Directive({
selector: '[phoneFormat]',
providers: [{ provide: NG_VALIDATORS, useExisting: PhoneFormatDirective, multi: true }]
})
export class PhoneFormatDirective extends Validators {
@Input('phoneFormat')
public phoneFormatString = '';
public validate(control: AbstractControl): ValidationErrors | null {
return this.phoneFormatString ? phoneFormatValidator(new RegExp(this.phoneFormatString, 'i'))(control)
: null;
}
}
Depois de definido e adicionado ao módulo do seu aplicativo, você pode defini-lo declarativamente para uma determinada coluna na grade:
<igx-column phoneFormat="\+\d{1}\-(?!0)(\d{3})\-(\d{3})\-(\d{4})\b" ...>
Change default error template
Você pode definir seu próprio modelo de erro personalizado que será exibido na dica de ferramenta de erro quando a célula entrar em estado inválido. Isso é útil em cenários em que você deseja adicionar sua própria mensagem de erro personalizada ou alterar a aparência ou o conteúdo da mensagem.
<igx-column ... >
<ng-template igxCellValidationError let-cell='cell' let-defaultErr="defaultErrorTemplate">
<ng-container *ngTemplateOutlet="defaultErr">
</ng-container>
<div *ngIf="cell.validation.errors?.['phoneFormat']">
Please enter correct phone format
</div>
</ng-template>
</igx-column>
Prevent exiting edit mode on invalid state
Em alguns casos, você pode querer impedir o envio de um valor inválido nos dados. Nesses cenários, você pode usar oscellEdit eventos ourowEdit e cancelar o evento caso o novo valor seja inválido. Os argumentos de ambos os eventos têm umavalid propriedade e podem ser cancelados de acordo. Como ele é usado pode ser visto no exemplo de Validação Cruzada de Campo
<igx-hierarchical-grid (cellEdit)='cellEdit($event)' ...>
public cellEdit(evt) {
if (!evt.valid) {
evt.cancel = true;
}
}
Example
O exemplo abaixo demonstra as opções de personalização mencionadas acima.
Cross-field validation
Em alguns cenários, a validação de um campo pode depender do valor de outro campo no registro. Nesse caso, um validador personalizado pode ser usado para comparar os valores no registro via seu compartilhamentoFormGroup.
Cross-field validators can be added to the formGroup on the formGroupCreated event. In them multiple fields can be compared for validity.
public formCreateCustomerHandler(event: IGridFormGroupCreatedEventArgs) {
const formGroup = event.formGroup;
formGroup.addValidators(this.addressValidator());
}
public formCreateOrderHandler(event: IGridFormGroupCreatedEventArgs) {
const formGroup = event.formGroup;
formGroup.addValidators(this.dateValidator());
}
public addressValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const formGroup = control;
let returnObject = {};
const city = formGroup.get('City');
const country = formGroup.get('Country');
const validCities = this.countryData.get(country.value);
if (!validCities || !validCities[city.value]) {
returnObject['invalidAddress'] = true;
}
return returnObject;
}
}
public dateValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const formGroup = control;
let returnObject = {};
const orderDate = formGroup.get('OrderDate').value;
const shippedDate = formGroup.get('ShippedDate').value;
if (new Date(shippedDate) < new Date(orderDate)) {
returnObject['invalidRange'] = true;
}
return returnObject;
}
}
Os erros de vários campos podem ser exibidos em uma coluna fixada separada.
<igx-column field="row_valid" header=" " [editable]="false" [dataType]="'number'" [pinned]="true" [width]="'50px'">
<ng-template igxCell let-cell="cell">
<div *ngIf="isRowValid(cell)" [igxTooltipTarget]="tooltipRef"
>
<img width="18" src="assets/images/grid/active.png"/>
</div>
<div *ngIf="!isRowValid(cell)" [igxTooltipTarget]="tooltipRef"
>
<img width="18" src="assets/images/grid/expired.png"/>
</div>
<div #tooltipRef="tooltip" igxTooltip [style.width]="'max-content'">
<div *ngFor="let message of stateMessage(cell)">
{{message}}
</div>
</div>
</ng-template>
</igx-column>
Os erros e as mensagens detalhadas podem ser determinados com base na validade da linha e da célula.
public isRowValid(cell: CellType) {
const hasErrors = !!cell.row.validation.errors || cell.row.cells.some(x => !!x.validation.errors);
return !hasErrors;
}
public stateMessage(cell: CellType) {
const messages = [];
const row = cell.row;
if (row.validation.errors?.invalidAddress) {
messages.push('The address information is invalid. City does not match the Country.');
}
if (row.validation.errors?.invalidRange) {
messages.push('The ShippedDate cannot be before the OrderDate.');
}
const cellValidationErrors = row.cells.filter(x => !!x.validation.errors);
if (cellValidationErrors && cellValidationErrors.length > 0) {
const fields = cellValidationErrors.map(x => x.column.field).join(',');
messages.push('The following fields are required: ' + fields);
}
if (messages.length === 0) {
// no errors
return ['Valid'];
}
return messages;
}
Cross-field example
O exemplo abaixo demonstra a validação entre campos em uma Grade Hierárquica para os dados raiz e filho.
Estilização
Usando a Ignite UI for Angular, podemos alterar os estilos de validação padrão durante a edição.
No exemplo abaixo, faremos uso do modelo exposto para mensagem de validação, que aparece em uma dica de ferramenta e substitui a cor do erro para modificar a aparência padrão da validação. Também estilizaremos o plano de fundo das linhas inválidas para torná-las mais distintas.
Import theme
A maneira mais fácil de estilizar e acessar variáveis CSS é definir estilos noapp nosso arquivo de estilo global (normalmentestyles.scss). A primeira coisa que precisamos fazer é importar othemes/index arquivo – isso nos dá acesso a todas as ferramentas poderosas do framework Ignite UI for Angular Sass:
@use "igniteui-angular/theming" as *;
// IMPORTANT: Prior to Ignite UI for Angular version 13 use:
// @import '~igniteui-angular/lib/core/styles/themes/index';
Include the styles
Para mudar a cor de erro, você pode usar a variável--igx-error-500 css:
--igx-error-500: 34, 80%, 63%;
Custom Templates
Alterar o modelo de erro padrão permite definir classes e estilos personalizados:
<ng-template igxCellValidationError let-cell='cell' let-defaultErr='defaultErrorTemplate'>
<div class="validator-container">
<ng-container *ngTemplateOutlet="defaultErr">
</ng-container>
</div>
</ng-template>
Invalid row and cell styles
Linhas e células fornecem API para que os desenvolvedores saibam se uma linha ou célula é inválida e que tipo de erro está ativo.
public rowStyles = {
background: (row: RowType) => row.validation.status === 'INVALID' ? '#FF000033' : '#00000000'
};
public cellStyles = {
'invalid-cell': (rowData, columnKey) => {
let cell = this.hierarchicalGrid.getCellByKey(rowData, columnKey);
// search in child grids
if (!cell) {
for (let grid of this.childGrid.gridAPI.getChildGrids()) {
cell = grid.getCellByKey(rowData, columnKey);
if (cell) break;
}
}
return cell && cell.validation.status === 'INVALID';
}
}
<igx-hierarchical-grid [rowStyles]="rowStyles">
<igx-column field="Artist" [editable]="true" [dataType]="'string'" required [cellClasses]="cellStyles">
...
<igx-row-island [key]="'Albums'" [rowStyles]="rowStyles">
<igx-column field="Album" [editable]="true" [dataType]="'string'" required [cellClasses]="cellStyles">
Demo
API References
Known Issues and Limitations
| Limitação | Descrição |
|---|---|
QuandovalidationTrigger é borrão,editValue e a validação será acionada somente depois que o editor estiver desfocado. |
A razão é que isso utiliza o formControl'supdateOn propriedade. Isso determina o evento no qual o formControl atualizará e acionará validadores relacionados. |
Additional Resources
- Crie operações CRUD com igxGrid
- Visão geral da grade hierárquica
- Edição de grade hierárquica
- Edição de linha de grade hierárquica
- Adição de linha de grade hierárquica
- Transações de grade hierárquica