Maramal
Maramal

Reputation: 3466

React Bootstrap can't validate forms

I am trying to add some validation to my React + Bootstrap project but I am not able to achieve this. According to Bootstrap Form validation documentation I have to provide a Form.Control.Feedback component to the Form Group component.

But is not showing the errors but check marks like everything is fine. I created this Code Sandbox yo demostrate what I need to achieve and what is showing me:

Edit magical-mcclintock-rnthy

And just in case, this is the code if you don't need the sandbox to see the error:

import React, { useState } from "react";
import "./styles.css";
import { Container, Form, Button } from "react-bootstrap";
import validator from "validator";
import empty from "is-empty";

export default function App() {
  const [validated, setValidated] = useState(false);
  const [errors, setErrors] = useState({});
  const [phone, setPhone] = useState("");
  const [email, setEmail] = useState("");

  const handleSubmit = async e => {
    e.preventDefault();

    const errors = {};

    // validation
    if (!validator.isMobilePhone(phone, ["es-UY"])) {
      errors.phone = "Invalid phone number";
    }

    if (!validator.isEmail(email)) {
      errors.email = "Invalid email address";
    }

    if (!empty(errors)) {
      setErrors(errors);
    }

    setValidated(true);
  };

  return (
    <Container>
      <Form validated={validated} onSubmit={handleSubmit}>
        <h1>Test form</h1>
        <Form.Group controlId="phone">
          <Form.Label>Phone number</Form.Label>
          <Form.Control
            type="tel"
            value={phone}
            onChange={e => setPhone(e.target.value)}
          />
          <Form.Control.Feedback type="invalid">Error</Form.Control.Feedback>
          {errors.phone && (
            <Form.Control.Feedback type="invalid">
              {errors.phone}
            </Form.Control.Feedback>
          )}
        </Form.Group>
        <Form.Group controlId="email">
          <Form.Label>Email address</Form.Label>
          <Form.Control
            type="email"
            value={email}
            onChange={e => setEmail(e.target.value)}
            feedback="Error"
          />
          {errors.email && (
            <Form.Control.Feedback type="invalid">
              {errors.email}
            </Form.Control.Feedback>
          )}
        </Form.Group>
        <Form.Group controld="submit">
          <Button type="submit" variant="primary">
            Submit
          </Button>
          <Button
            type="reset"
            variant="info"
            style={{ marginLeft: 10 }}
            onClick={() => {
              setErrors({});
              setValidated(false);
            }}
          >
            Reset
          </Button>
        </Form.Group>
      </Form>
    </Container>
  );
}

So, what am I doing wrong?

Upvotes: 2

Views: 7510

Answers (1)

Niraj Chutteeya
Niraj Chutteeya

Reputation: 215

Make sure you've set setValidated as false for the errors

const handleSubmit = async e => {
    e.preventDefault();

    const allErrors = {};  // <--- changed this as well

    // validation
    if (!validator.isMobilePhone(phone, ["es-UY"])) {
      allErrors.phone = "Invalid phone number";
    }

    if (!validator.isEmail(email)) {
      allErrors.email = "Invalid email address";
    }

    if (!empty(allErrors)) {
      setErrors(allErrors);
      setValidated(false);
    }
    else {
      setValidated(true);
    }
  };

In your field add isInvalid as props:

<Form.Control
   type="tel"
   value={phone}
   isInvalid={!!errors.phone}   <------
   onChange={e => setPhone(e.target.value)}
 />

  <Form.Control
    type="text"
    value={email}
    isInvalid={!!errors.email}  <-----
    onChange={e => setEmail(e.target.value)}
    feedback="Error"
   />

Upvotes: 5

Related Questions