How to set MUI input value inside loop with array value in react js?

281 views Asked by At

I have created the React js demo using React MUI. I have made a separate component for each input called InputText.js and used this for each text box. My issue is when I used this component for any single information then it's working fine but I have prepared one array using useState for education and I want to set each education in a separate input box using a loop in JSX but it is not works.

I have managed the input validation using react-hook-form with controller method.

Please check all my code and help me to fix this issue

components/InputText.js

import * as React from "react";
import { useState } from "react";
import TextField from "@mui/material/TextField";
import { PropTypes } from "prop-types";
import { Controller } from "react-hook-form";

const InputText = React.forwardRef(({ control, ...rest }, ref) => {

  const [textValue, setTextValue] = useState("");
  const onTextChange = (e, field) => {
    setTextValue(e.target.value);
    return rest.onChange(e);
  };
  return (
    <Controller
      name={rest.name}
      rules={rest.rules}
      control={control}
      render={({ field }) => (
        <TextField
          fullWidth
          onChange={e => {
            onTextChange(e, field);
          }} 
          label={rest.label}
          type={rest.type}
          value={textValue}
          helperText={rest.helperText}
          disabled={rest.disabled}
          {...field}
          ref={ref}
          //onChange={onTextChange}
        />
      )}
    />
  );
});

InputText.defaultProps = {
  type: "text",
  name: "",
  label: "Field",
  value: "",
  disabled: false,
};
InputText.propTypes = {
  label: PropTypes.string,
  value: PropTypes.string,
};

export default InputText;

components/AddEditUser.js

import * as React from "react";
import InputText from "./InputText.js";
import DatePicker from "./DatePicker.js";
import { useForm } from "react-hook-form";
import Grid from "@mui/material/Unstable_Grid2";
import MIButton from "./Button.js";
import { post, get, patch } from "../utils/ApiServices.js";
import { noti } from "../utils/helper.js";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import { useNavigate, useParams } from "react-router-dom";
import dayjs from "dayjs";
import { Backdrop, CircularProgress } from "@mui/material";
import AddIcon from "@mui/icons-material/Add";
const schema = yup.object({
  firstName: yup.string().required("Please enter first name"),
  lastName: yup.string().required("Please enter last name"),
  email: yup
    .string()
    .required("Please enter email")
    .matches(
      /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/,
      "Please enter valid email"
    ),
  birthDate: yup
    .date("Please select valid date")
    .typeError("Please select valid birth date")
    .required("Please enter birth date"),
});

export default function AddEditUser() {
  const { id } = useParams();
  const [education, setEducation] = React.useState([
    {
      education: "BCA",
      location: "Ahmedabad",
    },
    {
      education: "MCA",
      location: "USA",
    },
  ]);

  let formData = {
    firstName: "",
    lastName: "",
    email: "",
    phone: "",
    birthDate: "",
    age: "",
    edu: education,
  };
  const navigate = useNavigate();
  const {
    control,
    setValue,
    handleSubmit,
    formState: { errors },
  } = useForm({
    defaultValues: formData,
    resolver: yupResolver(schema),
  });

  const [age, setAge] = React.useState("");
  const [loading, setloading] = React.useState(id ? true : false);

  const onInputChange = (e) => {
    console.log("Its parent component............ ", e);
  };
  const onDateAccept = (date) => {
    var dob = new Date(date.$d);
    var month_diff = Date.now() - dob.getTime();
    var age_dt = new Date(month_diff);
    var year = age_dt.getUTCFullYear();
    var age = Math.abs(year - 1970);
    setValue("age", age);
  };

  //Submit form
  const onSubmit = (data) => {
    let params = data;
    let query = id ? patch("user/" + id, params) : post("user", params);
    query
      .then(({ data }) => {
        noti(
          "success",
          "User " + (id ? "updated" : "added") + " successfully."
        );
        navigate("/");
      })
      .catch((error) => {
        noti("error", error);
      });
  };

  //Set user form data
  React.useEffect(() => {
    if (id) {
      get("user/" + id)
      .then(({ data }) => {
        setValue("firstName", data.data["firstName"]);
        setValue("lastName", data.data["lastName"]);
        setValue("email", data.data["email"]);
        setValue("phone", data.data["phone"]);
        setValue("birthDate", dayjs(data.data["birthDate"]));
        setloading(false);
      })
      .catch((error) => {
        noti("error", error);
      });
    }
  }, []);

  const addEducation = () => {
    formData.edu.push({
      education: "Bvoc",
      location: "Junagadh",
    });
    setEducation(formData.edu);
    console.log("Add edu--> ", formData);
  };
  console.log(id);

  return (
    <>
      <h2>{id ? "Edit" : "Add"} User</h2>
      <form onSubmit={handleSubmit(onSubmit)}>
        <Backdrop
          sx={{ color: "#5ac8fa", zIndex: (theme) => theme.zIndex.drawer + 1 }}
          open={loading}
        >
          <CircularProgress color="inherit" />
        </Backdrop>
        <Grid
          container
          spacing={5}
          alignItems="center"
          justifyContent="center"
          columns={12}
          style={{ marginTop: "10px", textAlign: "center" }}
        >
          <Grid xs={6}>
            <InputText
              label={"First Name"}
              name="firstName"
              onChange={onInputChange}
              control={control}
              // rules={{
              //   required: "Please enter first name",
              //   maxLength: {
              //     value: 10,
              //     message: "Please enter max 10 character only",
              //   },
              //   minLength: {
              //     value: 2,
              //     message: "Please enter min 2 character",
              //   },
              // }}
              helperText={errors.firstName?.message}
            />
          </Grid>
          <Grid xs={6}>
            <InputText
              label={"Last Name"}
              name="lastName"
              onChange={onInputChange}
              control={control}
              helperText={errors.lastName?.message}
            />
          </Grid>
          <Grid xs={6}>
            <InputText
              label={"Email"}
              name="email"
              onChange={onInputChange}
              control={control}
              helperText={errors.email?.message}
              disabled={id ? true : false}
            />
          </Grid>
          <Grid xs={6}>
            <InputText
              label={"Phone"}
              name="phone"
              type="number"
              onChange={onInputChange}
              control={control}
              helperText={errors.phone?.message}
            />
          </Grid>
          <Grid xs={6}>
            <DatePicker
              label={"Birth Date"}
              name="birthDate"
              onAccept={onDateAccept}
              control={control}
              helperText={errors.birthDate?.message}
              disableFuture
              openTo="year"
            />
          </Grid>
          <Grid xs={6}>
            <InputText
              label={"Age"}
              name="age"
              onChange={onInputChange}
              control={control}
              value={age}
              disabled
            />
          </Grid>
        </Grid>
        {formData.edu.map((row, index) => (
          <Grid container spacing={5} columns={12} key={index}>
            <Grid xs={6}>
              {row.education}
              <InputText
                label={"Education"}
                name={row.education}
                onChange={onInputChange}
                control={control}
                value={row.education}
                //helperText={errors.lastName?.message}
              />
            </Grid>
            <Grid xs={6}>
              {row.location}
              <InputText
                label={"Location"}
                name="location"
                onChange={onInputChange}
                control={control}
                value={row.location}
                helperText={errors.lastName?.message}
              />
            </Grid>
          </Grid>
        ))}
        <AddIcon style={{ cursor: "pointer" }} onClick={addEducation} />
        <MIButton
          label={id ? "Update" : "Save"}
          type="submit"
          style={{ marginTop: "2%", marginBottom: "1%" }}
        />
      </form>
    </>
  );
}

I am new to React js Hence suggestions and fixes are most welcome. Kindly please let me know if still need any further details and share your answer Hence I can fix the above issue.


Thank you!

1

There are 1 answers

0
Kishan Bhensadadiya On

Here is the answer!

<InputText
  label={"Education"} 
  name={`edu[${index}].education`}
  onChange={onInputChange}
  control={control}
  value={row.education}
/>

I have used the name as name={edu[${index}].education} and it works perfectly