Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>
  }
})
like image 987
Khalil Gharbaoui Avatar asked Mar 14 '16 01:03

Khalil Gharbaoui


People also ask

How to disable or enable submit button until all forms are filled?

To disable or enable submit button until all forms have been filled with JavaScript, we can set the disabled property according to the input values. We have a form that has 2 text inputs and a submit button. Then to enable the submit button only when all the text inputs are filled, we write:

How do I add a submit button to a formula?

Unfortunately, you'll most likely need to consider a formula that includes all your required fields and any logic necessary to validate the fields and thus allow a submit button to be enabled. I often do this with a hidden Toggle control on the screen. Set the Default property to your formula then have the submit button key off of the toggle.

Is there a way to enable the submit button on screen?

Unfortunately, you'll most likely need to consider a formula that includes all your required fields and any logic necessary to validate the fields and thus allow a submit button to be enabled. I often do this with a hidden Toggle control on the screen.

What do we need to make a button disable?

And with controlled inputs to make it a reality, there isn't much we need! Having immediate access to fields' values is crucial for our ability to disable the button. Therefore, the requirement for this recipe is a form with controlled inputs. Suppose we have a sign-up form with just two fields, email and password:


3 Answers

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.

like image 73
wintvelt Avatar answered Sep 21 '22 00:09

wintvelt


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/

like image 30
Andreyco Avatar answered Sep 18 '22 00:09

Andreyco


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>
  );
};
like image 33
Shafie Mukhre Avatar answered Sep 21 '22 00:09

Shafie Mukhre