How to get my input validation and disabling/enabling my submit button depending on the state of the form in...
I am using npm Validator and trying to validate the input info and then change the state of the submit address button depending on the validation. The way I have it set up now I can type and the text shows in the console but not in the UI. I'm not sure what I have wrong. The button will not change to 'enabled' either.
Here is the component:
import React, {Component} from 'react';
import { CardElement, injectStripe } from 'react-stripe-elements';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { clearCart } from '../actions/clearCartAction';
import getTotal from '../helpers/getTotalHelper';
import { Container, Col, Form, FormGroup, Input, Button } from 'reactstrap';
import './StripeCheckoutForm.css';
import validator from 'validator';
const cardElement = {
base: {
color: '#32325d',
width: '50%',
lineHeight: '30px',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '18px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
const FIREBASE_FUNCTION = 'https://us-central1-velo-velo.cloudfunctions.net/charge/';
// Function used by all three methods to send the charge data to your Firebase function
async function charge(token, amount, currency) {
const res = await fetch(FIREBASE_FUNCTION, {
method: 'POST',
body: JSON.stringify({
token,
charge: {
amount,
currency,
},
}),
});
const data = await res.json();
data.body = JSON.parse(data.body);
return data;
}
class CheckoutForm extends Component {
constructor(props) {
super(props);
this.submit = this.submit.bind(this);
}
state = {
paymentComplete: false,
firstName: '',
lastName: '',
address: '',
city: '',
prefecture: '',
zipCode: '',
email: '',
submitDisabled: true
}
inputChangeHandler = (event, name) => {
console.log('inputChange', name, event.target.value)
event.preventDefault()
this.setState({
name: event.target.value
}, console.log(this.state.submitDisabled), function(){ this.canSubmit() })
}
canSubmit = () => {
console.log("canSubmit")
const { firstName, lastName, address, city, prefecture,zipCode, email} = this.state
if (validator.isAlpha(firstName)
&& validator.isAlpha(lastName)
&& address > 0
&& validator.isAlpha(city)
&& validator.isAlpha(prefecture)
&& zipCode > 0
&& validator.isEmail(email)) {
this.setState({submitDisabled: false})
} else {
this.setState({submitDisabled: true})
}
}
clearCartHandler = () => {
console.log('clearCartHandler');
this.props.onClearCart()
}
// User clicked submit
async submit(ev) {
console.log("clicked!")
const {token} = await this.props.stripe.createToken({name: "Name"});
const total = getTotal(this.props.cartItems);
const amount = total; // TODO: replace with form data
const currency = 'USD';
const response = await charge(token, amount, currency);
if (response.statusCode === 200) {
this.setState({paymentComplete: true});
console.log('200!!',response);
this.clearCartHandler();
} else {
alert("wrong credit information")
console.error("error: ", response);
}
}
render() {
if (this.state.complete) {
return (
<div>
<h1 className="purchase-complete">Purchase Complete</h1>
<Link to='/'>
<button>Continue Shopping</button>
</Link>
</div>
);
}
return (
<div className="checkout-wrapper">
<Container className="App">
<h2 className='text-center'>Let's Checkout</h2>
<Form className="form">
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="first name"
name={"first name"}
value={this.state.firstName}
id="exampleEmail"
placeholder="first name"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="last name"
name="last name"
value={this.state.lastName}
id="exampleEmail"
placeholder="last name"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="address"
name="address"
value={this.state.adress}
id="exampleEmail"
placeholder="address"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="city"
name="city"
value={this.state.city}
id="exampleEmail"
placeholder="city"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="prefecture"
name="prefecture"
value={this.state.prefecture}
id="exampleEmail"
placeholder="prefecture"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="zipcode"
name="zipcode"
value={this.state.zipCode}
id="exampleEmail"
placeholder="zipcode"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="email"
name="email"
value={this.state.email}
id="exampleEmail"
placeholder="myemail@email.com"
/>
</FormGroup>
</Col>
<Button className="save-address-button" disabled={this.state.submitDisabled}>Submit Address</Button>
<div className="card-element">
<CardElement style={cardElement}/>
</div>
</Form>
<button className="checkout-button" disabled={false} onClick={this.submit}>Submit</button>
</Container>
</div>
);
}
}
const mapStateToProps = state => {
return {
cartItems: state.shoppingCart.cartItems
}
}
const mapDispatchToProps = (dispatch) => {
return {
onClearCart: () => dispatch(clearCart())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(injectStripe(CheckoutForm));
reactjs reactstrap
add a comment |
I am using npm Validator and trying to validate the input info and then change the state of the submit address button depending on the validation. The way I have it set up now I can type and the text shows in the console but not in the UI. I'm not sure what I have wrong. The button will not change to 'enabled' either.
Here is the component:
import React, {Component} from 'react';
import { CardElement, injectStripe } from 'react-stripe-elements';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { clearCart } from '../actions/clearCartAction';
import getTotal from '../helpers/getTotalHelper';
import { Container, Col, Form, FormGroup, Input, Button } from 'reactstrap';
import './StripeCheckoutForm.css';
import validator from 'validator';
const cardElement = {
base: {
color: '#32325d',
width: '50%',
lineHeight: '30px',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '18px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
const FIREBASE_FUNCTION = 'https://us-central1-velo-velo.cloudfunctions.net/charge/';
// Function used by all three methods to send the charge data to your Firebase function
async function charge(token, amount, currency) {
const res = await fetch(FIREBASE_FUNCTION, {
method: 'POST',
body: JSON.stringify({
token,
charge: {
amount,
currency,
},
}),
});
const data = await res.json();
data.body = JSON.parse(data.body);
return data;
}
class CheckoutForm extends Component {
constructor(props) {
super(props);
this.submit = this.submit.bind(this);
}
state = {
paymentComplete: false,
firstName: '',
lastName: '',
address: '',
city: '',
prefecture: '',
zipCode: '',
email: '',
submitDisabled: true
}
inputChangeHandler = (event, name) => {
console.log('inputChange', name, event.target.value)
event.preventDefault()
this.setState({
name: event.target.value
}, console.log(this.state.submitDisabled), function(){ this.canSubmit() })
}
canSubmit = () => {
console.log("canSubmit")
const { firstName, lastName, address, city, prefecture,zipCode, email} = this.state
if (validator.isAlpha(firstName)
&& validator.isAlpha(lastName)
&& address > 0
&& validator.isAlpha(city)
&& validator.isAlpha(prefecture)
&& zipCode > 0
&& validator.isEmail(email)) {
this.setState({submitDisabled: false})
} else {
this.setState({submitDisabled: true})
}
}
clearCartHandler = () => {
console.log('clearCartHandler');
this.props.onClearCart()
}
// User clicked submit
async submit(ev) {
console.log("clicked!")
const {token} = await this.props.stripe.createToken({name: "Name"});
const total = getTotal(this.props.cartItems);
const amount = total; // TODO: replace with form data
const currency = 'USD';
const response = await charge(token, amount, currency);
if (response.statusCode === 200) {
this.setState({paymentComplete: true});
console.log('200!!',response);
this.clearCartHandler();
} else {
alert("wrong credit information")
console.error("error: ", response);
}
}
render() {
if (this.state.complete) {
return (
<div>
<h1 className="purchase-complete">Purchase Complete</h1>
<Link to='/'>
<button>Continue Shopping</button>
</Link>
</div>
);
}
return (
<div className="checkout-wrapper">
<Container className="App">
<h2 className='text-center'>Let's Checkout</h2>
<Form className="form">
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="first name"
name={"first name"}
value={this.state.firstName}
id="exampleEmail"
placeholder="first name"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="last name"
name="last name"
value={this.state.lastName}
id="exampleEmail"
placeholder="last name"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="address"
name="address"
value={this.state.adress}
id="exampleEmail"
placeholder="address"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="city"
name="city"
value={this.state.city}
id="exampleEmail"
placeholder="city"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="prefecture"
name="prefecture"
value={this.state.prefecture}
id="exampleEmail"
placeholder="prefecture"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="zipcode"
name="zipcode"
value={this.state.zipCode}
id="exampleEmail"
placeholder="zipcode"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="email"
name="email"
value={this.state.email}
id="exampleEmail"
placeholder="myemail@email.com"
/>
</FormGroup>
</Col>
<Button className="save-address-button" disabled={this.state.submitDisabled}>Submit Address</Button>
<div className="card-element">
<CardElement style={cardElement}/>
</div>
</Form>
<button className="checkout-button" disabled={false} onClick={this.submit}>Submit</button>
</Container>
</div>
);
}
}
const mapStateToProps = state => {
return {
cartItems: state.shoppingCart.cartItems
}
}
const mapDispatchToProps = (dispatch) => {
return {
onClearCart: () => dispatch(clearCart())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(injectStripe(CheckoutForm));
reactjs reactstrap
add a comment |
I am using npm Validator and trying to validate the input info and then change the state of the submit address button depending on the validation. The way I have it set up now I can type and the text shows in the console but not in the UI. I'm not sure what I have wrong. The button will not change to 'enabled' either.
Here is the component:
import React, {Component} from 'react';
import { CardElement, injectStripe } from 'react-stripe-elements';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { clearCart } from '../actions/clearCartAction';
import getTotal from '../helpers/getTotalHelper';
import { Container, Col, Form, FormGroup, Input, Button } from 'reactstrap';
import './StripeCheckoutForm.css';
import validator from 'validator';
const cardElement = {
base: {
color: '#32325d',
width: '50%',
lineHeight: '30px',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '18px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
const FIREBASE_FUNCTION = 'https://us-central1-velo-velo.cloudfunctions.net/charge/';
// Function used by all three methods to send the charge data to your Firebase function
async function charge(token, amount, currency) {
const res = await fetch(FIREBASE_FUNCTION, {
method: 'POST',
body: JSON.stringify({
token,
charge: {
amount,
currency,
},
}),
});
const data = await res.json();
data.body = JSON.parse(data.body);
return data;
}
class CheckoutForm extends Component {
constructor(props) {
super(props);
this.submit = this.submit.bind(this);
}
state = {
paymentComplete: false,
firstName: '',
lastName: '',
address: '',
city: '',
prefecture: '',
zipCode: '',
email: '',
submitDisabled: true
}
inputChangeHandler = (event, name) => {
console.log('inputChange', name, event.target.value)
event.preventDefault()
this.setState({
name: event.target.value
}, console.log(this.state.submitDisabled), function(){ this.canSubmit() })
}
canSubmit = () => {
console.log("canSubmit")
const { firstName, lastName, address, city, prefecture,zipCode, email} = this.state
if (validator.isAlpha(firstName)
&& validator.isAlpha(lastName)
&& address > 0
&& validator.isAlpha(city)
&& validator.isAlpha(prefecture)
&& zipCode > 0
&& validator.isEmail(email)) {
this.setState({submitDisabled: false})
} else {
this.setState({submitDisabled: true})
}
}
clearCartHandler = () => {
console.log('clearCartHandler');
this.props.onClearCart()
}
// User clicked submit
async submit(ev) {
console.log("clicked!")
const {token} = await this.props.stripe.createToken({name: "Name"});
const total = getTotal(this.props.cartItems);
const amount = total; // TODO: replace with form data
const currency = 'USD';
const response = await charge(token, amount, currency);
if (response.statusCode === 200) {
this.setState({paymentComplete: true});
console.log('200!!',response);
this.clearCartHandler();
} else {
alert("wrong credit information")
console.error("error: ", response);
}
}
render() {
if (this.state.complete) {
return (
<div>
<h1 className="purchase-complete">Purchase Complete</h1>
<Link to='/'>
<button>Continue Shopping</button>
</Link>
</div>
);
}
return (
<div className="checkout-wrapper">
<Container className="App">
<h2 className='text-center'>Let's Checkout</h2>
<Form className="form">
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="first name"
name={"first name"}
value={this.state.firstName}
id="exampleEmail"
placeholder="first name"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="last name"
name="last name"
value={this.state.lastName}
id="exampleEmail"
placeholder="last name"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="address"
name="address"
value={this.state.adress}
id="exampleEmail"
placeholder="address"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="city"
name="city"
value={this.state.city}
id="exampleEmail"
placeholder="city"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="prefecture"
name="prefecture"
value={this.state.prefecture}
id="exampleEmail"
placeholder="prefecture"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="zipcode"
name="zipcode"
value={this.state.zipCode}
id="exampleEmail"
placeholder="zipcode"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="email"
name="email"
value={this.state.email}
id="exampleEmail"
placeholder="myemail@email.com"
/>
</FormGroup>
</Col>
<Button className="save-address-button" disabled={this.state.submitDisabled}>Submit Address</Button>
<div className="card-element">
<CardElement style={cardElement}/>
</div>
</Form>
<button className="checkout-button" disabled={false} onClick={this.submit}>Submit</button>
</Container>
</div>
);
}
}
const mapStateToProps = state => {
return {
cartItems: state.shoppingCart.cartItems
}
}
const mapDispatchToProps = (dispatch) => {
return {
onClearCart: () => dispatch(clearCart())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(injectStripe(CheckoutForm));
reactjs reactstrap
I am using npm Validator and trying to validate the input info and then change the state of the submit address button depending on the validation. The way I have it set up now I can type and the text shows in the console but not in the UI. I'm not sure what I have wrong. The button will not change to 'enabled' either.
Here is the component:
import React, {Component} from 'react';
import { CardElement, injectStripe } from 'react-stripe-elements';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { clearCart } from '../actions/clearCartAction';
import getTotal from '../helpers/getTotalHelper';
import { Container, Col, Form, FormGroup, Input, Button } from 'reactstrap';
import './StripeCheckoutForm.css';
import validator from 'validator';
const cardElement = {
base: {
color: '#32325d',
width: '50%',
lineHeight: '30px',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '18px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
const FIREBASE_FUNCTION = 'https://us-central1-velo-velo.cloudfunctions.net/charge/';
// Function used by all three methods to send the charge data to your Firebase function
async function charge(token, amount, currency) {
const res = await fetch(FIREBASE_FUNCTION, {
method: 'POST',
body: JSON.stringify({
token,
charge: {
amount,
currency,
},
}),
});
const data = await res.json();
data.body = JSON.parse(data.body);
return data;
}
class CheckoutForm extends Component {
constructor(props) {
super(props);
this.submit = this.submit.bind(this);
}
state = {
paymentComplete: false,
firstName: '',
lastName: '',
address: '',
city: '',
prefecture: '',
zipCode: '',
email: '',
submitDisabled: true
}
inputChangeHandler = (event, name) => {
console.log('inputChange', name, event.target.value)
event.preventDefault()
this.setState({
name: event.target.value
}, console.log(this.state.submitDisabled), function(){ this.canSubmit() })
}
canSubmit = () => {
console.log("canSubmit")
const { firstName, lastName, address, city, prefecture,zipCode, email} = this.state
if (validator.isAlpha(firstName)
&& validator.isAlpha(lastName)
&& address > 0
&& validator.isAlpha(city)
&& validator.isAlpha(prefecture)
&& zipCode > 0
&& validator.isEmail(email)) {
this.setState({submitDisabled: false})
} else {
this.setState({submitDisabled: true})
}
}
clearCartHandler = () => {
console.log('clearCartHandler');
this.props.onClearCart()
}
// User clicked submit
async submit(ev) {
console.log("clicked!")
const {token} = await this.props.stripe.createToken({name: "Name"});
const total = getTotal(this.props.cartItems);
const amount = total; // TODO: replace with form data
const currency = 'USD';
const response = await charge(token, amount, currency);
if (response.statusCode === 200) {
this.setState({paymentComplete: true});
console.log('200!!',response);
this.clearCartHandler();
} else {
alert("wrong credit information")
console.error("error: ", response);
}
}
render() {
if (this.state.complete) {
return (
<div>
<h1 className="purchase-complete">Purchase Complete</h1>
<Link to='/'>
<button>Continue Shopping</button>
</Link>
</div>
);
}
return (
<div className="checkout-wrapper">
<Container className="App">
<h2 className='text-center'>Let's Checkout</h2>
<Form className="form">
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="first name"
name={"first name"}
value={this.state.firstName}
id="exampleEmail"
placeholder="first name"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="last name"
name="last name"
value={this.state.lastName}
id="exampleEmail"
placeholder="last name"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="address"
name="address"
value={this.state.adress}
id="exampleEmail"
placeholder="address"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="city"
name="city"
value={this.state.city}
id="exampleEmail"
placeholder="city"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="prefecture"
name="prefecture"
value={this.state.prefecture}
id="exampleEmail"
placeholder="prefecture"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="zipcode"
name="zipcode"
value={this.state.zipCode}
id="exampleEmail"
placeholder="zipcode"
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Input
onChange= {this.inputChangeHandler}
type="email"
name="email"
value={this.state.email}
id="exampleEmail"
placeholder="myemail@email.com"
/>
</FormGroup>
</Col>
<Button className="save-address-button" disabled={this.state.submitDisabled}>Submit Address</Button>
<div className="card-element">
<CardElement style={cardElement}/>
</div>
</Form>
<button className="checkout-button" disabled={false} onClick={this.submit}>Submit</button>
</Container>
</div>
);
}
}
const mapStateToProps = state => {
return {
cartItems: state.shoppingCart.cartItems
}
}
const mapDispatchToProps = (dispatch) => {
return {
onClearCart: () => dispatch(clearCart())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(injectStripe(CheckoutForm));
reactjs reactstrap
reactjs reactstrap
edited Feb 9 at 11:26
halfer
14.6k758112
14.6k758112
asked Jan 1 at 6:34
frootloopsfrootloops
528
528
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I think the bug is related to the misuse of the callback function of this.setState.
In your inputChangeHandler method, you passed three arguments to this.setState(), however, this.setState() expects you to pass only two arguments at most, with the second argument being the callback function.
Since you pass your callback function as the third argument, this.setState() will silently ignores it, so your validation method is not being called.
Another issue is related to the name parameter for the inputChangeHandler, the inputChangeHandler will only receive the event object, not the name. In order to access the name attribute of the input element, you will need to access it through event.target.name
To solve the issues, you can change the inputChangeHandler to
inputChangeHandler = event => {
const { name, value } = event.target;
console.log('inputChange', event.target.name, event.target.value)
// notice the square bracket, this means we use the computed variable as
// the object key, instead of using the string 'name' as object key
// also the name attribute in your Input element must match your state's key
// use name='lastName' instead of name='last name' as your state's key is lastName
this.setState({
[name]: value
}, this.canSubmit) // changing this line
}
If you want to keep your console.log(this.state.submitDisabled), you can add it inside your validation method.
canSubmit = () => {
console.log("canSubmit", this.state.submitDisabled) // add it here
const { firstName, lastName, address, city, prefecture, zipCode, email} = this.state
if (validator.isAlpha(firstName)
&& validator.isAlpha(lastName)
&& address > 0
&& validator.isAlpha(city)
&& validator.isAlpha(prefecture)
&& zipCode > 0
&& validator.isEmail(email)) {
this.setState({submitDisabled: false})
} else {
this.setState({submitDisabled: true})
}
}
In the render method, I think you mean
if (this.state.paymentComplete)
instead of
if (this.state.complete)
Also, the button at the bottom, you hard-coded the disabled attribute value
<button
className="checkout-button"
disabled={false}
onClick={this.submit}
>
Submit
</button>
maybe you mean
<button
className="checkout-button"
disabled={this.state.submitDisabled}
onClick={this.submit}
>
Submit
</button>
As a side note, the type attribute for the input element should be 'text', 'number', 'checkbox', etc... Instead of some random text like 'last name' or 'prefecture'
Thanks for your help, but I tried this and I still have the same problem.
– frootloops
Jan 1 at 10:54
Is the canSubmit method being called and the state being updated now?
– Ray Chan
Jan 1 at 11:05
@frootloops I updated the answer, maybe you can check whether it's working now
– Ray Chan
Jan 1 at 11:21
Thanks for pointing those out. I still can't get the type to appear in the inputs. I can see every key stroke and letter in the console though.
– frootloops
Jan 1 at 11:32
1
I finally found the problem. The main problem was that some of the Input names did not match the items in the state. and[event.target.name]: event.target.value. Thanks for your help @Ray Chan
– frootloops
Jan 1 at 13:49
|
show 1 more comment
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53993493%2fhow-to-get-my-input-validation-and-disabling-enabling-my-submit-button-depending%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think the bug is related to the misuse of the callback function of this.setState.
In your inputChangeHandler method, you passed three arguments to this.setState(), however, this.setState() expects you to pass only two arguments at most, with the second argument being the callback function.
Since you pass your callback function as the third argument, this.setState() will silently ignores it, so your validation method is not being called.
Another issue is related to the name parameter for the inputChangeHandler, the inputChangeHandler will only receive the event object, not the name. In order to access the name attribute of the input element, you will need to access it through event.target.name
To solve the issues, you can change the inputChangeHandler to
inputChangeHandler = event => {
const { name, value } = event.target;
console.log('inputChange', event.target.name, event.target.value)
// notice the square bracket, this means we use the computed variable as
// the object key, instead of using the string 'name' as object key
// also the name attribute in your Input element must match your state's key
// use name='lastName' instead of name='last name' as your state's key is lastName
this.setState({
[name]: value
}, this.canSubmit) // changing this line
}
If you want to keep your console.log(this.state.submitDisabled), you can add it inside your validation method.
canSubmit = () => {
console.log("canSubmit", this.state.submitDisabled) // add it here
const { firstName, lastName, address, city, prefecture, zipCode, email} = this.state
if (validator.isAlpha(firstName)
&& validator.isAlpha(lastName)
&& address > 0
&& validator.isAlpha(city)
&& validator.isAlpha(prefecture)
&& zipCode > 0
&& validator.isEmail(email)) {
this.setState({submitDisabled: false})
} else {
this.setState({submitDisabled: true})
}
}
In the render method, I think you mean
if (this.state.paymentComplete)
instead of
if (this.state.complete)
Also, the button at the bottom, you hard-coded the disabled attribute value
<button
className="checkout-button"
disabled={false}
onClick={this.submit}
>
Submit
</button>
maybe you mean
<button
className="checkout-button"
disabled={this.state.submitDisabled}
onClick={this.submit}
>
Submit
</button>
As a side note, the type attribute for the input element should be 'text', 'number', 'checkbox', etc... Instead of some random text like 'last name' or 'prefecture'
Thanks for your help, but I tried this and I still have the same problem.
– frootloops
Jan 1 at 10:54
Is the canSubmit method being called and the state being updated now?
– Ray Chan
Jan 1 at 11:05
@frootloops I updated the answer, maybe you can check whether it's working now
– Ray Chan
Jan 1 at 11:21
Thanks for pointing those out. I still can't get the type to appear in the inputs. I can see every key stroke and letter in the console though.
– frootloops
Jan 1 at 11:32
1
I finally found the problem. The main problem was that some of the Input names did not match the items in the state. and[event.target.name]: event.target.value. Thanks for your help @Ray Chan
– frootloops
Jan 1 at 13:49
|
show 1 more comment
I think the bug is related to the misuse of the callback function of this.setState.
In your inputChangeHandler method, you passed three arguments to this.setState(), however, this.setState() expects you to pass only two arguments at most, with the second argument being the callback function.
Since you pass your callback function as the third argument, this.setState() will silently ignores it, so your validation method is not being called.
Another issue is related to the name parameter for the inputChangeHandler, the inputChangeHandler will only receive the event object, not the name. In order to access the name attribute of the input element, you will need to access it through event.target.name
To solve the issues, you can change the inputChangeHandler to
inputChangeHandler = event => {
const { name, value } = event.target;
console.log('inputChange', event.target.name, event.target.value)
// notice the square bracket, this means we use the computed variable as
// the object key, instead of using the string 'name' as object key
// also the name attribute in your Input element must match your state's key
// use name='lastName' instead of name='last name' as your state's key is lastName
this.setState({
[name]: value
}, this.canSubmit) // changing this line
}
If you want to keep your console.log(this.state.submitDisabled), you can add it inside your validation method.
canSubmit = () => {
console.log("canSubmit", this.state.submitDisabled) // add it here
const { firstName, lastName, address, city, prefecture, zipCode, email} = this.state
if (validator.isAlpha(firstName)
&& validator.isAlpha(lastName)
&& address > 0
&& validator.isAlpha(city)
&& validator.isAlpha(prefecture)
&& zipCode > 0
&& validator.isEmail(email)) {
this.setState({submitDisabled: false})
} else {
this.setState({submitDisabled: true})
}
}
In the render method, I think you mean
if (this.state.paymentComplete)
instead of
if (this.state.complete)
Also, the button at the bottom, you hard-coded the disabled attribute value
<button
className="checkout-button"
disabled={false}
onClick={this.submit}
>
Submit
</button>
maybe you mean
<button
className="checkout-button"
disabled={this.state.submitDisabled}
onClick={this.submit}
>
Submit
</button>
As a side note, the type attribute for the input element should be 'text', 'number', 'checkbox', etc... Instead of some random text like 'last name' or 'prefecture'
Thanks for your help, but I tried this and I still have the same problem.
– frootloops
Jan 1 at 10:54
Is the canSubmit method being called and the state being updated now?
– Ray Chan
Jan 1 at 11:05
@frootloops I updated the answer, maybe you can check whether it's working now
– Ray Chan
Jan 1 at 11:21
Thanks for pointing those out. I still can't get the type to appear in the inputs. I can see every key stroke and letter in the console though.
– frootloops
Jan 1 at 11:32
1
I finally found the problem. The main problem was that some of the Input names did not match the items in the state. and[event.target.name]: event.target.value. Thanks for your help @Ray Chan
– frootloops
Jan 1 at 13:49
|
show 1 more comment
I think the bug is related to the misuse of the callback function of this.setState.
In your inputChangeHandler method, you passed three arguments to this.setState(), however, this.setState() expects you to pass only two arguments at most, with the second argument being the callback function.
Since you pass your callback function as the third argument, this.setState() will silently ignores it, so your validation method is not being called.
Another issue is related to the name parameter for the inputChangeHandler, the inputChangeHandler will only receive the event object, not the name. In order to access the name attribute of the input element, you will need to access it through event.target.name
To solve the issues, you can change the inputChangeHandler to
inputChangeHandler = event => {
const { name, value } = event.target;
console.log('inputChange', event.target.name, event.target.value)
// notice the square bracket, this means we use the computed variable as
// the object key, instead of using the string 'name' as object key
// also the name attribute in your Input element must match your state's key
// use name='lastName' instead of name='last name' as your state's key is lastName
this.setState({
[name]: value
}, this.canSubmit) // changing this line
}
If you want to keep your console.log(this.state.submitDisabled), you can add it inside your validation method.
canSubmit = () => {
console.log("canSubmit", this.state.submitDisabled) // add it here
const { firstName, lastName, address, city, prefecture, zipCode, email} = this.state
if (validator.isAlpha(firstName)
&& validator.isAlpha(lastName)
&& address > 0
&& validator.isAlpha(city)
&& validator.isAlpha(prefecture)
&& zipCode > 0
&& validator.isEmail(email)) {
this.setState({submitDisabled: false})
} else {
this.setState({submitDisabled: true})
}
}
In the render method, I think you mean
if (this.state.paymentComplete)
instead of
if (this.state.complete)
Also, the button at the bottom, you hard-coded the disabled attribute value
<button
className="checkout-button"
disabled={false}
onClick={this.submit}
>
Submit
</button>
maybe you mean
<button
className="checkout-button"
disabled={this.state.submitDisabled}
onClick={this.submit}
>
Submit
</button>
As a side note, the type attribute for the input element should be 'text', 'number', 'checkbox', etc... Instead of some random text like 'last name' or 'prefecture'
I think the bug is related to the misuse of the callback function of this.setState.
In your inputChangeHandler method, you passed three arguments to this.setState(), however, this.setState() expects you to pass only two arguments at most, with the second argument being the callback function.
Since you pass your callback function as the third argument, this.setState() will silently ignores it, so your validation method is not being called.
Another issue is related to the name parameter for the inputChangeHandler, the inputChangeHandler will only receive the event object, not the name. In order to access the name attribute of the input element, you will need to access it through event.target.name
To solve the issues, you can change the inputChangeHandler to
inputChangeHandler = event => {
const { name, value } = event.target;
console.log('inputChange', event.target.name, event.target.value)
// notice the square bracket, this means we use the computed variable as
// the object key, instead of using the string 'name' as object key
// also the name attribute in your Input element must match your state's key
// use name='lastName' instead of name='last name' as your state's key is lastName
this.setState({
[name]: value
}, this.canSubmit) // changing this line
}
If you want to keep your console.log(this.state.submitDisabled), you can add it inside your validation method.
canSubmit = () => {
console.log("canSubmit", this.state.submitDisabled) // add it here
const { firstName, lastName, address, city, prefecture, zipCode, email} = this.state
if (validator.isAlpha(firstName)
&& validator.isAlpha(lastName)
&& address > 0
&& validator.isAlpha(city)
&& validator.isAlpha(prefecture)
&& zipCode > 0
&& validator.isEmail(email)) {
this.setState({submitDisabled: false})
} else {
this.setState({submitDisabled: true})
}
}
In the render method, I think you mean
if (this.state.paymentComplete)
instead of
if (this.state.complete)
Also, the button at the bottom, you hard-coded the disabled attribute value
<button
className="checkout-button"
disabled={false}
onClick={this.submit}
>
Submit
</button>
maybe you mean
<button
className="checkout-button"
disabled={this.state.submitDisabled}
onClick={this.submit}
>
Submit
</button>
As a side note, the type attribute for the input element should be 'text', 'number', 'checkbox', etc... Instead of some random text like 'last name' or 'prefecture'
edited Jan 1 at 12:59
answered Jan 1 at 9:55
Ray ChanRay Chan
47919
47919
Thanks for your help, but I tried this and I still have the same problem.
– frootloops
Jan 1 at 10:54
Is the canSubmit method being called and the state being updated now?
– Ray Chan
Jan 1 at 11:05
@frootloops I updated the answer, maybe you can check whether it's working now
– Ray Chan
Jan 1 at 11:21
Thanks for pointing those out. I still can't get the type to appear in the inputs. I can see every key stroke and letter in the console though.
– frootloops
Jan 1 at 11:32
1
I finally found the problem. The main problem was that some of the Input names did not match the items in the state. and[event.target.name]: event.target.value. Thanks for your help @Ray Chan
– frootloops
Jan 1 at 13:49
|
show 1 more comment
Thanks for your help, but I tried this and I still have the same problem.
– frootloops
Jan 1 at 10:54
Is the canSubmit method being called and the state being updated now?
– Ray Chan
Jan 1 at 11:05
@frootloops I updated the answer, maybe you can check whether it's working now
– Ray Chan
Jan 1 at 11:21
Thanks for pointing those out. I still can't get the type to appear in the inputs. I can see every key stroke and letter in the console though.
– frootloops
Jan 1 at 11:32
1
I finally found the problem. The main problem was that some of the Input names did not match the items in the state. and[event.target.name]: event.target.value. Thanks for your help @Ray Chan
– frootloops
Jan 1 at 13:49
Thanks for your help, but I tried this and I still have the same problem.
– frootloops
Jan 1 at 10:54
Thanks for your help, but I tried this and I still have the same problem.
– frootloops
Jan 1 at 10:54
Is the canSubmit method being called and the state being updated now?
– Ray Chan
Jan 1 at 11:05
Is the canSubmit method being called and the state being updated now?
– Ray Chan
Jan 1 at 11:05
@frootloops I updated the answer, maybe you can check whether it's working now
– Ray Chan
Jan 1 at 11:21
@frootloops I updated the answer, maybe you can check whether it's working now
– Ray Chan
Jan 1 at 11:21
Thanks for pointing those out. I still can't get the type to appear in the inputs. I can see every key stroke and letter in the console though.
– frootloops
Jan 1 at 11:32
Thanks for pointing those out. I still can't get the type to appear in the inputs. I can see every key stroke and letter in the console though.
– frootloops
Jan 1 at 11:32
1
1
I finally found the problem. The main problem was that some of the Input names did not match the items in the state. and
[event.target.name]: event.target.value. Thanks for your help @Ray Chan– frootloops
Jan 1 at 13:49
I finally found the problem. The main problem was that some of the Input names did not match the items in the state. and
[event.target.name]: event.target.value. Thanks for your help @Ray Chan– frootloops
Jan 1 at 13:49
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53993493%2fhow-to-get-my-input-validation-and-disabling-enabling-my-submit-button-depending%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown