Skip to content

Commit 54a9e5e

Browse files
wanghoppehoppe
andauthored
parent form should trigger subform validate event (#2820)
Co-authored-by: hoppe <[email protected]>
1 parent f98e158 commit 54a9e5e

File tree

4 files changed

+58
-41
lines changed

4 files changed

+58
-41
lines changed

packages/bonito-core/src/form/__tests__/form.spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,33 @@ describe("Form tests", () => {
528528
expect(validationStatus).toBe(form.validationStatus);
529529
});
530530

531+
test("Subform validate event", async () => {
532+
type HelloWorldFormValues = {
533+
message: string;
534+
};
535+
536+
const form = createForm<HelloWorldFormValues>({
537+
values: {
538+
message: "Hello world!",
539+
},
540+
});
541+
542+
const parentForm = createForm({
543+
values: {
544+
child: {},
545+
},
546+
});
547+
548+
parentForm.subForm("child", form);
549+
550+
const validateSpy = jest.fn();
551+
form.on("validate", validateSpy);
552+
parentForm.validate();
553+
expect(validateSpy).toHaveBeenCalled();
554+
await parentForm.waitForValidation();
555+
expect(validateSpy).toHaveBeenCalledTimes(2);
556+
});
557+
531558
test("Events", () => {
532559
type ElfType = {
533560
name: string;

packages/bonito-core/src/form/form.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -129,24 +129,6 @@ export interface Form<V extends FormValues> {
129129
*/
130130
validate(opts?: ValidationOpts): Promise<ValidationSnapshot<V>>;
131131

132-
/**
133-
* Perform synchronous validation
134-
* @param opts Validation options
135-
*/
136-
validateSync(
137-
snapshot: ValidationSnapshot<V>,
138-
opts: ValidationOpts
139-
): ValidationSnapshot<V>;
140-
141-
/**
142-
* Perform asynchronous validation
143-
* @param opts Validation options
144-
*/
145-
validateAsync(
146-
snapshot: ValidationSnapshot<V>,
147-
opts: ValidationOpts
148-
): Promise<ValidationSnapshot<V>>;
149-
150132
/**
151133
* Returns a promise that resolves when any current form validation is
152134
* finished. If there is no validation in progress, returns a promise which

packages/bonito-core/src/form/internal/form-impl.ts

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,6 @@ export class FormImpl<V extends FormValues> implements Form<V> {
296296
this._validationSnapshot = snapshot;
297297
this.validateSync(snapshot, opts);
298298

299-
// Fire a validation event to allow updates after synchronous
300-
// validation to happen immediately
301-
this._emitValidateEvent(snapshot);
302-
303299
// Yield before doing any async validation to check if another validation
304300
// attempt has come in.
305301
let delayMs = 0;
@@ -320,26 +316,13 @@ export class FormImpl<V extends FormValues> implements Form<V> {
320316

321317
await this.validateAsync(snapshot, opts);
322318

323-
if (this._checkAndCancelValidationSnapshot(snapshot, opts.force)) {
324-
return snapshot;
325-
}
326-
327-
// This snapshot is done, and is now the current in-effect snapshot
328-
snapshot.validationCompleteDeferred.resolve();
329-
snapshot.updateOverallStatus();
330-
this._validationSnapshot = snapshot;
331-
332-
this._emitValidateEvent(snapshot);
333-
334-
if (!snapshot.overallStatus) {
335-
// Hitting this indicates a bug. This shouldn't ever be undefined
336-
// at this point.
337-
throw new Error("Failed to compute overall validation status");
338-
}
339-
340319
return snapshot;
341320
}
342321

322+
/**
323+
* Perform synchronous validation
324+
* @param opts Validation options
325+
*/
343326
validateSync(
344327
snapshot: ValidationSnapshot<V>,
345328
opts: ValidationOpts
@@ -373,9 +356,17 @@ export class FormImpl<V extends FormValues> implements Form<V> {
373356

374357
snapshot.syncValidationComplete = true;
375358

359+
// Fire a validation event to allow updates after synchronous
360+
// validation to happen immediately
361+
this._emitValidateEvent(snapshot);
362+
376363
return snapshot;
377364
}
378365

366+
/**
367+
* Perform asynchronous validation
368+
* @param opts Validation options
369+
*/
379370
async validateAsync(
380371
snapshot: ValidationSnapshot<V>,
381372
opts: ValidationOpts
@@ -443,6 +434,23 @@ export class FormImpl<V extends FormValues> implements Form<V> {
443434

444435
snapshot.asyncValidationComplete = true;
445436

437+
if (this._checkAndCancelValidationSnapshot(snapshot, opts.force)) {
438+
return snapshot;
439+
}
440+
441+
// This snapshot is done, and is now the current in-effect snapshot
442+
snapshot.validationCompleteDeferred.resolve();
443+
snapshot.updateOverallStatus();
444+
this._validationSnapshot = snapshot;
445+
446+
this._emitValidateEvent(snapshot);
447+
448+
if (!snapshot.overallStatus) {
449+
// Hitting this indicates a bug. This shouldn't ever be undefined
450+
// at this point.
451+
throw new Error("Failed to compute overall validation status");
452+
}
453+
446454
return snapshot;
447455
}
448456

packages/bonito-core/src/form/subform.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,14 @@ export class SubForm<
220220
snapshot: ValidationSnapshot<S>,
221221
opts: ValidationOpts
222222
): ValidationSnapshot<S> {
223-
return this.form.validateSync(snapshot, opts);
223+
return (this.form as FormImpl<S>).validateSync(snapshot, opts);
224224
}
225225

226226
async validateAsync(
227227
snapshot: ValidationSnapshot<S>,
228228
opts: ValidationOpts
229229
): Promise<ValidationSnapshot<S>> {
230-
return this.form.validateAsync(snapshot, opts);
230+
return (this.form as FormImpl<S>).validateAsync(snapshot, opts);
231231
}
232232

233233
forceValidationStatus(status: ValidationStatus): void {

0 commit comments

Comments
 (0)