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?9 Replies
equal-jade•3mo 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
but instead
evident-indigoOP•3mo 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!
equal-jade•3mo 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
evident-indigoOP•2mo 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?equal-jade•2mo 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 namespaceevident-indigoOP•2mo 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.
Argh, I just discovered another problem: the property name (like "password") in the field component must be the same as the property name in the form. But I want to make them independentequal-jade•2mo ago
if
account_data isn't an object that you expect to receive (because it could be called anything), then you should push those fields to the top level instead
evident-indigoOP•2mo ago
I found that assigning an object to
fields solves my problem. Thanks for your help.equal-jade•2mo ago
in case you need to check for the future: