We need to plot a form whose entire fields are coming from the backend. Since the fields are not known in advance, we cannot add them statically. The data about each field, such as its id to save with, name, validations, etc. all comes in the API response too.
For the given scenario, I have used React Hook Form. The demo and example code for a dynamic questionnaire is shared below.
Demo
Example Code
import React, { useState } from "react";
import { useForm, useFieldArray } from "react-hook-form";
export default function DynamicForm() {
const {
control,
register,
handleSubmit,
watch,
formState: { errors }
} = useForm();
const [loading, setLoading] = useState(false);
const { fields, append } = useFieldArray({
control,
name: "questionnaire"
});
const value = watch("questionnaire");
const questionnaireFromBackend = [
{
id: 1,
value: "",
placeholder: "First Name",
required: true
},
{
id: 2,
value: "",
placeholder: "Middle Name"
},
{
id: 3,
value: "",
placeholder: "Last Name",
required: true
}
];
const loadQuestionnaire = () => {
setLoading(true);
setTimeout(() => {
setLoading(false);
questionnaireFromBackend.forEach((q) => {
append(q, { shouldFocus: false });
});
}, 3000);
}
const onSubmit = (data) => {
console.log(data);
// submit dynamic questionnaire!
};
return (
<div
style={{
borderStyle: "ridge",
padding: "10px",
minHeight: "300px"
}}>
{
(!loading && !fields.length)
&&
<button
type="button"
onClick={loadQuestionnaire}>
Load Questionnaire
</button>
}
{loading ? (
"loading questionnaire..."
) : (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
{fields.map((field, index) => (
<div key={field.id} style={{ marginBottom: "10px" }}>
<input
{...register(`questionnaire.${index}.value`, {
required: value[index].required
})}
placeholder={value[index].placeholder}
/>
<br></br>
{errors?.questionnaire?.[index] && (
<span style={{ color: "red", fontSize: "small" }}>
{value[index].placeholder} is required
</span>
)}
</div>
))}
</div>
<br></br>
{!loading && fields.length > 0 && <input type="submit" />}
</form>
)}
</div>
)
}
In this next post I’m going to share how to handle dynamic conditional fields in a form.
See also
- Reduce JS Size With Constant Strings
- JavaScript SDK
- JavaScript: Find if the String Has a Particular Case
- Replace All Keys of Deeply Nested Objects or Array of Objects in JavaScript
- Restrict Content for Users of Specific Countries With JavaScript Only
- Track Number of User Visits With JavaScript Local Storage
- React JS Render Form With Dynamic Conditional Fields