@@ -30,6 +30,17 @@ export interface FormChangeEvent {
30
30
changed : boolean ;
31
31
}
32
32
33
+ export interface FormValidateEvent {
34
+ /**
35
+ * The current values of the form fields.
36
+ */
37
+ value : FormValuesData ;
38
+ /**
39
+ * Validation errors
40
+ */
41
+ errors ?: Array < FormValidationError > ;
42
+ }
43
+
33
44
export interface FormValuesData {
34
45
[ name : string ] : any ;
35
46
}
@@ -65,6 +76,10 @@ export interface FormProps<FormValues> extends StandardProps {
65
76
* Event emitted when the form is submitted.
66
77
*/
67
78
onSubmit ?( e : FormSubmitEvent ) : void ;
79
+ /**
80
+ * Event emitted when form errors are set or cleared
81
+ */
82
+ onValidate ?( e : FormValidateEvent ) : void ;
68
83
/**
69
84
* Disables the form in case of invalid input. Effectively
70
85
* disables the possibility of submitting forms.
@@ -159,6 +174,26 @@ export class Form<Values extends FormValuesData> extends React.Component<FormPro
159
174
}
160
175
}
161
176
177
+ componentDidUpdate ( _ : FormProps < Values > , prevState : FormState < Values > ) {
178
+ const { onValidate } = this . props ;
179
+ const { errors, current } = this . state ;
180
+
181
+ if ( typeof onValidate === 'function' && JSON . stringify ( prevState . errors ) !== JSON . stringify ( errors ) ) {
182
+ const arrayErrors = this . getErrorsAsArray ( errors ) ;
183
+ onValidate ( { errors : arrayErrors , value : current } ) ;
184
+ }
185
+ }
186
+
187
+ private getErrorsAsArray ( errors : FormState < Values > [ 'errors' ] ) {
188
+ return Object . keys ( errors ) . reduce < Array < FormValidationError > > ( ( arrayErrors , field ) => {
189
+ const error = errors [ field ] ;
190
+ if ( error ) {
191
+ arrayErrors . push ( { field, error } ) ;
192
+ }
193
+ return arrayErrors ;
194
+ } , [ ] ) ;
195
+ }
196
+
162
197
private setValues ( current : Values , changed : boolean ) {
163
198
const keys = Object . keys ( current ) ;
164
199
@@ -248,7 +283,7 @@ export class Form<Values extends FormValuesData> extends React.Component<FormPro
248
283
if ( name ) {
249
284
this . fields . push ( field ) ;
250
285
251
- let error ;
286
+ let error : React . ReactChild | undefined ;
252
287
if ( name in current ) {
253
288
const value = current [ name ] ;
254
289
error = this . getError ( name , value ) ;
@@ -262,7 +297,7 @@ export class Form<Values extends FormValuesData> extends React.Component<FormPro
262
297
}
263
298
264
299
if ( error ) {
265
- this . setState ( { errors : { ...errors , [ name ] : error } as FormState < Values > [ 'errors' ] } ) ;
300
+ this . setState ( ( { errors } ) => ( { errors : { ...errors , [ name ] : error } } ) ) ;
266
301
}
267
302
}
268
303
} ,
@@ -280,13 +315,7 @@ export class Form<Values extends FormValuesData> extends React.Component<FormPro
280
315
this . setErrors ( current ) ;
281
316
282
317
if ( ! disabled && typeof onSubmit === 'function' ) {
283
- const arrayErrors = Object . keys ( errors ) . reduce < Array < FormValidationError > > ( ( arrayErrors , field ) => {
284
- const error = errors [ field ] ;
285
- if ( error ) {
286
- arrayErrors . push ( { field, error } ) ;
287
- }
288
- return arrayErrors ;
289
- } , [ ] ) ;
318
+ const arrayErrors = this . getErrorsAsArray ( errors ) ;
290
319
291
320
this . setState (
292
321
{
0 commit comments