From 8fd0b76f7c1ee3aa8ce4c5c812e455346b42342f Mon Sep 17 00:00:00 2001
From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com>
Date: Thu, 17 Apr 2025 23:41:33 +0200
Subject: [PATCH 1/8] docs: expand submission handling in react guides
---
.../react/guides/submission-handling.md | 56 ++++++++++++++-----
docs/framework/react/guides/validation.md | 15 ++++-
2 files changed, 55 insertions(+), 16 deletions(-)
diff --git a/docs/framework/react/guides/submission-handling.md b/docs/framework/react/guides/submission-handling.md
index bc99f2a17..de7601571 100644
--- a/docs/framework/react/guides/submission-handling.md
+++ b/docs/framework/react/guides/submission-handling.md
@@ -3,38 +3,68 @@ id: submission-handling
title: Submission handling
---
-In a situation where you want to have multiple form submission types, for example, a form that has a button that navigates to a sub-form and another button that handles a standard submission, you can make use of the onSubmitMeta prop and the handleSubmit function overloads.
+## Passing additional data to submission handling
-## Basic Usage
+You may want to pass additional information to your submission handler, for example, which section to navigate to.
+To pass meta data to `onSubmit`, you can make use of the `onSubmitMeta` property.
-First you must define the default state of the form.onSubmitMeta prop:
+> Note: if `form.handleSubmit()` is called without metadata, it will use the provided default.
```tsx
const form = useForm({
defaultValues: {
firstName: 'Rick',
},
- // {} is the default value passed to `onSubmit`'s `meta` property
- onSubmitMeta: {} as { lastName: string },
+ // Specify what values to use as default if no meta is passed
+ onSubmitMeta: { lastName: 'The default value if no submit Meta is passed' },
onSubmit: async ({ value, meta }) => {
// Do something with the values passed via handleSubmit
- console.log(`${value.firstName} - ${meta}`)
+ console.log(`${value.firstName} - ${meta.lastName}`)
},
})
-```
-
-Note: the default state of onSubmitMeta is `never`, so if the prop is not provided and you try to access it in `handleSubmit`, or `onSubmit` it will error.
-
-Then when you call `onSubmit` you can provide it the predefined meta like so:
-```tsx
+>
+ {/* ... */}
+
+```
+
+## Transforming data with Standard Schemas
+
+While Tanstack Form provides Standard Schema support for validation, it does not preserve the Schema's output data.
+
+The value passed to the `onSubmit` function will always be the input data. To receive the output data of a Standard Schema, parse it in the `onSubmit` function:
+
+```tsx
+const schema = z.object({
+ age: z.string().transform((age) => Number(age)),
+})
+
+// Tanstack form uses the input type of Standard Schemas
+const defaultValues: z.input = {
+ age: '13',
+}
+
+const form = useForm({
+ defaultValues,
+ validators: {
+ onChange: schema,
+ },
+ onSubmit: ({ value }) => {
+ const inputAge: string = value.age
+ // Pass it through the schema to get the transformed value
+ const result = schema.parse(value)
+ const outputAge: number = result.age
+ },
+})
```
diff --git a/docs/framework/react/guides/validation.md b/docs/framework/react/guides/validation.md
index 777f03306..0ddb8a5c4 100644
--- a/docs/framework/react/guides/validation.md
+++ b/docs/framework/react/guides/validation.md
@@ -227,16 +227,23 @@ export default function App() {
const form = useForm({
defaultValues: {
age: 0,
+ socials: [],
+ details: {
+ email: '',
+ },
},
validators: {
onSubmitAsync: async ({ value }) => {
- // Verify the age on the server
- const isOlderThan13 = await verifyAgeOnServer(value.age)
- if (!isOlderThan13) {
+ // Validate the value on the server
+ const hasErrors = await verifyDataOnServer(value)
+ if (hasErrors) {
return {
form: 'Invalid data', // The `form` key is optional
fields: {
age: 'Must be 13 or older to sign',
+ // Set errors on nested fields with the field's name
+ 'socials[0].url': 'The provided URL does not exist'
+ 'details.email': 'An email is required',
},
}
}
@@ -450,6 +457,8 @@ TanStack Form natively supports all libraries following the [Standard Schema spe
_Note:_ make sure to use the latest version of the schema libraries as older versions might not support Standard Schema yet.
+> Validation will not provide you with transformed values. See [submission handling](./submission-handling.md) for more information.
+
To use schemas from these libraries you can pass them to the `validators` props as you would do with a custom function:
```tsx
From 29810425e1e4806e422e68cb88eb1e763f9e0eaf Mon Sep 17 00:00:00 2001
From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com>
Date: Fri, 18 Apr 2025 08:03:47 +0200
Subject: [PATCH 2/8] docs: update vue validation/submission handling pages
---
docs/framework/react/guides/validation.md | 2 +-
.../vue/guides/submission-handling.md | 82 +++++++++++++++++
docs/framework/vue/guides/validation.md | 87 +++++++++++++++++++
3 files changed, 170 insertions(+), 1 deletion(-)
create mode 100644 docs/framework/vue/guides/submission-handling.md
diff --git a/docs/framework/react/guides/validation.md b/docs/framework/react/guides/validation.md
index 0ddb8a5c4..be0ff3fc9 100644
--- a/docs/framework/react/guides/validation.md
+++ b/docs/framework/react/guides/validation.md
@@ -440,7 +440,7 @@ This will debounce every async call with a 500ms delay. You can even override th
/>
```
-> This will run `onChangeAsync` every 1500ms while `onBlurAsync` will run every 500ms.
+This will run `onChangeAsync` every 1500ms while `onBlurAsync` will run every 500ms.
## Validation through Schema Libraries
diff --git a/docs/framework/vue/guides/submission-handling.md b/docs/framework/vue/guides/submission-handling.md
new file mode 100644
index 000000000..fec403eca
--- /dev/null
+++ b/docs/framework/vue/guides/submission-handling.md
@@ -0,0 +1,82 @@
+---
+id: submission-handling
+title: Submission handling
+---
+
+## Passing additional data to submission handling
+
+You may want to pass additional information to your submission handler, for example, which section to navigate to.
+To pass meta data to `onSubmit`, you can make use of the `onSubmitMeta` property.
+
+> Note: if `form.handleSubmit()` is called without metadata, it will use the provided default.
+
+```vue
+
+
+
+
+
+```
+
+## Transforming data with Standard Schemas
+
+While Tanstack Form provides Standard Schema support for validation, it does not preserve the Schema's output data.
+
+The value passed to the `onSubmit` function will always be the input data. To receive the output data of a Standard Schema, parse it in the `onSubmit` function:
+
+```vue
+
+
+
+
+```
diff --git a/docs/framework/vue/guides/validation.md b/docs/framework/vue/guides/validation.md
index 6a9db48fb..50b19674b 100644
--- a/docs/framework/vue/guides/validation.md
+++ b/docs/framework/vue/guides/validation.md
@@ -225,6 +225,91 @@ const formErrorMap = form.useStore((state) => state.errorMap)
```
+### Setting field-level errors from the form's validators
+
+You can set errors on the fields from the form's validators. One common use case for this is validating all the fields on submit by calling a single API endpoint in the form's `onSubmitAsync` validator.
+
+```vue
+
+
+
+
+
+```
+
+> Something worth mentioning is that if you have a form validation function that returns an error, that error may be overwritten by the field-specific validation.
+>
+> This means that:
+>
+> ```vue
+>
+>
+>
+>
+> name="age"
+> :validators="{
+> onChange: ({ value }) => (value % 2 === 0 ? 'Must be odd!' : undefined),
+> }"
+> >
+>
+>
+>
+>
+>
+> ```
+>
+> Will only show `'Must be odd!` even if the 'Too young!' error is returned by the form-level validation.
+
## Asynchronous Functional Validation
While we suspect most validations will be synchronous, there are many instances where a network call or some other async operation would be useful to validate against.
@@ -385,6 +470,8 @@ TanStack Form natively supports all libraries following the [Standard Schema spe
_Note:_ make sure to use the latest version of the schema libraries as older versions might not support Standard Schema yet.
+> Validation will not provide you with transformed values. See [submission handling](./submission-handling.md) for more information.
+
To use schemas from these libraries you can pass them to the `validators` props as you would do with a custom function:
```vue
From beb25a6a4b7a024589f26944faebc7a93944a143 Mon Sep 17 00:00:00 2001
From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com>
Date: Fri, 18 Apr 2025 10:59:27 +0200
Subject: [PATCH 3/8] docs: update solid validation/submission handling page
---
.../react/guides/submission-handling.md | 92 +++++++++----
docs/framework/react/guides/validation.md | 2 +-
.../solid/guides/submission-handling.md | 111 ++++++++++++++++
docs/framework/solid/guides/validation.md | 124 +++++++++++++++++-
.../vue/guides/submission-handling.md | 50 +++++--
docs/framework/vue/guides/validation.md | 24 ++--
6 files changed, 347 insertions(+), 56 deletions(-)
create mode 100644 docs/framework/solid/guides/submission-handling.md
diff --git a/docs/framework/react/guides/submission-handling.md b/docs/framework/react/guides/submission-handling.md
index de7601571..50e70c995 100644
--- a/docs/framework/react/guides/submission-handling.md
+++ b/docs/framework/react/guides/submission-handling.md
@@ -5,43 +5,79 @@ title: Submission handling
## Passing additional data to submission handling
-You may want to pass additional information to your submission handler, for example, which section to navigate to.
-To pass meta data to `onSubmit`, you can make use of the `onSubmitMeta` property.
+You may want to split your long form into multiple sections, for example, when creating a booking form.
+To receive meta data in your `onSubmit` function, you can specify the `onSubmitMeta` property.
> Note: if `form.handleSubmit()` is called without metadata, it will use the provided default.
```tsx
-const form = useForm({
- defaultValues: {
- firstName: 'Rick',
- },
- // Specify what values to use as default if no meta is passed
- onSubmitMeta: { lastName: 'The default value if no submit Meta is passed' },
- onSubmit: async ({ value, meta }) => {
- // Do something with the values passed via handleSubmit
- console.log(`${value.firstName} - ${meta.lastName}`)
- },
-})
+import { useForm } from '@tanstack/react-form'
+
+type FormMeta = {
+ section: 'personalInfo' | 'paymentInfo' | null
+}
+
+// Metadata is not required to call form.handleSubmit().
+// Specify what values to use as default if no meta is passed
+const defaultMeta: FormMeta = {
+ section: null,
+}
-
+ return (
+ <>
+
+
+
+ >
+ )
+}
```
## Transforming data with Standard Schemas
-While Tanstack Form provides Standard Schema support for validation, it does not preserve the Schema's output data.
+While Tanstack Form provides [Standard Schema support](./validation.md) for validation, it does not preserve the Schema's output data.
The value passed to the `onSubmit` function will always be the input data. To receive the output data of a Standard Schema, parse it in the `onSubmit` function:
@@ -50,7 +86,7 @@ const schema = z.object({
age: z.string().transform((age) => Number(age)),
})
-// Tanstack form uses the input type of Standard Schemas
+// Tanstack Form uses the input type of Standard Schemas
const defaultValues: z.input = {
age: '13',
}
diff --git a/docs/framework/react/guides/validation.md b/docs/framework/react/guides/validation.md
index be0ff3fc9..7a0e2d036 100644
--- a/docs/framework/react/guides/validation.md
+++ b/docs/framework/react/guides/validation.md
@@ -242,7 +242,7 @@ export default function App() {
fields: {
age: 'Must be 13 or older to sign',
// Set errors on nested fields with the field's name
- 'socials[0].url': 'The provided URL does not exist'
+ 'socials[0].url': 'The provided URL does not exist',
'details.email': 'An email is required',
},
}
diff --git a/docs/framework/solid/guides/submission-handling.md b/docs/framework/solid/guides/submission-handling.md
new file mode 100644
index 000000000..72dc7812d
--- /dev/null
+++ b/docs/framework/solid/guides/submission-handling.md
@@ -0,0 +1,111 @@
+---
+id: submission-handling
+title: Submission handling
+---
+
+## Passing additional data to submission handling
+
+You may want to split your long form into multiple sections, for example, when creating a booking form.
+To receive meta data in your `onSubmit` function, you can specify the `onSubmitMeta` property.
+
+> Note: if `form.handleSubmit()` is called without metadata, it will use the provided default.
+
+```tsx
+import { createForm } from '@tanstack/solid-form'
+
+type FormMeta = {
+ section: 'personalInfo' | 'paymentInfo' | null
+}
+
+// Metadata is not required to call form.handleSubmit().
+// Specify what values to use as default if no meta is passed
+const defaultMeta: FormMeta = {
+ section: null,
+}
+
+export default function App() {
+ const form = createForm(() => ({
+ defaultValues: {
+ personal: {
+ name: '',
+ email: '',
+ },
+ payment: {
+ address: '',
+ },
+ },
+ // Define what meta values to expect on submission
+ onSubmitMeta: defaultMeta,
+ onSubmit: async ({ value, meta }) => {
+ // Do something with the values passed via handleSubmit
+ console.log(`Selected section - ${meta.section}`, value)
+ },
+ }))
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+```
+
+## Transforming data with Standard Schemas
+
+While Tanstack Form provides [Standard Schema support](./validation.md) for validation, it does not preserve the Schema's output data.
+
+The value passed to the `onSubmit` function will always be the input data. To receive the output data of a Standard Schema, parse it in the `onSubmit` function:
+
+```tsx
+import { createForm } from '@tanstack/solid-form'
+import { z } from 'zod'
+
+// ...
+
+const schema = z.object({
+ age: z.string().transform((age) => Number(age)),
+})
+
+// Tanstack Form uses the input type of Standard Schemas
+const defaultValues: z.input = {
+ age: '13',
+}
+
+const form = createForm(() => ({
+ defaultValues,
+ validators: {
+ onChange: schema,
+ },
+ onSubmit: ({ value }) => {
+ const inputAge: string = value.age
+ // Pass it through the schema to get the transformed value
+ const result = schema.parse(value)
+ const outputAge: number = result.age
+ },
+}))
+```
diff --git a/docs/framework/solid/guides/validation.md b/docs/framework/solid/guides/validation.md
index 6d076e44c..a8588638e 100644
--- a/docs/framework/solid/guides/validation.md
+++ b/docs/framework/solid/guides/validation.md
@@ -218,6 +218,126 @@ export default function App() {
}
```
+### Setting field-level errors from the form's validators
+
+You can set errors on the fields from the form's validators. One common use case for this is validating all the fields on submit by calling a single API endpoint in the form's `onSubmitAsync` validator.
+
+```tsx
+import { Show } from 'solid-js'
+import { createForm } from '@tanstack/solid-form'
+
+export default function App() {
+ const form = createForm(() => ({
+ defaultValues: {
+ age: 0,
+ socials: [],
+ details: {
+ email: '',
+ },
+ },
+ validators: {
+ onSubmitAsync: async ({ value }) => {
+ // Validate the value on the server
+ const hasErrors = await validateDataOnServer(value)
+ if (hasErrors) {
+ return {
+ form: 'Invalid data', // The `form` key is optional
+ fields: {
+ age: 'Must be 13 or older to sign',
+ // Set errors on nested fields with the field's name
+ 'socials[0].url': 'The provided URL does not exist',
+ 'details.email': 'An email is required',
+ },
+ }
+ }
+
+ return null
+ },
+ },
+ }))
+
+ return (
+
+
+ There was an error on the form: {state().errors.join(', ')}
+
+
+
+ )}
+ />
+
+
+ {/*...*/}
+
+
+ )
+}
+```
+
+> Something worth mentioning is that if you have a form validation function that returns an error, that error may be overwritten by the field-specific validation.
+>
+> This means that:
+>
+> ```tsx
+> const form = createForm(() => ({
+> defaultValues: {
+> age: 0,
+> },
+> validators: {
+> onChange: ({ value }) => {
+> return {
+> fields: {
+> age: value.age < 12 ? 'Too young!' : undefined,
+> },
+> };
+> },
+> },
+> }));
+>
+> return (
+> name="age"
+> validators={{
+> onChange: ({ value }) => (value % 2 === 0 ? 'Must be odd!' : undefined),
+> }}
+> children={() => <>{/* ... */}>}
+> />
+> );
+> }
+> ```
+>
+> Will only show `'Must be odd!` even if the 'Too young!' error is returned by the form-level validation.
+
## Asynchronous Functional Validation
While we suspect most validations will be synchronous, there are many instances where a network call or some other async operation would be useful to validate against.
@@ -328,7 +448,7 @@ This will debounce every async call with a 500ms delay. You can even override th
/>
```
-> This will run `onChangeAsync` every 1500ms while `onBlurAsync` will run every 500ms.
+This will run `onChangeAsync` every 1500ms while `onBlurAsync` will run every 500ms.
## Validation through Schema Libraries
@@ -344,6 +464,8 @@ TanStack Form natively supports all libraries following the [Standard Schema spe
_Note:_ make sure to use the latest version of the schema libraries as older versions might not support Standard Schema yet.
+> Validation will not provide you with transformed values. See [submission handling](./submission-handling.md) for more information.
+
To use schemas from these libraries you can pass them to the `validators` props as you would do with a custom function:
```tsx
diff --git a/docs/framework/vue/guides/submission-handling.md b/docs/framework/vue/guides/submission-handling.md
index fec403eca..e35b735e1 100644
--- a/docs/framework/vue/guides/submission-handling.md
+++ b/docs/framework/vue/guides/submission-handling.md
@@ -5,22 +5,40 @@ title: Submission handling
## Passing additional data to submission handling
-You may want to pass additional information to your submission handler, for example, which section to navigate to.
-To pass meta data to `onSubmit`, you can make use of the `onSubmitMeta` property.
+You may want to split your long form into multiple sections, for example, when creating a booking form.
+To receive meta data in your `onSubmit` function, you can specify the `onSubmitMeta` property.
> Note: if `form.handleSubmit()` is called without metadata, it will use the provided default.
```vue
@@ -28,24 +46,28 @@ const form = useForm({
+
+
```
## Transforming data with Standard Schemas
-While Tanstack Form provides Standard Schema support for validation, it does not preserve the Schema's output data.
+While Tanstack Form provides [Standard Schema support](./validation.md) for validation, it does not preserve the Schema's output data.
The value passed to the `onSubmit` function will always be the input data. To receive the output data of a Standard Schema, parse it in the `onSubmit` function:
diff --git a/docs/framework/vue/guides/validation.md b/docs/framework/vue/guides/validation.md
index 50b19674b..baeab4e47 100644
--- a/docs/framework/vue/guides/validation.md
+++ b/docs/framework/vue/guides/validation.md
@@ -245,20 +245,20 @@ const form = useForm({
// Add validators to the form the same way you would add them to a field
onSubmitAsync({ value }) {
// Validate the value on the server
- const hasErrors = await verifyDataOnServer(value)
- if (hasErrors) {
- return {
- form: 'Invalid data', // The `form` key is optional
- fields: {
- age: 'Must be 13 or older to sign',
- // Set errors on nested fields with the field's name
- 'socials[0].url': 'The provided URL does not exist'
- 'details.email': 'An email is required',
- },
- }
+ const hasErrors = await verifyDataOnServer(value)
+ if (hasErrors) {
+ return {
+ form: 'Invalid data', // The `form` key is optional
+ fields: {
+ age: 'Must be 13 or older to sign',
+ // Set errors on nested fields with the field's name
+ 'socials[0].url': 'The provided URL does not exist',
+ 'details.email': 'An email is required',
+ },
}
+ }
- return null
+ return null
},
},
})
From f3aa88e95f3fa26d7c75d42ff3e69084b81cf1aa Mon Sep 17 00:00:00 2001
From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com>
Date: Fri, 18 Apr 2025 14:15:22 +0200
Subject: [PATCH 4/8] docs: add angular submission handling
---
.../angular/guides/submission-handling.md | 113 +++++++++++++++
docs/framework/angular/guides/validation.md | 130 ++++++++++++++++++
docs/framework/react/guides/validation.md | 1 +
3 files changed, 244 insertions(+)
create mode 100644 docs/framework/angular/guides/submission-handling.md
diff --git a/docs/framework/angular/guides/submission-handling.md b/docs/framework/angular/guides/submission-handling.md
new file mode 100644
index 000000000..b7175537e
--- /dev/null
+++ b/docs/framework/angular/guides/submission-handling.md
@@ -0,0 +1,113 @@
+---
+id: submission-handling
+title: Submission handling
+---
+
+## Passing additional data to submission handling
+
+You may want to split your long form into multiple sections, for example, when creating a booking form.
+To receive meta data in your `onSubmit` function, you can specify the `onSubmitMeta` property.
+
+> Note: if `form.handleSubmit()` is called without metadata, it will use the provided default.
+
+```angular-ts
+import { Component } from '@angular/core';
+import { injectForm } from '@tanstack/angular-form';
+
+type FormMeta = {
+ section: 'personalInfo' | 'paymentInfo' | null;
+};
+
+// Metadata is not required to call form.handleSubmit().
+// Specify what values to use as default if no meta is passed
+const defaultMeta: FormMeta = {
+ section: null,
+};
+
+@Component({
+ selector: 'app-root',
+ standalone: true,
+ template: `
+
+
+
+
+ `,
+})
+
+export class AppComponent {
+ name = 'Angular';
+ form = injectForm({
+ defaultValues: {
+ personal: {
+ name: '',
+ email: '',
+ },
+ payment: {
+ address: '',
+ },
+ },
+ // Define what meta values to expect on submission
+ onSubmitMeta: defaultMeta,
+ onSubmit: async ({ value, meta }) => {
+ // Do something with the values passed via handleSubmit
+ console.log(`Selected section - ${meta.section}`, value);
+ },
+ });
+
+ handleSubmit(event: SubmitEvent, meta: FormMeta) {
+ event.preventDefault();
+ event.stopPropagation();
+ // Overwrites the default specified in onSubmitMeta
+ this.form.handleSubmit(meta);
+ }
+}
+```
+
+## Transforming data with Standard Schemas
+
+While Tanstack Form provides [Standard Schema support](./validation.md) for validation, it does not preserve the Schema's output data.
+
+The value passed to the `onSubmit` function will always be the input data. To receive the output data of a Standard Schema, parse it in the `onSubmit` function:
+
+```tsx
+import { z } from 'zod'
+// ...
+
+const schema = z.object({
+ age: z.string().transform((age) => Number(age)),
+})
+
+// Tanstack Form uses the input type of Standard Schemas
+const defaultValues: z.input = {
+ age: '13',
+}
+
+// ...
+
+export class AppComponent {
+ name = 'Angular'
+ form = injectForm({
+ defaultValues,
+ validators: {
+ onChange: schema,
+ },
+ onSubmit: ({ value }) => {
+ const inputAge: string = value.age
+ // Pass it through the schema to get the transformed value
+ const result = schema.parse(value)
+ const outputAge: number = result.age
+ },
+ })
+}
+```
diff --git a/docs/framework/angular/guides/validation.md b/docs/framework/angular/guides/validation.md
index 608817624..76213f0cf 100644
--- a/docs/framework/angular/guides/validation.md
+++ b/docs/framework/angular/guides/validation.md
@@ -288,6 +288,134 @@ export class AppComponent {
}
```
+### Setting field-level errors from the form's validators
+
+You can set errors on the fields from the form's validators. One common use case for this is validating all the fields on submit by calling a single API endpoint in the form's `onSubmitAsync` validator.
+
+```angular-ts
+@Component({
+ selector: 'app-root',
+ standalone: true,
+ imports: [TanStackField],
+ template: `
+
+ `,
+})
+
+export class AppComponent {
+ name = 'Angular';
+ form = injectForm({
+ defaultValues: {
+ age: 0,
+ socials: [],
+ details: {
+ email: '',
+ },
+ },
+ validators: {
+ onSubmitAsync: async ({ value }) => {
+ // Validate the value on the server
+ const hasErrors = await verifyDataOnServer(value)
+ if (hasErrors) {
+ return {
+ form: 'Invalid data', // The `form` key is optional
+ fields: {
+ age: 'Must be 13 or older to sign',
+ // Set errors on nested fields with the field's name
+ 'socials[0].url': 'The provided URL does not exist',
+ 'details.email': 'An email is required',
+ },
+ };
+ }
+
+ return null;
+ },
+ },
+ });
+
+ handleSubmit(event: SubmitEvent) {
+ event.preventDefault();
+ event.stopPropagation();
+ this.form.handleSubmit();
+ }
+}
+```
+
+> Something worth mentioning is that if you have a form validation function that returns an error, that error may be overwritten by the field-specific validation.
+>
+> This means that:
+>
+> ```angular-ts
+> @Component({
+> selector: 'app-root',
+> standalone: true,
+> imports: [TanStackField],
+> template: `
+>
+> `,
+> })
+> export class AppComponent {
+> name = 'Angular';
+> form = injectForm({
+> defaultValues: {
+> age: 0,
+> },
+> validators: {
+> onChange: ({ value }) => {
+> return {
+> fields: {
+> age: value.age < 12 ? 'Too young!' : undefined,
+> },
+> };
+> },
+> },
+> });
+>
+> fieldValidator: FieldValidateFn = ({ value }) =>
+> value % 2 === 0 ? 'Must be odd!' : undefined;
+> }
+>
+> ```
+>
+> Will only show `'Must be odd!` even if the 'Too young!' error is returned by the form-level validation.
+
## Asynchronous Functional Validation
While we suspect most validations will be synchronous, there are many instances where a network call or some other async operation would be useful to validate against.
@@ -429,6 +557,8 @@ TanStack Form natively supports all libraries following the [Standard Schema spe
_Note:_ make sure to use the latest version of the schema libraries as older versions might not support Standard Schema yet.
+> Validation will not provide you with transformed values. See [submission handling](./submission-handling.md) for more information.
+
To use schemas from these libraries you can pass them to the `validators` props as you would do with a custom function:
```angular-ts
diff --git a/docs/framework/react/guides/validation.md b/docs/framework/react/guides/validation.md
index 7a0e2d036..e9bdee07c 100644
--- a/docs/framework/react/guides/validation.md
+++ b/docs/framework/react/guides/validation.md
@@ -324,6 +324,7 @@ export default function App() {
> validators={{
> onChange: ({ value }) => (value % 2 === 0 ? 'Must be odd!' : undefined),
> }}
+> children={() => <>{/* ... */}>}
> />
> )
> ```
From 5b9a71fd42859ce1e4f8cb35a0a1deeb7bef5864 Mon Sep 17 00:00:00 2001
From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com>
Date: Fri, 18 Apr 2025 14:47:50 +0200
Subject: [PATCH 5/8] Update
docs/framework/angular/guides/submission-handling.md
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Pascal Küsgen
---
docs/framework/angular/guides/submission-handling.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/docs/framework/angular/guides/submission-handling.md b/docs/framework/angular/guides/submission-handling.md
index b7175537e..0afb5209c 100644
--- a/docs/framework/angular/guides/submission-handling.md
+++ b/docs/framework/angular/guides/submission-handling.md
@@ -44,7 +44,6 @@ const defaultMeta: FormMeta = {
`,
})
-
export class AppComponent {
name = 'Angular';
form = injectForm({
From ef685b1cd6ee97b67f36db1dc9ddeaa4e25358b6 Mon Sep 17 00:00:00 2001
From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com>
Date: Fri, 18 Apr 2025 16:34:51 +0200
Subject: [PATCH 6/8] Update
docs/framework/angular/guides/submission-handling.md
---
docs/framework/angular/guides/submission-handling.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/docs/framework/angular/guides/submission-handling.md b/docs/framework/angular/guides/submission-handling.md
index 0afb5209c..a7205af06 100644
--- a/docs/framework/angular/guides/submission-handling.md
+++ b/docs/framework/angular/guides/submission-handling.md
@@ -94,6 +94,9 @@ const defaultValues: z.input = {
// ...
+@Component({
+ // ...
+})
export class AppComponent {
name = 'Angular'
form = injectForm({
From 7d12469ee4ef5be47bffdd9094f165020c7a3358 Mon Sep 17 00:00:00 2001
From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com>
Date: Fri, 18 Apr 2025 21:43:32 +0200
Subject: [PATCH 7/8] docs: change example for submit meta
---
.../angular/guides/submission-handling.md | 47 ++++++--------
.../react/guides/submission-handling.md | 63 ++++++++-----------
.../solid/guides/submission-handling.md | 63 ++++++++-----------
.../vue/guides/submission-handling.md | 53 +++++++---------
4 files changed, 93 insertions(+), 133 deletions(-)
diff --git a/docs/framework/angular/guides/submission-handling.md b/docs/framework/angular/guides/submission-handling.md
index b7175537e..a9b7db998 100644
--- a/docs/framework/angular/guides/submission-handling.md
+++ b/docs/framework/angular/guides/submission-handling.md
@@ -5,8 +5,8 @@ title: Submission handling
## Passing additional data to submission handling
-You may want to split your long form into multiple sections, for example, when creating a booking form.
-To receive meta data in your `onSubmit` function, you can specify the `onSubmitMeta` property.
+You may have multiple types of submission behaviour, for example, going back to another page or staying on the form.
+You can accomplish this by specifying the `onSubmitMeta` property. This meta data will be passed to the `onSubmit` function.
> Note: if `form.handleSubmit()` is called without metadata, it will use the provided default.
@@ -14,60 +14,51 @@ To receive meta data in your `onSubmit` function, you can specify the `onSubmitM
import { Component } from '@angular/core';
import { injectForm } from '@tanstack/angular-form';
+
type FormMeta = {
- section: 'personalInfo' | 'paymentInfo' | null;
+ submitAction: 'continue' | 'backToMenu' | null;
};
// Metadata is not required to call form.handleSubmit().
// Specify what values to use as default if no meta is passed
const defaultMeta: FormMeta = {
- section: null,
+ submitAction: null,
};
@Component({
selector: 'app-root',
standalone: true,
template: `
-
-
-
-
+
`,
})
-
export class AppComponent {
name = 'Angular';
form = injectForm({
defaultValues: {
- personal: {
- name: '',
- email: '',
- },
- payment: {
- address: '',
- },
+ data: '',
},
// Define what meta values to expect on submission
onSubmitMeta: defaultMeta,
onSubmit: async ({ value, meta }) => {
// Do something with the values passed via handleSubmit
- console.log(`Selected section - ${meta.section}`, value);
+ console.log(`Selected action - ${meta.submitAction}`, value);
},
});
- handleSubmit(event: SubmitEvent, meta: FormMeta) {
+ handleSubmit(event: SubmitEvent) {
event.preventDefault();
event.stopPropagation();
+ }
+
+ handleClick(meta: FormMeta) {
// Overwrites the default specified in onSubmitMeta
this.form.handleSubmit(meta);
}
diff --git a/docs/framework/react/guides/submission-handling.md b/docs/framework/react/guides/submission-handling.md
index 50e70c995..a7fe65ca7 100644
--- a/docs/framework/react/guides/submission-handling.md
+++ b/docs/framework/react/guides/submission-handling.md
@@ -5,8 +5,8 @@ title: Submission handling
## Passing additional data to submission handling
-You may want to split your long form into multiple sections, for example, when creating a booking form.
-To receive meta data in your `onSubmit` function, you can specify the `onSubmitMeta` property.
+You may have multiple types of submission behaviour, for example, going back to another page or staying on the form.
+You can accomplish this by specifying the `onSubmitMeta` property. This meta data will be passed to the `onSubmit` function.
> Note: if `form.handleSubmit()` is called without metadata, it will use the provided default.
@@ -14,63 +14,50 @@ To receive meta data in your `onSubmit` function, you can specify the `onSubmitM
import { useForm } from '@tanstack/react-form'
type FormMeta = {
- section: 'personalInfo' | 'paymentInfo' | null
+ submitAction: 'continue' | 'backToMenu' | null
}
// Metadata is not required to call form.handleSubmit().
// Specify what values to use as default if no meta is passed
const defaultMeta: FormMeta = {
- section: null,
+ submitAction: null,
}
function App() {
const form = useForm({
defaultValues: {
- personal: {
- name: '',
- email: '',
- },
- payment: {
- address: '',
- },
+ data: '',
},
// Define what meta values to expect on submission
onSubmitMeta: defaultMeta,
onSubmit: async ({ value, meta }) => {
// Do something with the values passed via handleSubmit
- console.log(`Selected section - ${meta.section}`, value)
+ console.log(`Selected action - ${meta.submitAction}`, value)
},
})
return (
- <>
-
-
-
- >
+ Submit and back to menu
+
+
)
}
```
diff --git a/docs/framework/solid/guides/submission-handling.md b/docs/framework/solid/guides/submission-handling.md
index 72dc7812d..0ff523e1c 100644
--- a/docs/framework/solid/guides/submission-handling.md
+++ b/docs/framework/solid/guides/submission-handling.md
@@ -5,8 +5,8 @@ title: Submission handling
## Passing additional data to submission handling
-You may want to split your long form into multiple sections, for example, when creating a booking form.
-To receive meta data in your `onSubmit` function, you can specify the `onSubmitMeta` property.
+You may have multiple types of submission behaviour, for example, going back to another page or staying on the form.
+You can accomplish this by specifying the `onSubmitMeta` property. This meta data will be passed to the `onSubmit` function.
> Note: if `form.handleSubmit()` is called without metadata, it will use the provided default.
@@ -14,63 +14,50 @@ To receive meta data in your `onSubmit` function, you can specify the `onSubmitM
import { createForm } from '@tanstack/solid-form'
type FormMeta = {
- section: 'personalInfo' | 'paymentInfo' | null
+ submitAction: 'continue' | 'backToMenu' | null
}
// Metadata is not required to call form.handleSubmit().
// Specify what values to use as default if no meta is passed
const defaultMeta: FormMeta = {
- section: null,
+ submitAction: null,
}
export default function App() {
const form = createForm(() => ({
defaultValues: {
- personal: {
- name: '',
- email: '',
- },
- payment: {
- address: '',
- },
+ data: '',
},
// Define what meta values to expect on submission
onSubmitMeta: defaultMeta,
onSubmit: async ({ value, meta }) => {
// Do something with the values passed via handleSubmit
- console.log(`Selected section - ${meta.section}`, value)
+ console.log(`Selected action - ${meta.submitAction}`, value)
},
}))
return (
- <>
-
-
-
- >
+ Submit and back to menu
+
+
)
}
```
diff --git a/docs/framework/vue/guides/submission-handling.md b/docs/framework/vue/guides/submission-handling.md
index e35b735e1..2976e0b85 100644
--- a/docs/framework/vue/guides/submission-handling.md
+++ b/docs/framework/vue/guides/submission-handling.md
@@ -5,8 +5,8 @@ title: Submission handling
## Passing additional data to submission handling
-You may want to split your long form into multiple sections, for example, when creating a booking form.
-To receive meta data in your `onSubmit` function, you can specify the `onSubmitMeta` property.
+You may have multiple types of submission behaviour, for example, going back to another page or staying on the form.
+You can accomplish this by specifying the `onSubmitMeta` property. This meta data will be passed to the `onSubmit` function.
> Note: if `form.handleSubmit()` is called without metadata, it will use the provided default.
@@ -15,52 +15,47 @@ To receive meta data in your `onSubmit` function, you can specify the `onSubmitM
import { useForm } from '@tanstack/vue-form'
type FormMeta = {
- section: 'personalInfo' | 'paymentInfo' | null
+ submitAction: 'continue' | 'backToMenu' | null
}
// Metadata is not required to call form.handleSubmit().
// Specify what values to use as default if no meta is passed
const defaultMeta: FormMeta = {
- section: null,
+ submitAction: null,
}
const form = useForm({
defaultValues: {
- personal: {
- name: '',
- email: '',
- },
- payment: {
- address: '',
- },
+ data: '',
},
// Define what meta values to expect on submission
onSubmitMeta: defaultMeta,
onSubmit: async ({ value, meta }) => {
// Do something with the values passed via handleSubmit
- console.log(`Selected section - ${meta.section}`, value)
+ console.log(`Selected action - ${meta.submitAction}`, value)
},
})
-
-
-
```
From 9a84719a1f188ea16b9e3f7eab17fd33dce81e44 Mon Sep 17 00:00:00 2001
From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com>
Date: Tue, 22 Apr 2025 10:27:42 +0200
Subject: [PATCH 8/8] Docs: Clean up redundant angular properties
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Pascal Küsgen
---
docs/framework/angular/guides/submission-handling.md | 3 ---
docs/framework/angular/guides/validation.md | 3 ---
2 files changed, 6 deletions(-)
diff --git a/docs/framework/angular/guides/submission-handling.md b/docs/framework/angular/guides/submission-handling.md
index a1c0a5cb4..e5fae2477 100644
--- a/docs/framework/angular/guides/submission-handling.md
+++ b/docs/framework/angular/guides/submission-handling.md
@@ -27,7 +27,6 @@ const defaultMeta: FormMeta = {
@Component({
selector: 'app-root',
- standalone: true,
template: `