How to setErrorValidation for the specific input field that is causing that validation error?

Viewed 14

What im trying to do is to put an error validation message under the input field that is empty.

The error validation is shown, but the problem is that is shown for every input form that exists on the component, and not in the input form that is empty.

  const [user, setUser] = useState({
    firstName: "",
    lastName: "",
    email: "",
  });

  const [errorMsg, setErrorMsg] = useState("");

  const handleItemChanged = (event) => {
    const { name, value } = event.target;
    console.log(name, value);
    setUser({ ...user, [name]: value });

    const regex = /^[A-Za-z0-9_-]{1,128}$/;
    if (regex.test(value) === false) {
      setErrorMsg(
        "The field is empty"
      );
    } else {
      setErrorMsg("");
    }
  };

return(
      <div>
         <div>
            <label
                htmlFor="firstName"
              >
                First Name
              </label>
              <div>
                <input
                  type="text"
                  name="firstName"
                  onChange={(event) => handleItemChanged(event)}
                  autoComplete="off"
                />
                {errorValidation && (
                  <div className="text-color-error">
                    <label htmlFor="username" className="block"></label>
                    <div className="sm:col-span-2">
                      <svg
                        xmlns="http://www.w3.org/2000/svg"
                        className="inline-block mr-2 h-5 w-5"
                        viewBox="0 0 20 20"
                        fill="currentColor"
                      >
                        <path
                          fillRule="evenodd"
                          d="M18 10a8 8 0 11-16 0 8 8 0 0116
                        0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1
                        0 102 0V6a1 1 0 00-1-1z"
                          clipRule="evenodd"
                        />
                      </svg>{" "}
                      {errorValidation}
                      {""}
                    </div>
                  </div>
                )}
              </div>
            </div>

         <div>
            <label
                htmlFor="lastName"
              >
                Last Name
              </label>
              <div>
                <input
                  type="text"
                  name="lastName"
                  onChange={(event) => handleItemChanged(event)}
                  autoComplete="off"
                />
                {errorValidation && (
                  <div className="text-color-error">
                    <label htmlFor="username" className="block"></label>
                    <div className="sm:col-span-2">
                      <svg
                        xmlns="http://www.w3.org/2000/svg"
                        className="inline-block mr-2 h-5 w-5"
                        viewBox="0 0 20 20"
                        fill="currentColor"
                      >
                        <path
                          fillRule="evenodd"
                          d="M18 10a8 8 0 11-16 0 8 8 0 0116
                        0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1
                        0 102 0V6a1 1 0 00-1-1z"
                          clipRule="evenodd"
                        />
                      </svg>{" "}
                      {errorValidation}
                      {""}
                    </div>
                  </div>
                )}
              </div>
            </div>
             ...
       </div>
);

So what happens, is that if the first name is empty, last name not empty, email not empty, the error message will be shown under first name, last name and email input. What I want is for error message to be shown only under the input that is empyt(first name input in this case.)

How can I solve it?

1 Answers

You can do that by creating an object that holds key-value pairs where the key is the name of the input that has the error and the value is the error message. That way, you can separate the parts that have errors and the ones that do not.

example:

const [errorMsg, setErrorMsg] = useState({
  emailError: "",
  userError: "",
});

When handling an error, you can make use of event.target to identify the component that created the error and set its error message while keeping everything else:

const [user, setUser] = useState({
    firstName: '',
    lastName: '',
    email: '',
  });

  const [errorMsg, setErrorMsg] = useState({
    firstName: '',
    lastName: '',
    email: '',
  });

  const handleItemChanged = (event) => {
    const { name, value } = event.target;
    console.log(name, value);
    setUser({ ...user, [name]: value });

    const regex = /^[A-Za-z0-9_-]{1,128}$/;
    if (regex.test(value) === false) {
      setErrorMsg({ ...errorMsg, [name]: 'The field is empty' });
    } 
    console.log(errorMsg)
  };
Related