Please I am developing an application with React JS, Inertia and Laravel that require users to submit their academic qualifications. I want the user to be able to add additional form row for more qualifications or remove as the case may be and this is working already. Also, I want the form to be submitted as an array of values and as well validate the values in the array when the form is finally submitted to laravel controller. I have only done this before with traditional php/html but couldn't figure out how best to submit the form as array in React/Inertia
I want to store all the qualifications as array in data.qualifications with keys that correspond to the index of the map. The same for data.institution, data.course and data.date_of_graduation
Below is the code
const StaffEducation = () => {
const user = usePage().props.auth.user;
const { data, setData, post, processing, errors } = useForm<{
staffid: string;
qualification: string[];
institution: string[];
course: string[];
date_of_graduation: string[];
}>({
staffid: user.username,
qualification: [],
institution: [],
course: [],
date_of_graduation: [],
});
//Default no of forms provided for qualifications
const [educations, setEducations] = useState<number[]>([1, 2]);
const educationList = (education?: number) => {
//pass an element from the list to delete
if (education) {
// educations.splice(educations.indexOf(education), 1);
setEducations([...educations.filter((edu) => edu !== education)]);
} else {
setEducations([
...educations,
educations[educations.length - 1] + 1,
]);
}
};
// console.log(data.qualification);
// const handleSchool = (e: React.ChangeEvent<HTMLInputElement>) =>
// console.log(e);
return (
<>
<Head title="Education and Qualifications" />
<section className="section">
<div className="row">
<div className="col-lg-12">
<div className="card">
<div className="card-body">
<h5 className="card-title text-center">
Education and Qualifications
</h5>
<form>
<table className="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">
Qualification
</th>
<th scope="col">
University/College
</th>
<th scope="col">
Course/Programme
</th>
<th scope="col">Date of Graduation</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{educations &&
educations.map(
(
education: number,
id: number
) => (
<tr key={id}>
<th scope="row">
{id + 1}
</th>
<td>
<div className="col-md-12">
<input
type="text"
className="form-control"
placeholder="e.g B.Sc"
value={
data
.qualification[
id
]
}
name="qualification[]"
onChange={(
e
) =>
setData(
"qualification",
data.qualification.splice(
id,
1,
e
.target
.value
)
)
}
/>
</div>
</td>
<td>
<div className="col-md-12">
<input
type="text"
className="form-control"
placeholder="University/Institution"
name="institution[]"
/>
</div>
</td>
<td>
<div className="col-md-12">
<input
type="text"
className="form-control"
placeholder="Course"
name="course[]"
/>
</div>
</td>
<td>
<div className="col-md-12">
<input
type="date"
className="form-control"
name="date_of_graduation[]"
/>
</div>
</td>
<td>
{educations[0] ===
education ? (
<button
type="button"
className="btn btn-primary "
onClick={() =>
educationList()
}
>
Add
</button>
) : (
<button
type="button"
className="btn btn-danger "
onClick={() =>
educationList(
education
)
}
>
Remove
</button>
)}
</td>
</tr>
)
)}
</tbody>
</table>
</form>
</div>
</div>
</div>
</div>
</section>
</>
);
};
export default StaffEducation;
I also tried the below code in setting the value, //setData("qualification", data.qualification.map((q,index) =>index === id ? e.target.value : q) but this only work if I set default values for the qualification array in the useForm hook while the data.qualification.splice(id,1,e.target.value) does not work in setting the value.
I need advise on how best to approach this. Thank you.
Update
I have to use setData("qualification",data.qualification.map((q,index) =>index === id ? e.target.value : q)) for the onChange event instead of onChange={(e) => data.qualification.splice(id, 1, e.target.value)} as the splice method did not even allow typing in the fieds. Also I change the method to add and remove form row to the below
const removeEducation = (id: number) => {
//pass an element index from the list to delete
setEducations(educations.filter((_, index) => index !== id));
data.qualification.splice(id, 1);
data.institution.splice(id, 1);
data.course.splice(id, 1);
data.date_of_graduation.splice(id, 1);
};
const addEducation = () => {
setEducations([
...educations,
educations[educations.length - 1] + 1,
]);
data.qualification.push("");
data.institution.push("");
data.course.push("");
data.date_of_graduation.push("");
};
Default value was also set like qualification: educations.map((edu) => "") in the useForm hook.
Thank you for your support