form
form copied to clipboard
canSubmit in form is true even if some fields are unvalid
In your own example: https://codesandbox.io/s/react-form-custom-select-multi-select-inputs-6962t
The canSubmit is true
even before the two colors in the multiselect have been set. As long as the single select have been set, it's all good.
Is this expected?
As of right now, this is by design. I’ll look into the why ASAP and how we could make it better.
Tanner Linsley On Nov 19, 2019, 3:23 AM -0700, Anders Hallundbæk [email protected], wrote:
In your own example: https://codesandbox.io/s/react-form-custom-select-multi-select-inputs-6962t The canSubmit is true even before the two colors in the multiselect have been set. As long as the single select have been set, it's all good. Is this expected? — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.
This is an issue for me as well, this needs to be fixed ASAP. Thanks.
Any fix for this?? My buttons are all active even if an error occurred after validation, not healthy. Please fix this.
Hi, experiencing issues with this as well. I was expecting isValid
to remain false
until all fields were valid (using fields with validatePristine
enabled). I noticed it seems to return true
just on the 2nd render. All other renders receive the expected value (false
).
Edit: I took a closer look... this is how it behaves:
- field is validating
- field is done validating and no error is set, but it should be! Form now says its valid:
!fieldsAreValidating && fieldsAreValid && !meta.error
- field now shows an error
As from today, it's still an issue. Essentially canSubmit
lies 🤥 . I have resolved from my side by doing like this 1️⃣ :
<div className="mt-5 place-self-center md:col-span-2">
<formAPI.Subscribe
selector={(state) => state}
children={(state) => (
<SubmitButton isValid={validateFieldMeta(state.fieldMeta)} />
)}
/>
And, here is my utility function to do the full validation before 'activating' SubmitButton
:
import { type FieldMeta } from '@tanstack/react-form';
export function validateFieldMeta(
fieldMeta: Record<string, FieldMeta>,
): boolean {
return Object.values(fieldMeta).every(({ isTouched, touchedErrors }) => {
return isTouched && touchedErrors.length === 0;
});
}
And, some tests ✅ for the same:
describe('validateFieldMeta', () => {
it('returns false if all fields are not touched', () => {
const input = {
name: {
isValidating: false,
isTouched: true,
touchedErrors: [],
errors: [],
errorMap: {},
},
email: {
isValidating: false,
isTouched: true,
touchedErrors: [],
errors: [],
errorMap: {},
},
help: {
isValidating: false,
isTouched: false,
touchedErrors: [],
errors: [],
errorMap: {},
},
};
const expected = false;
const actual = validateFieldMeta(input);
expect(actual).toBe(expected);
});
it('returns false if all fields are touched but at least one has errors', () => {
const input = {
name: {
isValidating: false,
isTouched: true,
touchedErrors: [],
errors: [],
errorMap: {},
},
email: {
isValidating: false,
isTouched: true,
touchedErrors: [],
errors: [],
errorMap: {},
},
help: {
isValidating: false,
isTouched: true,
touchedErrors: ['Some error'], // Field with error
errors: [],
errorMap: {},
},
};
const expected = false;
const actual = validateFieldMeta(input);
expect(actual).toBe(expected);
});
it('returns true if all fields are touched and have no errors', () => {
const input = {
name: {
isValidating: false,
isTouched: true,
touchedErrors: [],
errors: [],
errorMap: {},
},
email: {
isValidating: false,
isTouched: true,
touchedErrors: [],
errors: [],
errorMap: {},
},
help: {
isValidating: false,
isTouched: true,
touchedErrors: [],
errors: [],
errorMap: {},
},
};
const expected = true;
const actual = validateFieldMeta(input);
expect(actual).toBe(expected);
});
});
Only minor issue now is that whenever we use the browser's autocomplete
features, without actually clickng 🐭 and typing ⌨️ it doesn't register as being isTouched
.
When first rendered, the onUpdate function is called and even if the default state canSubmit is set to false, the statement (image below) is always true and sets canSubmit to true :
@t-rosa @manavm1990 please open a new issue with a StackBlitz link or similar. This ticket is specific for the legacy codebase, not the new codebase you're reporting an issue on