How to disable form submit button until all input fields are filled?! ReactJS ES2015

Hi i found an answer to this for a single field form… but what if we have a form with multiple field?

this is fine for disabling it if you have 1 field but it does not work when you want to disable it based on many fields:

getInitialState() {
    return {email: ''}
  },
  handleChange(e) {
    this.setState({email: e.target.value})
  },
  render() {
    return <div>
      <input name="email" value={this.state.email} onChange={this.handleChange}/>
      <button type="button" disabled={!this.state.email}>Button</button>
    </div>
  }
})

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Here is a basic setup for form validation:

getInitialState() {
    return {
      email: '',
      text: '',
      emailValid: false,         // valid flags for each field
      textValid: false, 
      submitDisabled: true       // separate flag for submit
    }
  },
  handleChangeEmail(e) {         // separate handler for each field
    let emailValid = e.target.value ? true : false;        // basic email validation
    let submitValid = this.state.textValid && emailvalid   // validate total form
    this.setState({
      email: e.target.value
      emailValid: emailValid, 
      submitDisabled: !submitValid
    })
  },
  handleChangeText(e) {         // separate handler for each field
    let textValid = e.target.value ? true : false;        // basic text validation
    let submitValid = this.state.emailValid && textvalid   // validate total form
    this.setState({
      text: '',
      textValid: textValid, 
      submitDisabled: !submitValid
    })
  },
  render() {
    return <div>
      <input name="email" value={this.state.email} onChange={this.handleChangeEmail}/>
      <input name="text" value={this.state.text} onChange={this.handleChangeText}/>
      <button type="button" disabled={this.state.submitDisabled}>Button</button>
    </div>
  }
})

In a more elaborate setup, you may want to put each input field in a separate component. And make the code more DRY (note the duplication in the change handlers).
There are also various solutions for react forms out there, like here.

Method 2

I would take a little bit different way here…

Instead of setting submitDisabled in every single onChange handler I would hook into lifecycle method to listen to changes.
To be exact into componentWillUpdate(nextProps, nextState). This method is invoked before every change to component – either props change or state change. Here, you can validate your form data and set flag you need – all in one place.
Code example:

componentWillUpdate(nextProps, nextState) {
  nextState.invalidData = !(nextState.email && nextState.password);
},

Full working fiddle https://jsfiddle.net/4emdsb28/

Method 3

This is how I’d do it by only rendering the normal button element if and only if all input fields are filled where all the states for my input elements are true. Else, it will render a disabled button.

Below is an example incorporating the useState hook and creating a component SubmitButton with the if statement.

import React, { useState } from 'react';

export function App() {
  const [firstname, setFirstname] = useState('');
  const [lastname, setLastname] = useState('');
  const [email, setEmail] = useState('');
    
  function SubmitButton(){
    if (firstname && lastname && email){
      return <button type="button">Button</button>
    } else {
      return <button type="button" disabled>Button</button>
    };
  };

  return (
    <div>
      <input value={email} onChange={ e => setEmail(e.target.value)}/>
      <input value={firstname} onChange={ e => setFirstname(e.target.value)}/>
      <input value={lastname} onChange={ e => setLastname(e.target.value)}/>
      <SubmitButton/>
    </div>
  );
};

Method 4

This might help. (credits – https://goshakkk.name/form-recipe-disable-submit-button-react/)

import React from "react";
import ReactDOM from "react-dom";

class SignUpForm extends React.Component {
  constructor() {
    super();
    this.state = {
      email: "",
      password: ""
    };
  }

  handleEmailChange = evt => {
    this.setState({ email: evt.target.value });
  };

  handlePasswordChange = evt => {
    this.setState({ password: evt.target.value });
  };

  handleSubmit = () => {
    const { email, password } = this.state;
    alert(`Signed up with email: ${email} password: ${password}`);
  };

  render() {
    const { email, password } = this.state;
    const isEnabled = email.length > 0 && password.length > 0;
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type="text"
          placeholder="Enter email"
          value={this.state.email}
          onChange={this.handleEmailChange}
        />
        <input
          type="password"
          placeholder="Enter password"
          value={this.state.password}
          onChange={this.handlePasswordChange}
        />
        <button disabled={!isEnabled}>Sign up</button>
      </form>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<SignUpForm />, rootElement);

Method 5

  export default function SignUpForm() {

    const [firstName, onChangeFirstName] = useState("");
    const [lastName, onChangeLastName] = useState("");
    const [phoneNumber, onChangePhoneNumber] = useState("");

    const areAllFieldsFilled = (firstName != "") && (lastName != "") && (phoneNumber != "")

    return (
      <Button
        title="SUBMIT"
        disabled={!areAllFieldsFilled}
        onPress={() => {
          signIn()
        }
        }
      />
    )
    }

Similar approach as Shafie Mukhre’s!


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x