Skip to content Skip to sidebar Skip to footer

Unable To Show Helpertext Once We Click On The Submit Button Using Reactjs?

I'm new to this dropdown validations, i want to show helpertext bottom of the dropdown when the dropdown field is selected (or) we have selected but again selected the -1 menu item

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.

  1. 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>
  2. You've 2 levels of select fields. When a user changes the root channel state, reset the movie and sports states.

  3. 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
          }
        });
      }
    }
    
  4. Add name attributes to the select inputs to be accessed in the onChange 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"
      >);
    };
  1. Since it isn't possible to select sportsANDmovie, use some branching logic to validate one or the other depending on channel, i.e. if sports is expected to have a value then movie 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
      };
    };
    
  2. 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 });
      }
    };
    

Edit unable-to-validate-dropdown-once-we-click-on-the-submit-button-using-reactjs

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?"