Home > Software engineering >  Having Issues with Form Validation for a SignUp component
Having Issues with Form Validation for a SignUp component

Time:09-22

I have a Sign Up Component in my current project, and I'm trying to implement validation for the email and phone number.

Code:


export default function Form() {

// States for registration
const [firstname, setFirstName] = useState('');
const [lastname, setLastName] = useState('');
const [email, setEmail] = useState('');
const [phonenumber, setPhoneNumber] = useState('');

// States for checking the errors
const [submitted, setSubmitted] = useState(false);
const [error, setError] = useState(false);

// Handling the email change
const handleEmail = (e) => {
    setEmail(e.target.value);
    setSubmitted(false);
};

// Handling the phonenumber change
const handlePhoneNumber = (e) => {
    setPhoneNumber(e.target.value);
    setSubmitted(false);
};

// Handling the form submission
const handleSubmit = (e) => {
    e.preventDefault();
    if (email === '' || phonenumber === '') {
    setError(true);
    } else {
    setSubmitted(true);
    setError(false);
    }
};



// Showing error message if error is true
const errorMessage = () => {
    return (
    <div
        className="error"
        style={{
        display: error ? '' : 'none',
        }}>
        <h1>Please enter all the fields</h1>
    </div>
    );
};

return (
    <div className="form">

    <div className="messages">
        {errorMessage()}
        {successMessage()}
    </div>
        <div className='inputval'>
            <div className="d-flex justify-content-center flex-column">
                <label className="label">Email</label>
                <input onChange={handleEmail} className="input"
                value={email} type="email" />
                <label className="label">Phone Number</label>
                <input onChange={handlePhoneNumber} className="input"
                value={phonenumber} type="email" />
            </div>
            
            <div className="d-inline-block justify-content-center align-items-center">
                <button className="btn" onClick={handleSubmit}  type="submit">
                Submit
                </button>
            </div>
            
            
        </div>
    </div>
);
}

For the most part, I tried implementing /^(([^<>()[\]\.,;:\s@\"] (\.[^<>()[\]\.,;:\s@\"] )*)|(\". \"))@(([^<>()[\]\.,;:\s@\"] \.) [^<>()[\]\.,;:\s@\"]{2,})$/i for the format constant in my email but I had no luck. I have a useState hook that checks if the boxes are empty, but if I could get some assistance on this, it would be much appreciated!

CodePudding user response:

There are a lot of form validation npm tools that will help alot. But if you want to do everything custom and understand about how it will work, here is a quick project demonstrating how to go about it. I would recommend putting some of the helper functions in different files so they can be used everywhere in your app. CodeSandbox: https://codesandbox.io/s/simple-form-validation-jqfvpy?file=/src/Input.js:0-325

export default function App() {
  const [form, setForm] = useState({ name: "", email: "", phone: "" });
  const [errors, setErrors] = useState({ name: [], email: [], phone: [] });

  const checkRules = (input, rules) => {
    let errors = [];
    let value = input;
    if (typeof value === "string") value = input.trim();

    if (rules.required) {
      if (value === "") errors.push("*This field is required.");
    }
    if (rules.phone) {
      let phoneno = new RegExp(/^\(?(\d{3})\)?[-. ]?(\d{3})[-. ]?(\d{4})$/);
      if (!phoneno.test(value))
        errors.push("*Please Enter valid phone number XXX-XXX-XXXX");
    }
    if (rules.email) {
      let pattern = new RegExp(
        /^(("[\w-\s] ")|([\w-] (?:\.[\w-] )*)|("[\w-\s] ")([\w-] (?:\.[\w-] )*))(@((?:[\w-] \.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i
      );
      if (!pattern.test(value)) errors.push("*Please enter a valid email.");
    }

    return errors;
  };

  const checkFormValidation = (f) => {
    const errors = {};

    errors.name = checkRules(f.name, { required: true });
    errors.phone = checkRules(f.phone, { phone: true });
    errors.email = checkRules(f.email, { email: true });

    for (const [, value] of Object.entries(errors)) {
      if (value.length > 0) return { noErrors: false, errors };
    }

    return { noErrors: true, errors };
  };

  const handleSubmit = (f) => {
    const { errors, noErrors } = checkFormValidation(f);
    setErrors(errors);
    if (noErrors) {
      alert(JSON.stringify(f));
    }
  };
  return (
    <div className="App">
      <div style={{ display: "grid", placeItems: "center" }}>
        <Input
          name="Name"
          value={form.name}
          errors={errors.name}
          onChange={(e) => setForm({ ...form, name: e.target.value })}
        />
        <Input
          name="Email"
          value={form.email}
          errors={errors.email}
          onChange={(e) => setForm({ ...form, email: e.target.value })}
        />
        <Input
          name="Phone"
          value={form.phone}
          errors={errors.phone}
          onChange={(e) => setForm({ ...form, phone: e.target.value })}
        />
        <button onClick={() => handleSubmit(form)}>Submit</button>
      </div>
    </div>
  );
}

export const Input = ({ name, value, onChange, errors }) => {
  return (
    <>
      <input type="text" placeholder={name} value={value} onChange={onChange} />
      {errors.length > 0
        ? errors.map((e) => (
            <p style={{ fontSize: "9px", color: "red" }}>{e}</p>
          ))
        : null}
    </>
  );
};
  • Related