Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

withNextInputAutoFocus does not work with nested components #42

Open
Gguigre opened this issue Nov 28, 2018 · 4 comments
Open

withNextInputAutoFocus does not work with nested components #42

Gguigre opened this issue Nov 28, 2018 · 4 comments

Comments

@Gguigre
Copy link

Gguigre commented Nov 28, 2018

Description

When using self-closing-tag components to generate text fields in a form, the withNextInputAutoFocusForm does not register the generated textInputs and the expected behaviour does not work : pressing "OK" with a textInput focused submits the entire form.

Steps to reproduce / example

const Form = withNextInputAutoFocusForm(View);

export class ReportForm extends PureComponent<PropsType, StateType> {
  renderForm = ({ values, handleSubmit }: { values: any, handleSubmit: Function }) => {
    return (
        <Form>
            <AircraftInformationSection />
      </Form>
    );
  };

  render() {
    return (
      <Formik
        // ...
        render={this.renderForm}
      />
    );
  }
}
export class AircraftInformationSection extends PureComponent<PropsType> {
  render() {
    return (
      <View>
        <TextInput
          name="aircraftInformationSectionType"
          // ...
        />
      </View>
    );
  }
}

In this case, getInputs does not see any children in the props of <AircraftInformationSection />

Ideas of technical solution

Create a Provider/Consumer system with textFields subscribing to the form.
Add a prop to the form to specify the order of the fields to be focused.

@Almouro
Copy link
Member

Almouro commented Nov 28, 2018

Hi @Gguigre, thanks for reporting!

In getInputs, withNextInputAutoFocusForm traverses the hierarchy of children of the wrapped component to find inputs.
In your case, only one child is found, which is AircraftInformationSection, but not an input of course, and AircraftInformationSection itself does not have any children.

Would it be possible in your case to use withNextInputAutoFocusForm directly on AircraftInformationSection?

@Gguigre
Copy link
Author

Gguigre commented Nov 29, 2018

Hi @Almouro,
unfortunately, the <AircraftInformationSection /> component is not the only one inside the <Form> and they're other components that generate fields too.

Actually, the renderForm method is more like

renderForm = ({ values, handleSubmit }: { values: any, handleSubmit: Function }) => {
    return (
        <Form>
            <AircraftInformationSection />
            <FlightInformationSection />
            <EngineInformationSection />
      </Form>
    );
  };

So if I create one <Form /> for each section, the next won't handle passing between the different sections :(

@louiszawadzki
Copy link
Contributor

@Gguigre I believe you should also add that AircraftInformationSection has several inputs as children, not only one.

@kacgrzes
Copy link

kacgrzes commented Jan 14, 2019

Recently merge doesn't fix the issue. The thing is that getInputs recursive function doesn't get into components without children, so... if you have something like that:

const Address = () => {
  return <Box>
    <Input name={'address_line_1'}
    <Input name={'address_line_2'}
  </Box>
}

const RegistrationForm = () => {
  <Form>
    <Box>
      <Input name={'a'} />
      <Input name={'b'} />
      <Input name={'c'} />
      <Input name={'d'} />
    </Box>
    <Address />
  </Form>
}

where Form is hoc composed with withNextInputAutoFocus

it doesn't not get into Address component as it does not conform to this part

const getInputs = children =>
    //...
    if (child && child.props && child.props.children) { // <- well, this
      //...
    }
    //...
  }, []);

I'm trying to get the solution for that. I will leave PR for you @Almouro if I have any 🤷‍♂️

EDIT
ok, I've found solution for that one. You can nest Forms, so basically this one below fixes the issue:

const Address = () => {
  return <Form>
    <Input name={'address_line_1'}
    <Input name={'address_line_2'}
  </Form>
}

const App = () => {
  <Form>
    //...
    <Address />
    //...
  </Form>
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants