2

I am trying to get the values of all the input elements in a form in React. Here is my form



export default function MarkAttendance() {

  const dispatch = useDispatch();
  const navigate = useNavigate();

  const { users, loading, error } = useSelector((state) => state.userList);
  const today = new Date().toISOString().substr(0, 10);
  const { userInfo } = useSelector((state) => state.userLogin);
  const [firstTime, setFirstTime] = useState('')
  const [secondTime, setSecondTime] = useState('')
  const [attenandance, setAttendance] = useState({ id: null, date: today, first_time: "Present", second_time: "Present" });

  useEffect(() => {
    if (userInfo && userInfo.isAdmin) {
      dispatch(listUsers());

    } else {
      navigate("/login");
    }

  }, [dispatch, userInfo, navigate]);

  const handleSubmit = (e) => {
    e.preventDefault();


    for (let i = 0; i < users.length; i++) {
      setAttendance({ id: users[i].id, date: today, first_time: firstTime, second_time: secondTime });

      postAttendance(attenandance);

    }
  }

  return (
      <section>
        <div className="row">
          <div className="col-md-12 text-dark">
            <h3>Mark Attendance</h3> for <h4>{today}</h4>'s meal
          </div>
        </div>
        {loading ? (
          <Loader />
        ) : error ? (
          <Message variant="danger">{error}</Message>
        ) : (
          <form onSubmit={handleSubmit}>
            <table className="table table-bordered">
              <thead>
                <tr>
                  <th scope="col">#</th>
                  <th scope="col">Name</th>
                  <th scope="col">Room no.</th>
                  <th scope="col">First Time</th>
                  <th scope="col">Second Time</th>
                </tr>
              </thead>
              <tbody>

                {users.map((user) => (
                  <tr key={user.id}>


                    <th scope="row" name="userId">{user.id}</th>
                    <td className="form-group">
                      <input

                        type="text"
                        className="form-control"
                        id="table-name"
                        name="username"
                        value={user.username}

                      />
                    </td>
                    <td className="form-group">
                      <input
                        type="text"
                        className="form-control"
                        id="table-room"
                        name="room"
                        value={user.room}

                      />

                    </td>

                    <td>
                      <select name={`firstAttendance${user.id}`} onChange={(e) => (e.target.value)} className="form-control" id="table-first-time">
                        <option value="present">Present ✓</option>
                        <option value="absent">Absent X</option>
                        <option value="double">Double 2</option>
                      </select>

                    </td>
                    <td>
                      <select name={`secondAttendance${user.id}`} onChange={(e) => (e.target.value)} className="form-control" id="table-second-time">
                        <option value="present">Present ✓</option>
                        <option value="absent">Absent X</option>
                        <option value="double">Double 2</option>
                      </select>

                    </td>
                  </tr>
                ))}
              </tbody>
            </table>

            <button type="submit" className="btn btn-primary">
              Submit
            </button>
          </form>

        )}
      </section >
  );
}

What I am want is get the select values along with user ids and send it back to the server . I don't know how to get the user id and what he has selected in the form . It is made by a map function which means name attriutes are all gonna be same .

What I have tried

  1. I tried to change the name attribute dynamically but it still give me undefined.
  2. I tried to use useState hook but it only gives me the value of last users and this also changes the value of other users since there is only one hook for all.

So how to get all the values in a form in reactjs. Thanks

Hasnain Sikander
  • 341
  • 3
  • 13
  • Does this [answer](https://stackoverflow.com/a/47678799/13405106) work? Can you create a working example in codesandbox? – Usama Jun 22 '22 at 05:33
  • Thank you very much for the answer. I have tried it but I am only be able to get last values of form and not all – Hasnain Sikander Jun 23 '22 at 00:32

1 Answers1

0

So after some time , I finally use the trick to get all the values. What I did is give each input tag , a separate id by incorporating the user-id of each user in input tag id .As each user have a unique id so did the input and selection tag . Then extracting the values of desired input first_time and second_time by providing user-id , looping through each inputs and getting separate values for all the users and dispatching them on postAttendance. Here is how it look like:


  const handleSubmit = (e) => {
    e.preventDefault();
    try {
      const attendanceExtractor = (e, id) => {
        let first_time = e.target.elements[`first-attendance-${id}`].value;
        let second_time = e.target.elements[`second-attendance-${id}`].value;

        return [first_time, second_time]
      }  // writing a separate function for extracting each value


// then looping through each 
      for (let index = 0; index < userIds.length; index++) {
        let id = userIds[index];

        const attendance = {
          student: id,
          date: date,
          first_time: attendanceExtractor(e, id)[0],
          second_time: attendanceExtractor(e, id)[1]
        }
        dispatch(postAttendance(attendance, id))
      }
      alert("All the attendance is submitted successfully")
      dispatch(getAttendance());
      let count = counter(getAttendanceObj, date);
      setTotal(count)

      console.log(count)
    } catch (error) {

    }
  }

and the form look like this:

  <form className="form" onSubmit={handleSubmit}>

              <table className="table table-bordered">
                <thead>
                  <tr>
                    <th scope="col">#</th>
                    <th scope="col">Name</th>
                    <th scope="col">Room no.</th>
                    <th scope="col">First Time</th>
                    <th scope="col">Second Time</th>
                    <th scope="col">Status</th>
                  </tr>
                </thead>

                {users.map((user) => (


                  <tbody>




                    <tr key={user.id}>


                      <th scope="row" id={`user-id-${user.id}}`}>{user.id}</th>
                      <td className="form-group">
                        <input

                          type="text"
                          className="form-control"
                          id={`table-name-${user.id}`}
                          name="username"
                          value={user.username}

                        />
                      </td>
                      <td className="form-group">
                        <input
                          type="text"
                          className="form-control"
                          id={`table-ropm-${user.id}`}
                          name="room"
                          value={user.room}

                        />

                      </td>

                      <td>
                        <select id={`first-attendance-${user.id}`} onChange={(e) => (e.target.value)} className="form-control" >
                          <option value="present">Present ✓</option>
                          <option value="absent">Absent X</option>
                          <option value="double">Double 2</option>
                        </select>

                      </td>
                      <td>
                        <select id={`second-attendance-${user.id}`} onChange={(e) => (e.target.value)} className="form-control" > // FOCUS ON ID
                          <option value="present">Present ✓</option>
                          <option value="absent">Absent X</option>
                          <option value="double">Double 2</option>
                        </select>

                      </td>
                      <td>
                        <i class="bi bi-check" ></i>
                      </td>
                    </tr>

                  </tbody>
                ))
                }

              </table>
              <button type="submit" className="btn btn-primary">
                Submit
              </button>

            </form>
Hasnain Sikander
  • 341
  • 3
  • 13