Home > front end >  Fill disabled form input based on select option - React
Fill disabled form input based on select option - React

Time:10-16

I'm building a form that has a select component that is wrapped with an array from an API MySQL "get" call. The array contains 3 items; userID, firstName and lastName.

Upon making a selection, the value of the select input is set the the selected userID which is then sent back to the same API. I also have two disabled input fields directly below the select component that I would like to automatically populate with the firstName and lastName based on the option the user selects.

States used:

const [userID, setUserID] = useState("");
const [studentOption, setStudentOption] = useState([]);
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");

useEffect to set state of select component

useEffect(() => {
  const config = {
    headers: { "x-auth-token": token },
  };

  const fetchData = async () => {
    const results = await api.get("/students/userID", config);
    setStudentOption(results.data);
  };

  fetchData();
}, [setStudentOption, token]);

Select Component:

<select
  className="form-select"
  aria-label="Default select example"
  onChange={(e) => setUserID(e.target.value)}
>
  <option>Select Student User Account</option>
  {studentOption.map((studentOption) => (
    <option key={studentOption.userID} value={studentOption.userID}>
      {studentOption.firstName} {studentOption.lastName}
    </option>
  ))}
</select>

The 2 input fields

<div className="row">
  <div className="col-md-6">
    <input
      disabled
      type="text"
      className="form-control"
      placeholder="Student First Name"
      onChange={(e) => setFirstName(e.target.value)}
      value={firstName}
    />
  </div>
  <div className="col-md-6">
    <input
      disabled
      type="text"
      className="form-control"
      placeholder="Student Last Name"
      onChange={(e) => setLastName(e.target.value)}
      value={lastName}
    />
  </div>
</div>

API controller for the get query

export const studentID = (req, res) => {
  db.query(
    "SELECT userID, firstName, lastName  FROM userIndex WHERE role = 'student' ORDER BY firstName ASC;",
    (err, rows) => {
      if (!err) {
        res.send(rows);
      } else {
        console.log(err).res.send({ alert: err });
      }
    }
  );
};

I can't quite figure out the correct state changes for this one. I would appreciate any help! Let me know if I can supply any more code - thanks in advance.

CodePudding user response:

I suppose the studentOptions array looks something like this. [{'id':'12','fname':'anu','lname':'sr'},{'id':'123','fname':'surya','lname':'r'}] Then you can try like below.

<select
  className="form-select"
  aria-label="Default select example"
  onChange={(e) => {
    setUserID(e.target.value)
    setFirstName(studentOption.filter((s)=>s.id===e.target.id)[0].fname)
    setLastName(studentOption.filter((s)=>s.id===e.target.id)[0].fname)
    }}
>

Note this will change the first name and last name everytime when the select is changed by user.

Let me know if the studentOption has a different structure or if you can share a codesandbox we can check for optimal solution.

CodePudding user response:

Found a solution to the issue.

In the select component, I left everything as above. All it does is set the userID state.

Then I implemented a useEffect hook with an if statement to call the API for the firstName and lastName values and set them in the state, using the userID state value as a dependency. If userID is null, the useEffect doesn't run and vice versa.

Select Component

<select
  className="form-select"
  aria-label="Default select example"
  onChange={(e) => setUserID(e.target.value)}
>
  <option>Select Student User Account</option>
  {studentOption.map((studentOption) => (
    <option key={studentOption.userID} value={studentOption.userID}>
      {studentOption.firstName} {studentOption.lastName}
    </option>
  ))}
</select>;

useEffect hook

useEffect(() => {
    const config = {
      headers: { "x-auth-token": token },
    };

    const fetchData = async () => {
      const results = await api.get("/students/studentadd/"   userID, config);
      setFirstName(results.data[0].firstName);
      setLastName(results.data[0].lastName);
    };
    if (userID) {
      fetchData();
    }
  }, [userID, token]);

I hope this helps anyone struggling with the same issue. Note this could does invoke another API call, so server usage could be impacted.

If anyone has a more elegant solution, I'm all ears.

  • Related