Search code examples
javascripthtmlreactjsformsonsubmit

Prevent submit button from submitting all forms on page?


I have 2 forms on one page, a login and signup form in my React / Material-UI page. Each form has their own separate submit button which calls a function that validates the data and performs a set of actions (not included in the code below because of irrelevancy to problem). When I submit the signup form, it also submits the login form. How can I make it so that both forms don't fire from one submit button?

 handleLoginSubmit = (event) => {
    event.preventDefault();
    const userData = {
       email: this.state.email,
       password: this.state.password,
    };
    this.props.loginUser(userData, this.props.history);
 };
handleSignupSubmit = (event) => {
  event.preventDefault();
  const newUserData = {
    email: this.state.newEmail,
    password: this.state.newPassword,
    confirmPassword: this.state.confirmNewPassword,
    handle: this.state.newHandle,
  };
  this.props.signupUser(newUserData, this.props.history);
};

     <Grid container className={classes.formWrapper}>
          // login form
          <Grid item sm xs={12} className={classes.loginFormWrapper}>
            <form
              noValidate
              onSubmit={this.handleLoginSubmit}
              className={classes.form}
              id="loginform"
            >
              <TextField
                id="email"
                name="email"
                type="email"
                label="Email"
                variant="outlined"
                margin="dense"
                className={classes.loginTextField}
                helperText={errors.email}
                error={errors.email ? true : false}
                value={this.state.email}
                onChange={this.handleChange}
              />
              <TextField
                id="password"
                name="password"
                type="password"
                label="Password"
                variant="outlined"
                margin="dense"
                className={classes.loginTextField}
                helperText={errors.password}
                error={errors.password ? true : false}
                value={this.state.password}
                onChange={this.handleChange}
              />
              {errors.general && (
                <Typography variant="body2" className={classes.customError}>
                  {errors.general}
                </Typography>
              )}
              <Button
                type="submit"
                variant="contained"
                color="primary"
                disabled={loading}
                className={classes.button}
              >
                Log In
                {loading && (
                  <CircularProgress
                    size={30}
                    className={classes.progress}
                  />
                )}
              </Button>
            </form>
          </Grid>
       // signup form
          <Grid item sm xs={12} className={classes.signupFormWrapper}>
            <Typography className={classes.pageTitle}>
              Create An Account
            </Typography>
            <Typography className={classes.subTitle}>
              Joining made easy.
            </Typography>
            <form
              noValidate
              onSubmit={this.handleSignupSubmit}
              className={classes.form}
              id="signupform"
            >
              <TextField
                id="newHandle"
                name="newHandle"
                type="text"
                label="Handle"
                variant="outlined"
                margin="dense"
                color="secondary"
                className={classes.textField}
                helperText={errors.handle}
                error={errors.handle ? true : false}
                value={this.state.newHandle}
                onChange={this.handleChange}
                fullWidth
              />
              <TextField
                id="newEmail"
                name="newEmail"
                type="email"
                label="Email"
                variant="outlined"
                margin="dense"
                color="secondary"
                className={classes.textField}
                helperText={errors.newEmail}
                error={errors.newEmail ? true : false}
                value={this.state.newEmail}
                onChange={this.handleChange}
                fullWidth
              />
              <TextField
                id="newPassword"
                name="newPassword"
                type="password"
                label="Password (Min 6 Characters)"
                variant="outlined"
                margin="dense"
                color="secondary"
                className={classes.textField}
                helperText={errors.newPassword}
                error={errors.newPassword ? true : false}
                value={this.state.newPassword}
                onChange={this.handleChange}
                fullWidth
              />
              <TextField
                id="confirmNewPassword"
                name="confirmNewPassword"
                type="password"
                label="Confirm Password"
                variant="outlined"
                margin="dense"
                color="secondary"
                className={classes.textField}
                helperText={errors.confirmNewPassword}
                error={errors.confirmNewPassword ? true : false}
                value={this.state.confirmNewPassword}
                onChange={this.handleChange}
                fullWidth
              />

              {errors.general && (
                <Typography variant="body2" className={classes.customError}>
                  {errors.general}
                </Typography>
              )}
              <br />
              <br />
              <Button
                type="submit"
                variant="contained"
                color="secondary"
                className={classes.button}
                disabled={loading}
                fullWidth
              >
                SignUp
                {loading && (
                  <CircularProgress
                    size={30}
                    className={classes.progress}
                  />
                )}
              </Button>
            </form>
          </Grid>
        </Grid>
   export const loginUser = (userData, history) => dispatch => {
        dispatch({ type: LOADING_UI });
        axios
         .post("/login", userData)
         .then(res => {
             setAuthorizationHeader(res.data.token);
             dispatch(getUserData());
             dispatch({ type: CLEAR_ERRORS });
             history.push("/home");
         })
    .catch(err => {
       dispatch({
          type: SET_ERRORS,
          payload: err.response.data
         });
       });
      };

    export const signupUser = (newUserData, history) => dispatch => {
        dispatch({ type: LOADING_UI });
        axios
         .post("/signup", newUserData)
         .then(res => {
              setAuthorizationHeader(res.data.token);
              dispatch(getUserData());
              dispatch({ type: CLEAR_ERRORS });
              history.push("/home");
        })
  .catch(err => {
    dispatch({
      type: SET_ERRORS,
      payload: err.response.data
   });
 });
};

Solution

  • Quick fix: Change the button type so that it's just a normal button instead of a submit button. Then create a function which takes the form id as an argument and submits that form.

    But really both forms should not be being submitted at the same time anyway. Is there anything in your code that you haven't shown us which explains why they might be linked in this way? Ar ethey nested or in a table for example?