Skip to content

Commit

Permalink
feature: preserve validation error between updates config flag
Browse files Browse the repository at this point in the history
  • Loading branch information
hala94 committed Dec 31, 2023
1 parent c771ee4 commit c1b0667
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 8 deletions.
6 changes: 6 additions & 0 deletions .changeset/lucky-coats-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@formeus/core": minor
"docs": minor
---

preserveValidationErrorOnUpdate configuration flag added
7 changes: 0 additions & 7 deletions apps/docs/pages/docs/reference/createForm.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,6 @@ Returning a promise from this function makes returned `isSubmitting` value `true

### `config`

```js
type FormConfig = {
autoValidate?: boolean
validateConcurrentlyOnSubmit?: boolean
}
```

Configuration options for the current form.

Overrides global config if set.
Expand Down
7 changes: 7 additions & 0 deletions apps/docs/pages/docs/reference/setFormConfig.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const form = createForm({
type FormConfig = {
autoValidate?: boolean,
validateConcurrentlyOnSubmit?: boolean,
preserveValidationErrorOnUpdate?: boolean,
}
```

Expand All @@ -42,3 +43,9 @@ When set to `true`, calling the `submit` method will trigger concurrent validati

Default is `false`, and calling the `submit` method triggers sequential validation of your form fields, stopping
if any validation fails.

### `preserveValidationErrorOnUpdate`

When set to `true`, field validation errors will be preserved after updates.

Default is `false`, and updating the field value will clear its validation error.
4 changes: 3 additions & 1 deletion packages/form-core/src/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ export function createForm<
newValidations = {
...newValidations,
[key]: {
error: undefined,
error: config.preserveValidationErrorOnUpdate
? validations[key].error
: undefined,
checked: false,
validating: false,
} as ValidationState,
Expand Down
1 change: 1 addition & 0 deletions packages/form-core/src/formConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { FormConfig } from "./types"
let staticConfig: FormConfig = {
autoValidate: false,
validateConcurrentlyOnSubmit: false,
preserveValidationErrorOnUpdate: false,
}

export function setFormConfig(config: FormConfig) {
Expand Down
67 changes: 67 additions & 0 deletions packages/form-core/src/tests/form.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,73 @@ describe("form", () => {
})
})

it("field validation error is cleared after update", async () => {
const form = createForm({
initial: {
email: "",
},
validators: {
...createClientValidator("failing", "email"),
},
})

const snapshot1 = form.getSnapshot()
snapshot1.runValidation("email")

const snapshot2 = form.getSnapshot()

expect(snapshot2.validations.email).toStrictEqual({
checked: true,
error: new Error("email invalid"),
validating: false,
})

snapshot2.update("email", "newInvalidMail")

const snapshot3 = form.getSnapshot()

expect(snapshot3.validations.email).toStrictEqual({
checked: false,
error: undefined,
validating: false,
})
})

it("field validation error is not cleared after update if flag is set", async () => {
const form = createForm({
initial: {
email: "",
},
validators: {
...createClientValidator("failing", "email"),
},
config: {
preserveValidationErrorOnUpdate: true,
},
})

const snapshot1 = form.getSnapshot()
snapshot1.runValidation("email")

const snapshot2 = form.getSnapshot()

expect(snapshot2.validations.email).toStrictEqual({
checked: true,
error: new Error("email invalid"),
validating: false,
})

snapshot2.update("email", "newInvalidMail")

const snapshot3 = form.getSnapshot()

expect(snapshot3.validations.email).toStrictEqual({
checked: false,
error: new Error("email invalid"),
validating: false,
})
})

it("has correct state after running server validations", async () => {
const initial = {
email: "",
Expand Down
10 changes: 10 additions & 0 deletions packages/form-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,14 @@ export type FormConfig = {
* Default is `false`.
*/
validateConcurrentlyOnSubmit?: boolean
/**
* `true` - If form field had a validation error, updating that field will preserve the validation error.
*
* `false` - Form field validation error is cleared when that field is updated.
*
* This doesn't affect validation logic and result in any way, it controls the preserving of error state between updates.
*
* Default is `false`.
*/
preserveValidationErrorOnUpdate?: boolean
}

0 comments on commit c1b0667

Please sign in to comment.