Unable To Show Helpertext Once We Click On The Submit Button Using Reactjs?
Solution 1:
Issue 1
Couldn't able to show red color for helpertext.
You can color the text red by using the error
prop on the FormControl
or FormHelperText
. The FormControl
actually provides a context to the fields it wraps so it's easiest to set the error
prop there.
<FormControlerror={!!errors?.channel}>
...
{errors?.channel && <FormHelperText>{errors.channel}</FormHelperText>}
</FormControl>
Issue 2
For me, it is showing error in line #50 but in Sandbox it is not showing any error.
Unfortunately without any more context about what line 50 consists of locally for you there's not much to resolve here. Feel free to update your question with more details, perhaps a code snippet of the offending line and the copy of the error message.
Issue 3
While submitting form with empty dropdown field(-1) then it should show helpertext.
Here I think a bit of a refactor is in order.
Disable the first "placeholder" select option, it should really be selectable, but it can still be the defaultValue. What this means is that once a valid option is selected, only other valid options can be selected, it can never select the disabled option. This also means that the field is only invalid while a user has not chosen any option.
<MenuItemdisabledvalue={-1}> Select Channel </MenuItem><MenuItemvalue={10}>Sports</MenuItem><MenuItemvalue={20}>Entertainment</MenuItem>
You've 2 levels of select fields. When a user changes the root
channel
state, reset themovie
andsports
states.Change the state shape to include some error/validation object that will hold errors and form submittable status. Reset when state updates.
componentDidUpdate(prevProps, prevState) { // If channel updated then reset "nested" select valuesif (prevState.channel !== this.state.channel) { this.setState({ sports: null, movie: null }); } // Clear error state upon change, next validation to occur next submit attemptif (!prevState.validation.canSubmit && !this.state.validation.canSubmit) { this.setState({ validation: { canSubmit: true } }); } }
Add
name
attributes to the select inputs to be accessed in theonChange
handlers; these should match the names in state. Also, because you have a name, you can reduce the onChange handlers down to a single input change handler.<Select defaultValue={-1} onChange={this.handleChange} displayEmpty inputProps={{ "aria-label": "Without label" }} name="channel"// <-- add name attribute (add for other inputs as well) >
handler
handleChange = (e: any) => {
const { name, value } = e.target;
this.setState({ [name]: value } asPick<
State,
"channel" | "movie" | "sports"
>);
};
Since it isn't possible to select
sports
ANDmovie
, use some branching logic to validate one or the other depending onchannel
, i.e. ifsports
is expected to have a value thenmovie
will never have a value, and vice-versa.Valid = ({ channel, sports, movie }): Validation => { consterrors: Errors = {}; if (!channel) { errors.channel = "Please select channel"; } else { if (channel === 10) { if (!sports) { errors.sports = "select Sports"; } } else { if (!movie) { errors.movie = "select movie"; } } } return { errors, canSubmit: !Object.keys(errors).length }; };
Move the form validation to the
onSubmit
handler, disable the submit button if the validation "canSubmit" status is false.handleSubmit = (e: any) => { e.preventDefault(); const { channel, movie, sports } = this.state; const validation = this.Valid({ channel, movie, sports }); if (validation.canSubmit) { window.alert("SUBMIT!!"); } else { console.log("errors", validation.errors); this.setState({ validation }); } };
Fullcode
I'll apologize ahead of time as I have very little to no typescript experience. Just some quick reading up on syntax. The following has zero errors/warnings in the linked sandbox.
importReactfrom"react";
import {
FormControl,
Select,
MenuItem,
FormHelperText,
Button
} from"@material-ui/core";
interfaceProps {}
interfaceErrors {
channel?: string;
sports?: string;
movie?: string;
}
interfaceValidation {
errors?: Errors;
canSubmit: boolean;
}
interfaceState {
channel: number;
sports: number;
movie: string;
validation: Validation;
}
classSampleextendsReact.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
channel: null,
sports: null,
movie: null,
validation: {
canSubmit: true
}
};
}
componentDidUpdate(prevProps, prevState) {
// If channel updated then reset "nested" select valuesif (prevState.channel !== this.state.channel) {
this.setState({
sports: null,
movie: null
});
}
// Clear error state upon change, next validation to occur next submit attemptif (!prevState.validation.canSubmit && !this.state.validation.canSubmit) {
this.setState({
validation: {
canSubmit: true
}
});
}
}
handleChange = (e: any) => {
const { name, value } = e.target;
this.setState({ [name]: value } asPick<
State,
"channel" | "movie" | "sports"
>);
};
Valid = ({ channel, sports, movie }): Validation => {
consterrors: Errors = {};
if (!channel) {
errors.channel = "Please select channel";
} else {
if (channel === 10) {
if (!sports) {
errors.sports = "select Sports";
}
} else {
if (!movie) {
errors.movie = "select movie";
}
}
}
return {
errors,
canSubmit: !Object.keys(errors).length
};
};
handleSubmit = (e: any) => {
e.preventDefault();
const { channel, movie, sports } = this.state;
const validation = this.Valid({ channel, movie, sports });
if (validation.canSubmit) {
window.alert("SUBMIT!!");
} else {
console.log("errors", validation.errors);
this.setState({ validation });
}
};
render() {
const {
validation: { canSubmit, errors }
} = this.state;
return (
<><FormControlerror={!!errors?.channel}><SelectdefaultValue={-1}onChange={this.handleChange}displayEmptyinputProps={{ "aria-label": "Withoutlabel" }}
name="channel"
><MenuItemdisabledvalue={-1}>
Select Channel
</MenuItem><MenuItemvalue={10}>Sports</MenuItem><MenuItemvalue={20}>Entertainment</MenuItem></Select>
{errors?.channel && <FormHelperText>{errors.channel}</FormHelperText>}
</FormControl>
{this.state.channel === 10 && (
<div><FormControlerror={!!errors?.sports}><SelectdefaultValue={-1}onChange={this.handleChange}displayEmptyinputProps={{ "aria-label": "Withoutlabel" }}
name="sports"
><MenuItemdisabledvalue={-1}>
Select{" "}
</MenuItem><MenuItemvalue={10}>Star sports 1</MenuItem><MenuItemvalue={20}>Star sports 2</MenuItem></Select>
{errors?.sports && (
<FormHelperText>{errors.sports}</FormHelperText>
)}
</FormControl></div>
)}
{this.state.channel === 20 && (
<div><FormControlerror={!!errors?.movie}><SelectdefaultValue={-1}onChange={this.handleChange}displayEmptyinputProps={{ "aria-label": "Withoutlabel" }}
name="movie"
><MenuItemdisabledvalue={-1}>
Select
</MenuItem><MenuItemvalue={10}>Star Movies</MenuItem><MenuItemvalue={20}>ABC</MenuItem></Select>
{errors?.movie && (
<FormHelperTexterror>{errors.movie}</FormHelperText>
)}
</FormControl></div>
)}
<div><Buttondisabled={!canSubmit}onClick={this.handleSubmit}>
Submit
</Button></div></>
);
}
}
exportdefaultSample;
Post a Comment for "Unable To Show Helpertext Once We Click On The Submit Button Using Reactjs?"