T
TanStack2w ago
wee-brown

Field level validation possible?

Field level validation possible? I'm working on an webapp with many forms and many types of input. If I have a input field <AgeInputField/>, I want to do the input validation inside this component, not on the form level. All manuals I've found, assume the validation is on the form level: you have to add all validations in each form. Is there no way to do this on the input field level? This is not a rare use case, right? So I have a field like this export function IdFormField() { const field = useFieldContext<string>(); // Add validation function here return <div className={styles.inputLine}> <TextField label="Id" value={field.state.value} onChange={(event) => field.handleChange(event.target.value)} /> </div>; } Then, in my form: <form.AppField name="id"> {(field) => <field.IdField/>} </form.AppField> I see there are functions like field.pushValue() and field.setErrorMap(), but they're poorly documented and I can't find how to use them. An alternative solution would be to pass form to the input field component. I'm developing with TypeScript, and to pass form properly typed, I have to use AppFieldExtendedReactFormApi<> with 14 (fourteen!) generic parameters. I tried to use broad types, but couldn't make the types correct. In short: Where can I find documentation about the fieldAPI? So, the API as listed here: https://tanstack.com/form/v1/docs/reference/classes/fieldapi but with explanations, examples etcetera. And if that's not possible, how can I pass form well typed to a component?
6 Replies
fascinating-indigo
fascinating-indigo2w ago
so you want to have a preset field that has only field level validation ready, and many forms should be able to use it? withFieldGroup could be a solution to that. It allows you to write sections of forms so that multiple forms may use them the thing is that when you do field level validators, it would not be
<form.AppField name="id">
{(field) => <field.IdField validators={}/>}
</form.AppField>
<form.AppField name="id">
{(field) => <field.IdField validators={}/>}
</form.AppField>
but instead
<form.AppField name="id" validators={}>
{(field) => <field.IdField />}
</form.AppField>
<form.AppField name="id" validators={}>
{(field) => <field.IdField />}
</form.AppField>
wee-brown
wee-brownOP2w ago
I thought withFieldGroup was specifically to let multiple fields "talk" to each other. But you can also use it for a single input field. I'll use this. Thanks!
fascinating-indigo
fascinating-indigo2w ago
yes, because that's the most common logic that has to be associated with fields that you don't want to repeat too often but field validation is another case for it
wee-brown
wee-brownOP2d ago
Thanks for your answer. Is it also possible to pass a string instead of an object? const defaultValues: FormValues = { name: "", age: 0, account_data: { password: "", confirm_password: "", }, }; It seems withFieldGroup can only deal with account_data and not with name. My form data is just an object with key: values . Do I have to write a conversion function (and convert back function) for withFieldGroup to work?
fascinating-indigo
fascinating-indigo2d ago
a string is a shorthand for all shallow keys starting with the string so in this case, account_data as string would just be account_data.password and account_data.confirm_password if you want to allow strings for your field group, you can put them into a namespace
wee-brown
wee-brownOP2d ago
Oh, I meant the other way around. This is the example from the documentation: const defaultValues: FormValues = { name: "", age: 0, account_data: { password: "", confirm_password: "", }, }; But my data looks like this: const defaultValues: FormValues = { name: "", age: 0, password: "", confirm_password: "", }; But is seems withFieldGroup only accepts an object like account_data: { password: "", confirm_password: "", }, and not a top level property.

Did you find this page helpful?