Skip to content

Instantly share code, notes, and snippets.

@Shahzad6077
Forked from reksamamur/MultiNestedField.tsx
Created September 2, 2022 23:13
Show Gist options
  • Save Shahzad6077/904860fd5a20624609a00e35f8482323 to your computer and use it in GitHub Desktop.
Save Shahzad6077/904860fd5a20624609a00e35f8482323 to your computer and use it in GitHub Desktop.
Multi Nested Field Array using react-hook-form
import "./styles.css";
import {
useForm,
FormProvider,
useFormContext,
useFieldArray,
UseFieldArrayReturn
} from "react-hook-form";
interface InputMultiProps {
depth: number;
formParentName: string;
index: number;
value?: any;
fieldArray: UseFieldArrayReturn;
}
const InputMulti = ({
depth,
formParentName,
index,
fieldArray
}: InputMultiProps) => {
const formName = `${formParentName}.${index}`;
const formNameNested = `${formName}.children`;
const { register, control } = useFormContext();
// console.log("input multi", fieldArray.fields);
const nestedFieldArray = useFieldArray({
control,
name: formNameNested
});
// console.log([formName, formNameNested, index]);
return (
<>
<div style={{ paddingLeft: depth * 10 }}>
<input
type="text"
placeholder="name"
{...register(`${formName}.value` as const)}
/>
<button
onClick={() =>
fieldArray.append({
value: "",
depth: depth,
children: []
})
}
>
Add
</button>
<button
onClick={() =>
nestedFieldArray.append({
value: "",
depth: depth + 1,
children: []
})
}
>
Add Nested
</button>
<button onClick={() => fieldArray.remove(index)}>Delete</button>
<button onClick={() => fieldArray.move(index, index - 1)}>
Move Up
</button>
<button onClick={() => fieldArray.move(index, index + 1)}>
Move Down
</button>
</div>
{nestedFieldArray.fields.map((field, index) => (
<InputMulti
key={field.id}
depth={depth + 1}
index={index}
formParentName={formNameNested}
fieldArray={nestedFieldArray}
/>
))}
</>
);
};
const CustomForm = () => {
const { control, handleSubmit } = useFormContext();
const fieldArrayName = "parent";
const fieldArray = useFieldArray({
control,
name: fieldArrayName
});
// console.log("custom form", fieldArray.fields);
const onSubmit = (data: any) => console.log("data", data);
// const testOnSubmit = (e: React.FormEvent<HTMLFormElement>) => {
// e.preventDefault();
// const fdata = new FormData(e.currentTarget);
// const inputObject = Object.fromEntries(fdata);
// console.log(inputObject);
// };
return (
<>
<form onSubmit={handleSubmit(onSubmit)}>
<button
onClick={() =>
fieldArray.append({ value: "", depth: 0, children: [] })
}
>
First
</button>
{/* <form onSubmit={(e) => testOnSubmit(e)}> */}
{fieldArray.fields.map((field, index) => (
<InputMulti
key={field.id}
depth={0}
index={index}
formParentName={`parent`}
value={field}
fieldArray={fieldArray}
/>
))}
<input style={{ marginTop: 20 }} type="submit" value="Submit" />
</form>
</>
);
};
export default function App() {
//const methods = useForm({
// defaultValues: { parent: [{ name: "parent", value: "" }] }
//});
// const fieldArrayName = "form";
const defaultValues = {
parent: [
{
value: "Te st",
children: []
},
{
value: " asda Sa",
children: []
},
{
value: "Asda asd",
children: [
{
value: "child 1",
children: []
},
{
value: "child 2",
children: []
}
]
}
]
};
// const methods = useForm({defaultValues});
const methods = useForm();
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<FormProvider {...methods}>
<CustomForm />
</FormProvider>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment