Skip to content

Commit

Permalink
docs: add linked fields docs for React
Browse files Browse the repository at this point in the history
  • Loading branch information
crutchcorn committed Mar 18, 2024
1 parent 250a839 commit 7e8b1b0
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@
"label": "Arrays",
"to": "framework/react/guides/arrays"
},
{
"label": "Linked Fields",
"to": "framework/react/guides/linked-fields"
},
{
"label": "UI Libraries",
"to": "framework/react/guides/ui-libraries"
Expand Down
74 changes: 74 additions & 0 deletions docs/framework/react/guides/linked-fields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Link Two Form Fields Together

You may find yourself needing to link two fields together; when one is validated as another field's value has changed.
One such usage is when you have both a `password` and `confirm_password` field,
where you want to `confirm_password` to error out when `password`'s value does not match;
regardless of which field triggered the value change.

Imagine the following userflow:

- User updates confirm password field.
- User updates the non-confirm password field.

In this example, the form will still have errors present,
as the "confirm password" field validation has not been re-ran to mark as accepted.

To solve this, we need to make sure that the "confirm password" validation is re-run when the password field is updated.
To do this, you can add a `onChangeListenTo` property to the `confirm_password` field.

```tsx
function App() {
const form = useForm({
defaultValues: {
password: '',
confirm_password: '',
},
// ...
})

return (
<div>
<form.Field name="password">
{(field) => (
<label>
<div>Password</div>
<input
value={field.state.value}
onChange={(e) => field.handleChange(e.target.value)}
/>
</label>
)}
</form.Field>
<form.Field
name="confirm_password"
validators={{
onChangeListenTo: ['password'],
onChange: ({ value, fieldApi }) => {
if (value !== fieldApi.form.getFieldValue('password')) {
return 'Passwords do not match'
}
return undefined
},
}}
>
{(field) => (
<div>
<label>
<div>Confirm Password</div>
<input
value={field.state.value}
onChange={(e) => field.handleChange(e.target.value)}
/>
</label>
{field.state.meta.errors.map((err) => (
<div key={err}>{err}</div>
))}
</div>
)}
</form.Field>
</div>
)
}
```

This similarly works with `onBlurListenTo` property, which will re-run the validation when the field is blurred.
12 changes: 12 additions & 0 deletions docs/reference/fieldApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ An object type representing the options for a field in a form.
- An optional number to represent how long the `onChangeAsync` should wait before running
- If set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds

- ```tsx
onChangeListenTo?: DeepKeys<TParentData>[]
```

- An optional list of field names that should trigger **this** field's `onChange` and `onChangeAsync` events when **its** value changes

- ```tsx
onBlur?: ValidateFn<TData, TParentData>
```
Expand All @@ -108,6 +114,12 @@ An object type representing the options for a field in a form.
- An optional number to represent how long the `onBlurAsyncDebounceMs` should wait before running
- If set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds

- ```tsx
onBlurListenTo?: DeepKeys<TParentData>[]
```

- An optional list of field names that should trigger **this** field's `onBlur` and `onBlurAsync` events when **its** field blurs

- ```tsx
onSubmit?: ValidateFn<TData, TParentData>
```
Expand Down

0 comments on commit 7e8b1b0

Please sign in to comment.