Home > Mobile >  Dissable button if input empty and have errors
Dissable button if input empty and have errors

Time:01-17

I'm building registration form. I have signup.tsx which has validation for inputs. But I ran into a problem, I want to disable the button if the inputs are empty and if the inputs have one or more error during registration. I have no idea how to disable button with disable={} I'm trying to do like this: disable={!input}. But of course it's not right

My code of signup.tsx:

import React, { useState } from 'react';
import './signup.css';

function Signup() {

const [input, setInput] = useState({
    username: "",
    email: "",
    password: ""
});

const [error, setError] = useState({
    username: "",
    email: "",
    password: ""
});

const onInputChange = (e: any) => {
      const { name, value } = e.target;
      setInput(prev => ({
        ...prev,
        [name]: value
      }));
      validateInput(e);
};
const validateInput = (e: any) => {
  let { name, value } = e.target;
  setError(prev => {
  const stateObj = { ...prev, [name]: "" };
  const minLengthUser = /.{4,}/;
  const minLengthUsername = minLengthUser.test(value);
  const minLenghtPass = /.{6,}/;
  const minLenghtPassword = minLenghtPass.test(value);

switch (name) {
  case "username":
    if (!value) {
      stateObj[name as keyof typeof stateObj] = "Username is required";
    } else if (!minLengthUsername) {
        stateObj[name as keyof typeof stateObj] = "Username should be minimum 4 characters"
    };
break;

  case "email":
    if (!value) {
        stateObj[name as keyof typeof stateObj] = "Email address is required"
    } else if (!/^[A-Z0-9._% -] @[A-Z0-9.-] \.[A-Z]{2,4}$/i.test(input.email)) {
        stateObj[name as keyof typeof stateObj] = 'Invalid email address'
    }
  break;

  case "password":
    if (!value) {
      stateObj[name as keyof typeof stateObj] = "Password is required";
    } else if (!minLenghtPassword) {
        stateObj[name as keyof typeof stateObj] = "Password should be minimum 6 characters";
    }
  break;

  default:
  break;
}

return stateObj;
});
}

return (
<div className="container">
 <div className="box">
    <h1>
      <p className="title">Create an account</p>
    </h1>
    <form className="form">
        <div className="form-outline">
            <label className="input-label">Your Name</label>
            <input
              name="username"
              type="text"
              className="input"
              value={input.username}
              onChange={onInputChange}
              onBlur={validateInput}
            />
            {error.username && <div className="alert"><span className="err">{error.username}</span></div>}
        </div>

        <div className="form-outline">
            <label className="input-label">Your Email</label>
            <input
              name="email"
              type="email"
              className="input"
              value={input.email}
              onChange={onInputChange}
              onBlur={validateInput}
            />
            {error.email && <div className="alert"><span className="err">{error.email}</span></div>}
        </div>

        <div className="form-outline">
            <label className="input-label">Password</label>
            <input
              name="password"
              type="password"
              className="input"
              value={input.password}
              onChange={onInputChange}
              onBlur={validateInput}
            />
            {error.password && <div className="alert"><span className='err'>{error.password}</span></div>}
        </div>

        <div className="button">
            <button className="btn">Create account</button>
        </div>

    </form>
 </div>
</div>
)
}

export default Signup;

CodePudding user response:

You could create a method isInputValid which returns a boolean. It loops over the error object checking errors if they're not the default value "" return false. If they all are the default return true.

const isInputValid = Object.values(error).reduce((isValid: boolean, err) => {
  if (err !== "") return false;
  // will return true if isValid is true else returns false
  return isValid && true;
}, true);

Which you can use like this

<button className="btn" disabled={!isInputValid}>
  Create account
</button>

EDIT:

To disable the button at the start, you can use null as a value.

type ErrorType = {
  username: string | null;
  email: string | null;
  password: string | null;
};

const [error, setError] = useState<ErrorType>({
  username: null,
  email: null,
  password: null,
});
const isValid = Object.values(error).reduce((isValid: boolean, error) => {
  if (error === null || error !== "") return false;
  return isValid && true;
}, true);
  • Related