Categories
React Bootstrap

React Bootstrap — Form State and Validation, and Input Groups

Spread the love

React Bootstrap is one version of Bootstrap made for React.

It’s a set of React components that have Bootstrap styles.

In this article, we’ll look at how to add forms and input groups to a React app with React Bootstrap.

Form Libraries

We can use form libraries to make form validation easier for us.

React Bootstrap has integration with the Formik library to let us bind our input values to states.

It also does form validation when it’s used with Yup.

For instance, we can use it by writing:

import React from "react";
import Form from "react-bootstrap/Form";
import Col from "react-bootstrap/Col";
import Button from "react-bootstrap/Button";
import { Formik } from "formik";
import * as yup from "yup";
import "bootstrap/dist/css/bootstrap.min.css";

const schema = yup.object({
  firstName: yup.string().required(),
  lastName: yup.string().required(),
  username: yup.string().required(),
  city: yup.string().required(),
  region: yup.string().required(),
  postalcode: yup.string().required(),
  terms: yup.bool().required()
});

export default function App() {
  return (
    <Formik
      validationSchema={schema}
      onSubmit={console.log}
      initialValues={{
        firstName: "james",
        lastName: "smith"
      }}
    >
      {({
        handleSubmit,
        handleChange,
        handleBlur,
        values,
        touched,
        isValid,
        errors
      }) => (
        <Form noValidate onSubmit={handleSubmit}>
          <Form.Row>
            <Form.Group as={Col} md="6">
              <Form.Label>First name</Form.Label>
              <Form.Control
                type="text"
                name="firstName"
                value={values.firstName}
                onChange={handleChange}
                isValid={touched.firstName && !errors.firstName}
              />
              <Form.Control.Feedback>Looks good</Form.Control.Feedback>
            </Form.Group>
            <Form.Group as={Col} md="6">
              <Form.Label>Last name</Form.Label>
              <Form.Control
                type="text"
                name="lastName"
                value={values.lastName}
                onChange={handleChange}
                isValid={touched.lastName && !errors.lastName}
              />

              <Form.Control.Feedback>Looks good</Form.Control.Feedback>
            </Form.Group>
          </Form.Row>
          <Form.Row>
            <Form.Group as={Col} md="6">
              <Form.Label>City</Form.Label>
              <Form.Control
                type="text"
                placeholder="City"
                name="city"
                value={values.city}
                onChange={handleChange}
                isInvalid={!!errors.city}
              />

              <Form.Control.Feedback type="invalid">
                {errors.city}
              </Form.Control.Feedback>
            </Form.Group>
            <Form.Group as={Col} md="3">
              <Form.Label>State</Form.Label>
              <Form.Control
                type="text"
                placeholder="Region"
                name="region"
                value={values.region}
                onChange={handleChange}
                isInvalid={!!errors.region}
              />
              <Form.Control.Feedback type="invalid">
                {errors.region}
              </Form.Control.Feedback>
            </Form.Group>
            <Form.Group as={Col} md="3">
              <Form.Label>Postal Code</Form.Label>
              <Form.Control
                type="text"
                placeholder="Postal Code"
                name="postalcode"
                value={values.postalcode}
                onChange={handleChange}
                isInvalid={!!errors.postalCode}
              />

              <Form.Control.Feedback type="invalid">
                {errors.zip}
              </Form.Control.Feedback>
            </Form.Group>
          </Form.Row>
          <Form.Group>
            <Form.Check
              required
              name="terms"
              label="Agree to terms"
              onChange={handleChange}
              isInvalid={!!errors.terms}
              feedback={errors.terms}
            />
          </Form.Group>
          <Button type="submit">Submit</Button>
        </Form>
      )}
    </Formik>
  );
}

We create the form validation with Yup before we create the component.

All the fields are marked required.

Then in the component, we use the Formik component to create the form.

We set the initial values with the initialValues prop.

It takes a callback that has an object with various properties that we’ll pass into our form control components.

handleSubmit is passed into the onSubmit prop of the form element.

handleChange updates the state from the input values of the form controls, so it’s passed into the onChange prop of each form control.

values is an object with the inputted values, so it’s passed in as the value of each form control.

touched indicates whether the user has interacted with the form or not.

We can use that while we check form control validity.

errors is an object with the form validations errors divided by field.

So we can also use that in the isValid prop.

Once we have that, we have a form with validation and we didn’t have to write code to set the input values of each field as a state value and check them ourselves.

Input Group

We can use the InputGroup component to lets us add content besides an input box.

For instance, we can write:

import React from "react";
import FormControl from "react-bootstrap/FormControl";
import InputGroup from "react-bootstrap/InputGroup";
import "bootstrap/dist/css/bootstrap.min.css";

export default function App() {
  return (
    <div>
      <InputGroup className="mb-3">
        <InputGroup.Prepend>
          <InputGroup.Text>@</InputGroup.Text>
        </InputGroup.Prepend>
        <FormControl placeholder="Name" />
      </InputGroup>
    </div>
  );
}

to add an InputGroup with the @ sign to the left of the input box.

InputGroup.Prepend lets us add content to the left of the input.

We can also use InputGroup.Append to add content to the right of the input.

For example, we can write:

import React from "react";
import FormControl from "react-bootstrap/FormControl";
import InputGroup from "react-bootstrap/InputGroup";
import "bootstrap/dist/css/bootstrap.min.css";

export default function App() {
  return (
    <div>
      <InputGroup className="mb-3">
        <FormControl placeholder="Name" />
        <InputGroup.Append>
          <InputGroup.Text>@</InputGroup.Text>
        </InputGroup.Append>
      </InputGroup>
    </div>
  );
}

Input Group Sizing

We can change the size of the InputGroup by using the size prop.

For example, we can write:

import React from "react";
import FormControl from "react-bootstrap/FormControl";
import InputGroup from "react-bootstrap/InputGroup";
import "bootstrap/dist/css/bootstrap.min.css";

export default function App() {
  return (
    <div>
      <InputGroup size="sm">
        <FormControl placeholder="Name" />
        <InputGroup.Append>
          <InputGroup.Text>@</InputGroup.Text>
        </InputGroup.Append>
      </InputGroup>
    </div>
  );
}

to make the input group extra small.

We can also make the size extra large with lg as the value.

Conclusion

Form validation can be made easy with Formik and Yup integration.

Input groups lets us add content to the left or right of the input box.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *