Skip to content

Grid Validation Specification

Maya edited this page Aug 30, 2022 · 23 revisions

Grid Validation Specification

Contents

  1. Overview
  2. User Stories
  3. Functionality
  4. Test Scenarios
  5. Accessibility
  6. Assumptions and Limitations
  7. References

Owned by

Grinders

Developer Name Maya Kirova

Designer Name

Requires approval from

  • Svilen Dimchevski | Date: 10 August, 2022
  • Konstantin Dinev | Date:
  • Stamen Stoychev | Date: 09 August, 2022
  • Deyan Kamburov | Date: 09 August, 2022

Signed off by

  • Radoslav Mirchev Name | Date:
  • Damyan Petev | Date:

Revision History

Version Users Date Notes
1 Maya Kirova 11/07/2022 Initial Draft
2 Svilen Dimchevski 21/07/2022 Updated Functionality section
3 Maya Kirova 03/08/2022 Update and polish specification

Objectives

igxGrid should allow validating user input when editing cells/rows.

Should extend Angular's reactive forms validation functionality to allow easier extensibility and maintainability.

Should show visual indicators (like error message, error styles etc.) when a cell/row enters invalid state.

Should have an option to prevent editing from continuing in case of invalid input.

End-to-end user experience prototype

Acceptance criteria

  1. Should allow defining declaratively the default angular supported validators on the igx-column components. For example:
<igx-column required ...>

These should then be used for cell validation.

  1. Should expose the generated FormGroup for the edited row/cell so that it can be customized by the user.

  2. Should allow customizing the error's.

Developer stories:

As a developer, I want to be able to:

  • declaratively set Angular's forms validators on the columns of the grid, so that I can validate the related cells on edit.
  • set my own custom validator, so that I can validate according to my business requirements.
  • customize the error messages.
  • access to the FormGroup used for validation so that I can further customize it.
  • prevent users from leaving edit mode for a cell/row when there are errors.
  • get all invalid values before commit.
  • set the validation trigger that would start validation on my inputs - similar to updateOn.

End-user stories:

  • Story 1: As an end-user, I want to get a descriptive validation message when I enter an invalid value, so that I can fix it.

3.1. Design handoff- https://www.figma.com/file/fmatez7lHAxkXHhybPIhIa/Validation-message?node-id=0%3A1

Validation service

Validation state is managed and stored in a validation service. The service exposed the following public apis:

  • valid - returns if current state is valid.
  • getInvalid - returns just the invalid record states.
  • markAsTouched - marks the related record/field as touched.
  • clear - clears the validity states.

Related public interfaces are as follows:

export interface IRecordValidationState {
    id: any;
    valid: boolean;
    state: IFieldValidationState[];
}

export interface IFieldValidationState {
    field: string,
    valid: boolean,
    errors: ValidationErrors
}

Validity is updated when editing rows/cells via the UI or via the api. However errors will be shown only if the row/cell has been touched by the user (via user interaction with the editor) or if it is manually marked as touched via the markAsTouched API.

Only exception is the adding row, where all cell will be marked as touched when the row is added.

When global grid validity changes from valid to invalid or vice versa the validationStatusChange event of grid will be emitted with the new state.

Integration Scenarios

Editing

  • Batch editing

When batch editing is enabled transactions can modify the grid state using the undo/redo API.

In those case validation state will update accordingly. Validation will re-trigger on the new value and the new state will be reflected in the validation service.

  • Submitting invalid values

It is up to the developer on application level to decide whether to allow invalid values to be submitted into the grid.

  • If no invalid values should be allowed to be entered in the data/transactions then the developer can cancel the cellEdit, rowEdit events to prevent the grid from entering an invalid state.

  • In case the developer would like to handle the invalid records himself he can do so via the getInvalid API from the grid.validation object. He can collect the invalid record information and decide how to proceed - whether to clear them, propt the user to fix them, allow commiting them etc., depending on the use case.

3.2. Developer Experience

3.2.1 Configuration

  • Validating via template-driven configuration

You can use the predefined angular forms validators declaratively on the igx-columns to enable validation for the related cells while editing:

<igx-column required minlength="4" ...>

These will then be injected for the cell when edit and used for validation.

The following will be supported out of the box, as we will extend the base angular directives to work on the igx-column:

  • required
  • min
  • max
  • email
  • minlength
  • maxlength
  • pattern

You can also defined your own custom directive that extends the column validator directive, for example:

  @Directive({
    selector: '[appForbiddenName]',
    providers: [{provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true}]
  })
  export class ForbiddenValidatorDirective extends Validators {
    @Input('appForbiddenName') 
    public forbiddenName = '';
  
    validate(control: AbstractControl): ValidationErrors | null {
      return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, 'i'))(control)
                                : null;
    }
  }

And use this in the column template:

<igx-column appForbiddenName='bob' ...>
  • Validating in reactive forms

We also expose the FormGroup that will be used for validation when editing starts on a row/cell via a formGroupCreated event. You can add validators to it for the related fields:

<igx-grid (formGroupCreated)='formCreateHandler($event)' ...>
public formCreateHandler(formGr: FormGroup) {
  // add a validator
  const prodName = formGr.get('UserName');
  prodName.addValidators(forbiddenNameValidator(/bob/i))
}

3.2.2 Customizing errors

The editing template can be modified with a custom one per column, for example:

<igx-column ... >
  <ng-template igxCellValidationError let-cell='cell'>
    <div *ngIf="cell.errors?.['forbiddenName']">
      This name is forbidden.
    </div>
  </ng-template>
</igx-column>

3.2.3 Prevent edit end when input is invalid

The editCell/editRow events can be canceled in case the isValid argument is false.

<igx-grid (cellEdit)='cellEdit($event)' ...>
public cellEdit(evt) {
  if (!evt.valid) {
    evt.cancel = true;
  }
}

In that case the cell will remain in edit mode until a valid value is set.

3.2.3 Customizing the validation trigger.

The validation trigger can be set via the validationTrigger property:

<igx-grid #grid validationTrigger='blur'></igx-grid>

Valid values are change, blur.

3.3. Globalization/Localization

Default errors originating from the predefined angular forms validators that are set on the columns will have a default error message (i.e. required - This field is required.)

Default error message strings will need to be localized.

3.4. Keyboard Navigation

Keys Description

3.5. API

Grid

Options

Name Description Type Default value Valid values
validationTrigger Gets/Sets the trigger for validators used when editing the grid. GridValidationTrigger change 'change' , 'blur'

Events

Name Description Cancelable Parameters
formGroupCreated Event emitted when validation form group is created for an edited row/cell. Emits the form group that with the form controls that will be used for validation. false FormGroup
validationStatusChange Event emitted when validation status changes from valid to invalid or vice versa false Validity

Validation service

Properties

Name Description Return type
valid Returns whether current state is valid. boolean

Methods

Name Description Return type Parameters
getInvalid Returns all invalid record states. IRecordValidationState[]
markAsTouched Marks the associated record or field as touched. void id: any, field?: string
clear Clears validity state by id or clears all states if no id is passed. void id?:any

Automation

Basic
  • should allow setting built-in validators via template-driven configuration on the <igx-column>.
  • should allow setting custom validator via template-driven configuration on the <igx-column>.
  • should allow setting validators on the exposed FormGroup object.
  • should allow setting validation triggers - 'change' , 'blur'.
  • should mark invalid cell with igx-grid__td--invalid class and show the related error cell template.
  • should show the error message on error icon hover and when the invalid cell becomes active.
  • should allow customizing the error message template.
  • should allow preventing edit mode for cell/row to end by canceling the related event if isValid event argument is false.
  • should trigger the validationStatusChange event on grid when validation status changes.
  • should return invalid record states using getInvalid api.
  • should allow clearing validation states via clear api.
  • should apply aria attributes aria-invalid, aria-errormessage to cell and editor when cell is invalid.

Integration

  • should update validity state but should not show error message when setting new values via grid api(updateRow, updateCell).
Batch editing
  • should update validity states on transaction's undo/redo api.
  • should not show error if record with invalid state is deleted.

ARIA Support

When the cell becomes invalid the following attributes are applied to it:

  • aria-invalid - set to true.
  • aria-errormessage - set to the error message tooltip id that contains details on the error.
Assumptions Limitation Notes
Clone this wiki locally