4

I'm following this documentation to use FormDataConsumer to show / hide inputs. But I have a nested ArrayInput / FormDataConsumer as below:

export const MyClassCreate = ({ permissions, ...props }) => (
  <Create {...props}>
    <TabbedForm>
      <FormTab label="summary">
        <SelectInput source="className" choices={choices} optionText="choiceType"
                     optionValue="className"disableValue="not_available"
        />
        <TextInput source="field1" />
        <NumberInput source="field2" />
        <FormDataConsumer>
          {({ formData, ...rest }) =>
            formData.className === "my.package.MyClass2" && (
              <TextInput source="field3" {...rest} />
            )
          }
        </FormDataConsumer>
        <FormDataConsumer>
          {({ formData, ...rest }) =>
            formData.className === "my.package.MyClass1" && (
              <Fragment>
                <NumberInput source="field4" {...rest} />
                <ArrayInput source="arrayField1">
                  <SimpleFormIterator>
                    <SelectInput source="field5.subField6" choices={choices} 
                                 optionText="choiceType"
                                 optionValue="className" 
                                 disableValue="not_available"
                    />
                    <TextInput source="field5.subField7" />
                    <FormDataConsumer>
                      {({ formData, scopedFormData, getSource, ...rest }) =>
                        scopedFormData.field5 &&
                        scopedFormData.field5.subField8 &&
                        scopedFormData.field5.subField8 ===
                          "my.package.MyClass3" && (
                          <NumberInput
                            source={getSource("field5.subField9")}
                            {...rest}
                          />
                        )
                      }
                    </FormDataConsumer>
                    <FormDataConsumer>
                      {({ formData, scopedFormData, getSource, ...rest }) =>
                        scopedFormData.field5 &&
                        scopedFormData.field5.subField8 &&
                        scopedFormData.field5.subField8 ===
                          "my.package.MyClass4" && (
                          <ArrayInput source={getSource("reward.rewards")}>
                            <SimpleFormIterator>
                              <SelectInput source={getSource("problemField1")} choices={choices}
                                           optionText="choiceType" optionValue="className"
                                           disableValue="not_available"
                              />
                              <TextInput source={getSource("problemField2")} />
                              <FormDataConsumer>
                                {({
                                  formData,
                                  scopedFormData,
                                  getSource,
                                  ...rest
                                }) =>
                                  scopedFormData.field8 &&
                                  scopedFormData.field8 ===
                                    "my.package.MyClass5" && (
                                    <NumberInput
                                      source={getSource("field8")}
                                      {...rest}
                                    />
                                  )
                                }
                              </FormDataConsumer>
                            </SimpleFormIterator>
                          </ArrayInput>
                        )
                      }
                    </FormDataConsumer>
                  </SimpleFormIterator>
                </ArrayInput>
              </Fragment>
            )
          }
        </FormDataConsumer>
      </FormTab>
      <FormTab label="campaign">
        <DateInput source="startTime" parse={dateParser} />
        <DateInput source="expirationTime" parse={dateParser} />
      </FormTab>
    </TabbedForm>
  </Create>
);

My problem is that in problemField1 and problemField2, although I'm calling getSource like I'm supposed to, the actual resolution of the source is still using referring to the first level source dereferencing. Is there a way to tell my nested / inner getSource to point to the right "level"?

1 Answer 1

1

I've been able to create nested ArrayInput with react-admin

Here's the simple example:

const NavBarInput = ({ source }) => (
  <Box>
    <ArrayInput source={source}>
      <SimpleFormIterator>
        <TextInput source="title" />
        <FormDataConsumer>
          {({ getSource }) => (
            <NavBarInput source={getSource?.('items')} />
          )}
        </FormDataConsumer>
      </SimpleFormIterator>
    </ArrayInput>
  </Box>
);
Sign up to request clarification or add additional context in comments.

1 Comment

This actually works, thank you! Just for clarity: when you iterate through the inner nested array each input field's source can simply be the array element's property name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.