From 749cbd561cdd7672957e747b2ce13ae53c64f7b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Huaier?= Date: Wed, 19 Apr 2023 14:21:25 -0300 Subject: [PATCH] Add methods for clearing error messages --- docs/reference/Field.md | 8 ++++++++ docs/reference/Form.md | 10 +++++++++- src/Field/index.ts | 5 +++++ src/Form/index.ts | 7 ++++++- tests/Field.test.ts | 38 ++++++++++++++++++++++++++++++++++++++ tests/Form.test.ts | 15 +++++++++++++++ 6 files changed, 81 insertions(+), 2 deletions(-) diff --git a/docs/reference/Field.md b/docs/reference/Field.md index f4b2a0c..170dacd 100644 --- a/docs/reference/Field.md +++ b/docs/reference/Field.md @@ -138,6 +138,14 @@ showError( errorMessage: string ): void Forces the field to show the given error message, overriding whatever `error` was returning. This does not depend on, nor affect at all, the validity state of the field. The method is intended to show errors coming from the backend, with an informative purpose only (for the end user). Ideal for "email already registered" or similar errors. +### clearError + +```ts +clearError(): void +``` + +Clears the error message currently being shown. This will clear errors that came from failed validations as well as errors displayed with the [`showError`](#showError) method. In either case, it doesn't affect the validity state of the field at all. + ### syncError ```ts diff --git a/docs/reference/Form.md b/docs/reference/Form.md index 8dbd7f0..c598064 100644 --- a/docs/reference/Form.md +++ b/docs/reference/Form.md @@ -218,4 +218,12 @@ Resets all the fields (calls [`reset`](Field.md#reset) on each of them). showErrors( errors: Record ): void ``` -This method is like a shortcut for calling `showError` on each field. Basically, for each key-error pair in the given `errors` object, shows the error message in the field identified by the key. Can be useful if the backend returns errors for each field and they can be directly shown on the form. +This method is like a shortcut for calling [`showError`](Field.md#showError) on each field. Basically, for each key-error pair in the given `errors` object, shows the error message in the field identified by the key. Can be useful if the backend returns errors for each field and they can be directly shown on the form. + +### clearErrors + +```ts +clearErrors(): void +``` + +Clears error messages for all fields, by calling [`clearError`](Field.md#clearError) on each of them. diff --git a/src/Field/index.ts b/src/Field/index.ts index 837a91e..259f8c3 100644 --- a/src/Field/index.ts +++ b/src/Field/index.ts @@ -34,6 +34,7 @@ export default abstract class Field { reset: action, syncError: action, showError: action, + clearError: action, attachToForm: action } ); } @@ -84,6 +85,10 @@ export default abstract class Field { this._presentedError = errorMessage; } + clearError() { + this.showError( '' ); + } + attachToForm( form: Form ) { this._state.attachToForm( form ); } diff --git a/src/Form/index.ts b/src/Form/index.ts index 22a2197..29962a9 100644 --- a/src/Form/index.ts +++ b/src/Form/index.ts @@ -38,7 +38,8 @@ export default class Form { submit: action, clear: action, reset: action, - showErrors: action + showErrors: action, + clearErrors: action } ); } @@ -105,6 +106,10 @@ export default class Form { forEach( errors, ( error, fieldKey ) => this.showErrorOnField( fieldKey, error ) ); } + clearErrors() { + this.eachField( field => field.clearError() ); + } + private attachFields() { forEach( this._fields, field => field.attachToForm( this ) ); } diff --git a/tests/Field.test.ts b/tests/Field.test.ts index 65f284b..22a140f 100644 --- a/tests/Field.test.ts +++ b/tests/Field.test.ts @@ -25,6 +25,8 @@ describe( 'Field', () => { ...params } ); + const createInvalidField = () => createField( { value: 'Too loong' } ); + describe( 'constructor', () => { it( 'assigns the given attributes to the field', () => { const field = createField(); @@ -244,6 +246,42 @@ describe( 'Field', () => { } ); } ); + describe( '@clearError', () => { + describe( 'when no error is being shown', () => { + it( 'does not show any error', () => { + const field = createInvalidField(); + + field.clearError(); + + expect( field.error ).toEqual( '' ); + } ); + } ); + + describe( 'when an error is being shown', () => { + describe( 'and it was manually set', () => { + it( 'hides the error', () => { + const field = createField(); + + field.showError( 'Something went wrong' ); + field.clearError(); + + expect( field.error ).toBe( '' ); + } ); + } ); + + describe( 'and it comes from a failed validation', () => { + it( 'hides the error', () => { + const field = createInvalidField(); + + field.syncError(); + field.clearError(); + + expect( field.error ).toBe( '' ); + } ); + } ); + } ); + } ); + describe( '@attachToForm', () => { const createAndAttachField = () => { const validator = jest.fn( diff --git a/tests/Form.test.ts b/tests/Form.test.ts index e026926..d480e1f 100644 --- a/tests/Form.test.ts +++ b/tests/Form.test.ts @@ -435,4 +435,19 @@ describe( 'Form', () => { expect( () => form.showErrors( { age: 'Invalid' } ) ).not.toThrow(); } ); } ); + + describe( '@clearErrors', () => { + it( 'clears the error messages on all fields', () => { + const form = createForm(); + + form.submit(); // Form is invalid, so error messages will show up + form.showErrors( { email: 'This email has a problem' } ); + + form.clearErrors(); + + form.eachField( ( field ) => { + expect( field.error ).toEqual( '' ); + } ); + } ); + } ); } );