Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ will attempt to apply focus to the first field with an error upon an attempted f
* [Usage](#usage)
* [🏁 Final Form Usage](#-final-form-usage)
* [🏁 React Final Form Usage](#-react-final-form-usage)
* [Multiple Forms](#multiple-forms)
* [Example](#example)
* [Focus On Error Example](#focus-on-error-example)
* [API](#api)
Expand Down Expand Up @@ -74,7 +75,7 @@ const undecorate = decorator(form)
```js
import React from 'react'
import { Form, Field } from 'react-final-form'
import createDecorator from 'final-form-focus'
import createDecorator, { getFormInputs } from 'final-form-focus'

const focusOnErrors = createDecorator()
...
Expand All @@ -92,6 +93,27 @@ const focusOnErrors = createDecorator()
/>
```

### Multiple Forms

By default, `createDecorator()` searches all inputs in `document.forms`. If a page contains multiple forms with fields that share the same name, pass `getFormInputs(formName)` so each decorator only searches inputs from its own named `<form>`.

```js
import createDecorator, { getFormInputs } from 'final-form-focus'

const focusOnFirstFormErrors = createDecorator(getFormInputs('firstForm'))
const focusOnSecondFormErrors = createDecorator(getFormInputs('secondForm'))

<Form
decorators={[focusOnSecondFormErrors]}
onSubmit={submit}
render={({ handleSubmit }) => (
<form name="secondForm" onSubmit={handleSubmit}>
... inputs here ...
</form>
)}
/>
```

## Example

### [Focus On Error Example](https://codesandbox.io/s/6174kqr403)
Expand Down
21 changes: 21 additions & 0 deletions src/getFormInputs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,27 @@ describe('getFormInputs', () => {
expect(inputs.map(input => input.name)).toEqual(['firstName', 'lastName']);
});

it('should scope same-name inputs to the requested form', () => {
document.body.innerHTML = `
<form name="firstForm">
<input type="text" name="email" />
</form>
<form name="secondForm">
<input type="text" name="email" />
</form>
`;

const firstInput = document.forms.namedItem('firstForm')!.elements.namedItem('email') as HTMLInputElement;
const secondInput = document.forms.namedItem('secondForm')!.elements.namedItem('email') as HTMLInputElement;
const firstFocus = jest.spyOn(firstInput, 'focus');
const secondFocus = jest.spyOn(secondInput, 'focus');

getFormInputs('secondForm')()[0].focus();

expect(firstFocus).not.toHaveBeenCalled();
expect(secondFocus).toHaveBeenCalled();
});

it('should ignore unnamed inputs', () => {
document.body.innerHTML = `
<form name="testForm">
Expand Down
Loading