Add multiple form fields but show only one at a time

1.1k views Asked by At

I need final-form to be able to add array of form field records. But want to display only one field of array at a time. Like on left side I will have customer id or index which user will select and on right side i have to show customer corresponding to that index. I am able to add reac-final-form-array, but it always show all array elements. What should be the right approach to show only selected customer.

Please check the below code for reference. Hope my question is clear, if not please let me know, will add more explanation.

<FieldArray name="customer">
  {({ fields }) => (
    fields.map((name, index) => (
      <div key={index}>
        <Field name={`${name}.firstName`} />
        <Field name={`${name}.lastName`} />
      </div>
    ))
  )}
</FieldArray>

To add new customer:

<div className="buttons">
  <button
    type="button"
    onClick={() => push('customers', undefined)}>
    Add Customer
  </button>
</div>

Currently its looking like:

enter image description here

I need it to look like this: enter image description here

2

There are 2 answers

0
Praveen Jaya Kumar Ramesh On BEST ANSWER

Find the below code.

import React from "react";
import { Form, Field } from "react-final-form";
import arrayMutators from "final-form-arrays";
import { FieldArray } from "react-final-form-arrays";

const onSubmit = () => {
  console.log("submitted");
};

const validate = () => {
  // console.log("validated");
};

const MyForm = () => (
  <Form
    onSubmit={onSubmit}
    mutators={{
      // potentially other mutators could be merged here
      ...arrayMutators
    }}
    validate={validate}
    render={({ handleSubmit, pristine, invalid }) => (
      <form onSubmit={handleSubmit}>
        <FieldArray name="customers">
          {({ fields }) => (
            <div>
              <button
                type="button"
                onClick={() =>
                  fields.push({ firstName: "", lastName: "", isVisible: true })
                }
              >
                Add Customer
              </button>
              {fields.map((name, index) => (
                <div key={name}>
                  <a
                    onClick={() =>
                      (fields.value[index].isVisible = !fields.value[index]
                        .isVisible)
                    }
                  >{`Cust #${index}`}</a>
                  {fields.value[index].isVisible ? (
                    <div>
                      <div>
                        <Field name={`${name}.firstName`} component="input" />
                      </div>
                      <div>
                        <Field name={`${name}.lastName`} component="input" />
                      </div>
                    </div>
                  ) : null}
                  <button type="button" onClick={() => fields.remove(index)}>
                    Remove
                  </button>
                </div>
              ))}
            </div>
          )}
        </FieldArray>
      </form>
    )}
  />
);

export default MyForm;

Check the codesandbox link here

2
Ratnajeet Shyamkunwar On

In the fields array, you can add one more key isVisible.

It will look like this:

fields = [
    {
        firstName: 'John',
        lastName: 'Doe',
        isVisible: true,
    },
    {
        firstName: 'Jane',
        lastName: 'Doe',
        isVisible: false,
    }
];

Now while showing, only render the field when isVisible is true,

<FieldArray name="customer">
  {({ fields }) => (
    fields.map((name, index) => {
      if(name.isVisible){
        return (
          <div key={index}>
            <Field name={`${name}.firstName`} />
            <Field name={`${name}.lastName`} />
          </div>
      );
    ))
  )}
</FieldArray>

You can control isVisible key by clicking Cust # button.