handleChange / handleBlur resets validation errors
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6.7k
- Forks
- 682
- Avg merge
- 5d 18h
- Merged PRs (30d)
- 7
Description
Describe the bug
We currently using this form library, but we have 0 client side / JS form validation. All of this happens server side in an Rails application. When submitting the form, we check for any server side form validation errors and set them like suggested. But the library resets the validation errors upon blur/change which is unfortunate as the errors should persist until next submit for UX and accessibility concerns.
Our way to circumvent this is not gonna work if #1526 is fixed/implemented.
Screen recording of the errors being reset:
https://github.com/user-attachments/assets/a6b77c56-2931-4142-8ebe-6218b33a354e
Screen recording with our temporary solution:
https://github.com/user-attachments/assets/22ed10c5-7d2e-49d4-a477-da325340591c
Your minimal, reproducible example
https://stackblitz.com/edit/vitejs-vite-nevftfj5?file=src%2FApp.vue
Steps to reproduce
Setup a form, with no validation besides an async submit that can se the errors:
useForm({
defaultValues,
canSubmitWhenInvalid: true,
validators: {
onSubmitAsync: async ({ value }) => {
try {
// Call API
} catch (error) {
if (isValidationFailedResponseError(error)) {
// Return formatted errors like this:
return { fields: { systolic: ["Field is required", "Must be a number"] } };
}
if (isRequestError(error) || isResponseError(error)) {
return { form: error.message };
}
throw error;
}
}
}
});
Then in the layout we had this:
<form.Field v-slot="{ field }" name="systolic">
<input
:name="field.name"
type="number"
class="form-control"
:value="field.state.value"
placeholder="Systolic mmHg"
@blur="() => field.handleBlur()"
@input="(event) => field.handleChange(event.target.valueAsNumber)"
/>
<FieldErrors :errors="field.state.meta.errors" />
</form.Field>
But it would reset the form errors whenever we blurred the field or changed the input value. We currently switched it to:
<form.Field v-slot="{ field }" name="systolic">
<input
:name="field.name"
type="number"
class="form-control"
:value="field.state.value"
placeholder="Systolic mmHg"
@input="(event) => form.setFieldValue(field.name, event.target.valueAsNumber)"
/>
<FieldErrors :errors="field.state.meta.errors" />
</form.Field>
This works like we want it to, but the form is not aware of blur events and any other state changes the 2 field handlers do.
Expected behavior
When no validation hooks are given (either form level or field level) the library shouldn't reset the existing / previous error map. Or else it could also be implemented as an option in the library?
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
- MacOS
- Chrome 136.0.7103.114 (Official version) (arm64)
TanStack Form adapter
vue-form
TanStack Form version
v1.11.2
TypeScript version
v5.8.3
Additional context
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Vue adapter's useForm flow and the field.handleBlur/handleChange paths shown in the issue, using the linked StackBlitz reproduction. Check how onSubmitAsync returns field errors when no field validators are configured, and verify that those errors remain visible across blur and change until the next submit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100