0

Im new to reactJS. Im wondering why my code below doesnt work. Everything works except disabling my NEXT button when text fields are empty. My expectation is that after i fill out ALL the textboxes, the NEXT button will be enabled.

class Registration extends React.Component { constructor (props) { super (props); this.state = { selectedGender: null, errors: [], initComplete: false } this._handleSubmit = this._handleSubmit.bind(this); this._handleInputMobileOnChange = this._handleInputMobileOnChange.bind(this); this.clearError = this.clearError.bind(this); } clearError () { this.setState({ errors: [] }); } _handleInputMobileOnChange (e) { e.preventDefault(); this.clearError(); e.target.value = utils.removeNonNumbers(e.target.value); //this.setState({value: e.target.value}) } change(e){ if("" != e.target.value){ this.button.disabled = false; } else{ this.button.disabled = true; } } render() { return ( <div className="container-fluid"> <form onSubmit={this._handleSubmit}> <div className="form-group has-danger"> <label htmlFor="input-MobileNum">number *</label> <input ref={(ref) => this.inputMobile = ref} type="tel" className={'form-control ' } id="input-MobileNum" onChange={()=>{ this._handleInputMobileOnChange; this.change.bind(this)}} defaultValue=""/> </div> <div className="form-group has-danger"> <label htmlFor="input-Email">Email address *</label> <input ref={(ref) => this.inputEmail = ref} type="email" className={'form-control '} id="input-Email" defaultValue="" onChange={()=>{ this.clearError; this.change.bind(this)}}/> </div> <div className="form-group has-danger"> <label htmlFor="input-Invitation">Invitation code</label> <input ref={(ref) => this.inputInvitation = ref} type="text" className={'form-control '} id="input-Invitation" defaultValue="" onChange={()=>{ this.clearError; this.change.bind(this)}}/> </div> <div className="form-group cta"> //NEXT BUTTON <button type="submit" className="btn btn-primary" ref={(button) => this.button=button}>Next</button> </div> </form> </div> ) } 

THANKS!!!

I updated my code to this. And i tested it case by case. Only mobile works, the email and invitation code dont work for some reason.

class Registration extends React.Component { constructor (props) { super (props); this.state = { selectedGender: null, errors: [], initComplete: false } this._handleSubmit = this._handleSubmit.bind(this); this._handleInputMobileOnChange = this._handleInputMobileOnChange.bind(this); this._handleInputEmailOnChange = this._handleInputEmailOnChange.bind(this); this._handleInputInvitationOnChange = this._handleInputInvitationOnChange.bind(this); this.clearError = this.clearError.bind(this); } clearError () { this.setState({ errors: [] }); } disable(){ let disable = true; if (this.state.inputMobile || this.state.inputEmail || this.state.inputInvitation) { //I tried && operator, still only mobile works disable = false; } return disable; } _handleInputMobileOnChange (e) { e.preventDefault(); this.clearError(); e.target.value = utils.removeNonNumbers(e.target.value); this.setState({inputMobile: e.target.value}) } _handleInputEmailOnChange(e){ e.preventDefault(); this.clearError(); e.target.value = utils.removeNonNumbers(e.target.value); this.setState({inputEmail: e.target.value}) } _handleInputInvitationOnChange(e){ e.preventDefault(); this.clearError(); e.target.value = utils.removeNonNumbers(e.target.value); this.setState({inputInvitation: e.target.value}) } change(e){ if("" != e.target.value){ this.button.disabled = false; } else{ this.button.disabled = true; } } render() { return ( <div className="container-fluid"> <form onSubmit={this._handleSubmit}> <div className="form-group has-danger"> <label htmlFor="input-MobileNum">number *</label> <input ref={(ref) => this.inputMobile = ref} type="tel" className={'form-control ' } id="input-MobileNum" onChange={this._handleInputMobileOnChange}} defaultValue=""/> </div> <div className="form-group has-danger"> <label htmlFor="input-Email">Email address *</label> <input ref={(ref) => this.inputEmail = ref} type="email" className={'form-control '} id="input-Email" defaultValue="" onChange={this._handleInputEmailOnChange}/> </div> <div className="form-group has-danger"> <label htmlFor="input-Invitation">Invitation code</label> <input ref={(ref) => this.inputInvitation = ref} type="text" className={'form-control '} id="input-Invitation" defaultValue="" onChange={this._handleInputInvitationOnChange}/> </div> <div className="form-group cta"> //NEXT BUTTON <button type="submit" className="btn btn-primary" disabled={this.disable()}>Next</button> </div> </form> </div> ) } 

Nvm. I was being stupid. The code above works! :)))

2 Answers 2

1

You should consider using controlled input elements rather than uncontrolled. This lets react manage the values of your input elements which makes things a bit easier.

First of all start by adding the initial values of each input element to to your constructor. You probably just want empty strings here ("").

Then, add a change event listener for each input element and create a function for each. Each such function should then check what the value for the other elements are, as well as its own, and then enable or disable the button.


Demo:

class Registration extends React.Component { constructor (props) { super(props); this.state = { selectedGender: null, errors: [], initComplete: false, buttonIsDisabled: true, numberValue: "", emailValue: "", codeValue: "", } this.changeNumber = this.changeNumber.bind(this); this.changeEmail = this.changeEmail.bind(this) this.changeCode = this.changeCode.bind(this); } changeNumber = (e) => { let s = true; if(this.state.emailValue.length && this.state.codeValue.length && e.target.value.length) { s = false; } let val = e.target.value; //let val = utils.removeNonNumbers(e.target.value); this.setState({numberValue: val, buttonIsDisabled: s, errors: []}); } changeEmail = (e) => { let s = true; if(this.state.numberValue.length && this.state.codeValue.length && e.target.value.length) { s = false; } this.setState({emailValue: e.target.value, buttonIsDisabled: s, errors: []}); } changeCode = (e) => { let s = true; if(this.state.numberValue.length && this.state.emailValue.length && e.target.value.length) { s = false; } this.setState({codeValue: e.target.value, buttonIsDisabled: s, errors: []}); } render() { return ( <div className="container-fluid"> <form onSubmit={this._handleSubmit}> <div className="form-group has-danger"> <label htmlFor="input-MobileNum">number *</label> <input type="tel" className={'form-control ' } id="input-MobileNum" onChange={this.changeNumber} /> </div> <div className="form-group has-danger"> <label htmlFor="input-Email">Email address *</label> <input type="email" className={'form-control '} id="input-Email" onChange={this.changeEmail} /> </div> <div className="form-group has-danger"> <label htmlFor="input-Invitation">Invitation code</label> <input type="text" className={'form-control '} id="input-Invitation" onChange={this.changeCode} /> </div> <div className="form-group cta"> <button type="submit" className="btn btn-primary" disabled={this.state.buttonIsDisabled} ref={(button) => this.button=button}>Next</button> </div> </form> </div> ) }} ReactDOM.render(<Registration />, document.getElementById("myApp"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="myApp"></div>

Sign up to request clarification or add additional context in comments.

Comments

0

Keep a state disabled and then on change function check whether all inputs have value , then set the state disabled to false like below snippet

class Registration extends React.Component { constructor (props) { super (props); this.state = { selectedGender: null, errors: [], initComplete: false, disabled: true } this._handleSubmit = this._handleSubmit.bind(this); this._handleInputMobileOnChange = this._handleInputMobileOnChange.bind(this); this.clearError = this.clearError.bind(this); } clearError () { this.setState({ errors: [] }); } _handleInputMobileOnChange (e) { e.preventDefault(); this.clearError(); e.target.value = utils.removeNonNumbers(e.target.value); //this.setState({value: e.target.value}) } change = () => { if(this.inputMobile !== '' && this.inputEmail !== '' && this.inputInvitation != '' ) { this.setState({disabled: false}); } } render() { return ( <div className="container-fluid"> <form onSubmit={this._handleSubmit}> <div className="form-group has-danger"> <label htmlFor="input-MobileNum">number *</label> <input ref={(ref) => this.inputMobile = ref} type="tel" className={'form-control ' } id="input-MobileNum" onChange={()=>{ this._handleInputMobileOnChange; this.change.bind(this)}} defaultValue=""/> </div> <div className="form-group has-danger"> <label htmlFor="input-Email">Email address *</label> <input ref={(ref) => this.inputEmail = ref} type="email" className={'form-control '} id="input-Email" defaultValue="" onChange={()=>{ this.clearError; this.change.bind(this)}}/> </div> <div className="form-group has-danger"> <label htmlFor="input-Invitation">Invitation code</label> <input ref={(ref) => this.inputInvitation = ref} type="text" className={'form-control '} id="input-Invitation" defaultValue="" onChange={()=>{ this.clearError; this.change.bind(this)}}/> </div> <div className="form-group cta"> //NEXT BUTTON <button type="submit" className="btn btn-primary" ref={(button) => this.button=button} disabled={this.state.disabled}>Next</button> </div> </form> </div> ) } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.