I'm trying to add validation to TextField and Select before going to handleNext(). Here is the code (2 components):
class Quote extends React.Component {
state = {
activeStep: 0,
zipCode: '',
destination: '',
sedanPrice: '',
suvPrice: '',
labelWidth: 0,
};
getStepContent = (step) => {
switch (step) {
case 0:
return (
<div>
<QuoteForm
{...this.state}
{...this.state.value}
handleChange={this.handleChange}
/>
</div>
)
case 1:
return (
<div>
<QuotePrice
{...this.state}
{...this.state.value}
/>
</div>
)
default:
throw new Error('Unknown step');
}
}
handleNext = () => {
this.setState(prevState => ({
activeStep: prevState.activeStep + 1,
}));
switch(this.state.activeStep){
case 0:
// Creates an API call for sedan pricing
API.getPrice(this.state.zipCode, "sedan" + this.state.destination).then(res => {
let price = res.data;
let key = Object.keys(price);
console.log("Sedan price is $" + price[key]);
this.setState({sedanPrice: price[key]});
})
.catch(err => console.log(err));
// Creates an API call for SUV pricing
API.getPrice(this.state.zipCode, "suv" + this.state.destination).then(res => {
let price = res.data;
let key = Object.keys(price);
console.log("SUV price is $" + price[key])
this.setState({suvPrice: price[key]});
})
.catch(err => console.log(err));
break
case 1:
console.log('forward to booking page');
window.location.href = '/booking';
break
default:
console.log('over');
}
};
handleBack = () => {
this.setState(state => ({
activeStep: state.activeStep - 1,
sedanPrice: '',
suvPrice: '',
destination: '',
zipCode: '',
}));
};
handleReset = () => {
this.setState({
activeStep: 0,
});
};
handleChange = event => {
const { name, value } = event.target;
this.setState({
[name]: value,
});
};
render() {
const { classes } = this.props;
const { activeStep } = this.state;
const steps = ['Pick Up Address', 'Select Your Vehicle'];
return (
<React.Fragment>
<CssBaseline />
<main className={classes.layout}>
<Paper className={classes.paper}>
<React.Fragment>
{activeStep === steps.length ? (
<React.Fragment>
<Typography variant="h5" gutterBottom>
Thank you for your interest!
</Typography>
</React.Fragment>
) : (
<React.Fragment>
{this.getStepContent(activeStep)}
<div className={classes.buttons}>
{activeStep !== 0 && (
<Button onClick={this.handleBack} className={classes.button}>
Back
</Button>
)}
<Button
variant="contained"
color="primary"
onClick={this.handleNext}
className={classes.button}
>
{activeStep === steps.length - 1 ? 'Book Now' : 'Next'}
</Button>
</div>
</React.Fragment>
)}
</React.Fragment>
</Paper>
</main>
</React.Fragment>
);
}
}
QuoteForm.js
export class QuoteForm extends React.Component {
state = {
zipCode: this.props.zipCode,
destination: this.props.destination,
}
render() {
const { classes } = this.props;
return (
<React.Fragment>
<Typography variant="h5" align="center">
Enter your zip code for a quick quote
</Typography>
<Grid container>
<Grid className={classes.TextField} item xs={12} sm={6}>
<TextField
required
id="zip"
name="zipCode"
label="Zip / Postal code"
fullWidth
autoComplete="billing postal-code"
value={this.props.zipCode}
onChange={this.props.handleChange}
/>
</Grid>
<FormControl xs={12} sm={6} className={classes.formControl}>
<Select
required
value={this.props.destination}
onChange={this.props.handleChange}
input={<Input name="destination" />}
displayEmpty
name="destination"
className={classes.selectEmpty}
>
<MenuItem value="">
<em>Select Your Airport *</em>
</MenuItem>
<MenuItem name="SAN" value={"SAN"}>San Diego International Airport</MenuItem>
<MenuItem name="LAX" value={"LAX"}>Los Angeles International Airport</MenuItem>
</Select>
</FormControl>
</Grid>
</React.Fragment>
);
}
}
I tried 2 different ways. First, using Button disabled and writing a function to handle the validation and set disabled to false. Second, using npm package to handle validation. Both failed since I'm new to this. Any help would be appreciated. Thanks in advance.
Do the following:
error
and errorMessage
error
and helperText
props to set/display errors nicely beside your fieldsFormControl
error
prop and provide label
to Select
in order to set/display errors nicely beside your fieldserror
and errorMessage
to QuoteForm
component.Working copy of your code is here in the codesandbox
state
state = {
activeStep: 0,
zipCode: "",
destination: "",
sedanPrice: "",
suvPrice: "",
labelWidth: 0,
error: false, //<---- here
errorMessage: {} //<-----here
};
handleNext
handleNext = () => {
let isError = false;
if (this.state.zipCode.length < 2) {
isError = true;
this.setState({
error: true,
errorMessage: { zipCode: "enter correct zipcode" }
});
}
if (this.state.destination === '') {
isError = true;
this.setState(prev => ({
...prev,
error: true,
errorMessage: { ...prev.errorMessage, destination: "enter correct destination" }
}))
} if(!isError){
//add else if for validating other fields (if any)
this.setState(prevState => ({
activeStep: prevState.activeStep + 1,
error: false,
errorMessage: {}
}));
}
...
Mui Textfield
<TextField
error={!!this.props.errorMessage.zipCode}
required
id="zip"
name="zipCode"
label="Zip / Postal code"
fullWidth
autoComplete="billing postal-code"
value={this.props.zipCode}
onChange={this.props.handleChange}
helperText={
this.props.errorMessage.zipCode &&
this.props.errorMessage.zipCode
}
/>
Mui Select use
<FormControl xs={12} sm={6} error={this.props.error}>
<Select
error={!!this.props.errorMessage.destination}
label="enter cor dest"
required
value={this.props.destination}
onChange={this.props.handleChange}
input={<Input name="destination" />}
displayEmpty
name="destination"
>
<MenuItem value="">
<em>Select Your Airport *</em>
</MenuItem>
<MenuItem name="SAN" value={"SAN"}>
San Diego International Airport
</MenuItem>
<MenuItem name="LAX" value={"LAX"}>
Los Angeles International Airport
</MenuItem>
</Select>
<FormHelperText>
{this.props.errorMessage.destination}
</FormHelperText>
</FormControl>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With