Recently I was working with React Bootstrap forms, and I wanted to add validations, so I am sharing the code you can use to hookup Formik and also utilizing Yup to add schema based validations to your React-Bootstrap forms. I could not find much resource building the same, hope you find it easy now.
React-Bootstrap Form validations with formik
import { ErrorMessage, Field, Formik } from 'formik';
import { Button, Card, Col, Container, Form, Row } from "react-bootstrap";
const Register = () => {
<Formik
initialValues={{
username: '',
first_name: '',
last_name: '',
email: '',
password: '',
password2: ''
}}
validate={values => {
const errors={};
if(!values.username){
errors.username = 'Username is required';
}
if(!values.first_name){
errors.first_name = 'First Name is required';
} else if (values.first_name.length > 15) {
errors.first_name = 'Must be 15 characters or less';
}
if(!values.last_name){
errors.last_name = 'Last Name is required';
}
if(!values.email){
errors.email = 'Email is required';
}else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
errors.email = 'Invalid email address';
}
if(!values.password){
errors.password = 'Password is required';
}
if(!values.password2){
errors.password2 = 'Please Confirm Password';
}
return errors;
}}
onSubmit={values => {
if(values.username && values.first_name && values.last_name && values.email && values.password && values.password2){
console.log('form submitted!!')
}
}}>
{({handleChange, handleSubmit, handleBlur, values, errors, touched }) => (
<Form>
<Field
name="username"
render={({field, formProps}) => (
<Form.Group controlId="username">
<Form.Label> Username</Form.Label>
<Form.Control type={'text'} value={field.value} onChange={handleChange} />
{/* {errors.username && touched.username && errors.username} */}
<ErrorMessage name="username" render={msg => <Card border="danger">{msg} </Card>} />
</Form.Group>
)}
/>
<Form.Row>
<Col>
<Field
name="first_name"
render={({field, formProps}) => (
<Form.Group controlId="first_name">
<Form.Label> First Name </Form.Label>
<Form.Control type={'text'} value={field.value} onChange={handleChange} />
<ErrorMessage name="first_name" render={msg => <Card border="danger">{msg} </Card>} />
</Form.Group>
)}
/>
</Col>
<Col>
<Field
name="last_name"
render={({field, formProps}) => (
<Form.Group controlId="last_name">
<Form.Label> Last Name </Form.Label>
<Form.Control type={'text'} value={field.value} onChange={handleChange} />
<ErrorMessage name="last_name" render={msg => <Card border="danger">{msg} </Card>} />
</Form.Group>
)}
/>
</Col>
</Form.Row>
<Field
name="email"
render={({field, formProps}) => (
<Form.Group controlId="email">
<Form.Label> Email Address</Form.Label>
<Form.Control type={'email'} value={field.value} onChange={handleChange} />
<ErrorMessage name="email" render={msg => <Card border="danger">{msg}</Card>} />
</Form.Group>
)}
/>
<Field
name="password"
render={({field, formProps}) => (
<Form.Group controlId="password">
<Form.Label> Password</Form.Label>
<Form.Control type={'password'} value={field.value} onChange={handleChange} />
<ErrorMessage name="password" render={msg => <Card border="danger">{msg}</Card>} />
</Form.Group>
)}
/>
<Field
name="password2"
render={({field, formProps}) => (
<Form.Group controlId="password2">
<Form.Label> Confirm Password</Form.Label>
<Form.Control type={'password'} value={field.value} onChange={handleChange} />
<ErrorMessage name="password2" render={msg => <Card border="danger">{msg}</Card>} />
</Form.Group>
)}
/>
<Button type="submit" onClick={handleSubmit}>
Register
</Button>
</Form>
)}
</Formik>
</Container>
)
export default Register;
React Bootstrap Form Validations using Formik and Yup

So, lets add Yup Validations to our form, it might change the structure a bit
import { ErrorMessage, Field, Formik } from 'formik';
import { Button, Card, Col, Container, Form, Row } from "react-bootstrap";
import * as Yup from 'yup';
// validations using yup
const registerValidationsSchema = Yup.object({
username: Yup.string()
.max(20, 'Must be 20 characters or less')
.required('Required'),
first_name: Yup.string()
.max(15, 'Must be 15 characters or less')
.required('Required'),
last_name: Yup.string()
.max(20, 'Must be 20 characters or less')
.required('Required'),
email: Yup.string().email('Invalid email address').required('Required'),
password: Yup.string()
.max(8, 'Must be 8 characters or less')
.required('Required'),
password2: Yup.string()
.max(8, 'Must be 8 characters or less')
.required('Required')
});
const Register = () => (
<Formik
initialValues = {{
username: '',
first_name: '',
last_name: '',
email: '',
password: '',
password2: ''
}}
validationSchema={registerValidationsSchema}
onSubmit={values => {
console.log('values', values);
}}
>
{props => (
<Form onSubmit={props.handleSubmit}>
<Field name="username">
{({field, form, meta}) => (
<Form.Group controlId="username">
<Form.Label> Username</Form.Label>
<Form.Control
type={'text'}
value={field.value}
onChange={props.handleChange}
onBlur={props.handleBlur}
/>
{/* {errors.username && touched.username && errors.username} */}
<ErrorMessage name="username" render={msg => <Card border="danger">{msg} </Card>} />
</Form.Group>
)}
</Field>
<Form.Row>
<Field name="first_name">
{({field, form, meta}) => (
<Col>
<Form.Group controlId="first_name">
<Form.Label> First Name </Form.Label>
<Form.Control type={'text'} value={field.value} onChange={props.handleChange} onBlur={props.handleBlur} />
<ErrorMessage name="first_name" render={msg => <Card border="danger">{msg} </Card>} />
</Form.Group>
</Col>
)}
</Field>
<Field name="last_name">
{({field, form, meta}) => (
<Col>
<Form.Group controlId="last_name">
<Form.Label> Last Name </Form.Label>
<Form.Control type={'text'} value={field.value} onChange={props.handleChange} onBlur={props.handleBlur} />
<ErrorMessage name="last_name" render={msg => <Card border="danger">{msg} </Card>} />
</Form.Group>
</Col>
)}
</Field>
</Form.Row>
<Field name="email">
{({field, form, meta}) => (
<Form.Group controlId="email">
<Form.Label> Email Address</Form.Label>
<Form.Control type={'email'} value={field.value} onChange={props.handleChange} onBlur={props.handleBlur} />
<ErrorMessage name="email" render={msg => <Card border="danger">{msg}</Card>} />
</Form.Group>
)}
</Field>
<Form.Row>
<Field name="password">
{({field, form, meta}) => (
<Col>
<Form.Group controlId="password">
<Form.Label> Password</Form.Label>
<Form.Control type={'password'} value={field.value} onChange={props.handleChange} onBlur={props.handleBlur} />
<ErrorMessage name="password" render={msg => <Card border="danger">{msg}</Card>} />
</Form.Group>
</Col>
)}
</Field>
<Field name="password2">
{({field, form, meta}) => (
<Col>
<Form.Group controlId="password2">
<Form.Label> Confirm Password</Form.Label>
<Form.Control type={'password'} value={field.value} onChange={props.handleChange} onBlur={props.handleBlur} />
<ErrorMessage name="password2" render={msg => <Card border="danger">{msg}</Card>} />
</Form.Group>
</Col>
)}
</Field>
</Form.Row>
<Button type="submit">
Register
</Button>
</Form>
)}
</Formik>
</Col>
</Row>
</Container>
)
export default Register;
to customize further, you can add feedback for forms fields :
<Field name="username">
{({field, form, meta}) => (
<Form.Group controlId="username">
<Form.Label> Username</Form.Label>
<Form.Control
type={'text'}
placeholder="Enter username"
value={field.value}
onChange={props.handleChange}
onBlur={props.handleBlur}
isInvalid={!!props.errors.username}
required
/>
<Form.Control.Feedback type="invalid">
{props.errors.username && props.touched.username && props.errors.username}
</Form.Control.Feedback>
{/* {errors.username && touched.username && errors.username} */}
{/* <ErrorMessage name="username" render={msg => <Card border="danger">{msg} </Card>} /> */}
</Form.Group>
)}
</Field>

now let’s test our form

The form is working fine !
Thanks for reading ! Stay Tuned for more.
Leave a Reply