Creating a book entry form with validation using Formik in a React application is a common task when building a library management system or any application that involves data input. Formik is a powerful library for managing forms in React, and it simplifies the process of handling form state and validation. In this step-by-step guide, we’ll create an AddBook component with Formik and demonstrate how to add form validation. Let’s get started!
Setup React Project
Before you begin, make sure you have a React project set up. You can create a new React project using tools like Create React App or set up your project manually.
Install Formik and Yup
Before you start, make sure you have Formik and Yup installed in your project. You can install them using npm or yarn:
npm install formik yup
OR
yarn add formik yup
Create the AddBook.js Component
Create a new file named AddBook.js and import the necessary modules and components:
import React from "react";
import Button from "react-bootstrap/Button";
import Col from "react-bootstrap/Col";
import Form from "react-bootstrap/Form";
import Row from "react-bootstrap/Row";
import * as formik from "formik";
import * as yup from "yup";
import { useTheme } from "../ThemeContext.js";
const AddBook = () => {
const { theme } = useTheme();
const { Formik } = formik;
const schema = yup.object().shape({
bookTitle: yup.string().required(),
bookName: yup.string().required(),
authorName: yup.string().required(),
quantity: yup.string().required(),
isbn: yup.string().required(),
genre: yup.string().required(),
publicationYear: yup.string().required(),
bookDescription: yup.string().required(),
bookLocation: yup.mixed().required(),
});
const onAddBook = (values) => {
var bookObj = [
{
id: 1,
title: values.bookTitle,
author: values.authorName,
isbn: values.isbn,
genre: values.genre,
description: values.description,
publication_year: values.publicationYear,
language: "English",
cover_image: "/Images/book-Cover.jpg",
total_copies: values.quantity,
available_copies: values.quantity,
location: values.location,
is_borrowed: false,
},
];
localStorage.setItem("addedBooks", JSON.stringify(bookObj));
};
return (
<>
<div className={`App ${theme}`}>
<h1>Add New Book</h1>
<Formik
validationSchema={schema}
// onSubmit={onAddBook}
initialValues={{
bookTitle: "",
authorName: "",
quantity: "",
isbn: "",
genre: "",
publicationYear: "",
bookDescription: "",
bookLocation: "",
}}
>
{({ handleSubmit, handleChange, values, touched, errors }) => (
<Form noValidate onSubmit={handleSubmit} className="add_book">
<Row className="mb-3">
{/* <Form.Group
as={Col}
md="3"
controlId="validationFormik104"
className="position-relative"
>
<Form.Label>Book Title</Form.Label>
<Form.Control
type="text"
placeholder="Book Title"
name="bookTitle"
value={values.bookTitle}
onChange={handleChange}
isInvalid={!!errors.bookTitle}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.genre}
</Form.Control.Feedback>
</Form.Group> */}
<Form.Group
as={Col}
md="5"
controlId="validationFormik101"
className="position-relative"
>
<Form.Label>Book Title</Form.Label>
<Form.Control
type="text"
name="bookTitle"
placeholder="Book Title"
value={values.bookTitle}
onChange={handleChange}
isInvalid={touched.bookTitle && !!errors.bookTitle}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.bookTitle}
</Form.Control.Feedback>
</Form.Group>
<Form.Group
as={Col}
md="4"
controlId="validationFormik102"
className="position-relative"
>
<Form.Label>Author Name</Form.Label>
<Form.Control
type="text"
name="authorName"
placeholder="Author Name"
value={values.authorName}
onChange={handleChange}
isInvalid={touched.authorName && !!errors.authorName}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.authorName}
</Form.Control.Feedback>
</Form.Group>
<Form.Group
as={Col}
md="2"
controlId="validationFormik103"
className="position-relative"
>
<Form.Label>Quantity</Form.Label>
<Form.Control
type="number"
placeholder="Number of Books"
name="quantity"
value={values.quantity}
onChange={handleChange}
isInvalid={touched.quantity && !!errors.quantity}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.quantity}
</Form.Control.Feedback>
</Form.Group>
</Row>
<Row className="mb-3">
<Form.Group
as={Col}
md="4"
controlId="validationFormik102"
className="position-relative"
>
<Form.Label>isbn</Form.Label>
<Form.Control
type="text"
name="isbn"
placeholder="ISBN"
value={values.isbn}
onChange={handleChange}
isInvalid={touched.isbn && !!errors.isbn}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.isbn}
</Form.Control.Feedback>
</Form.Group>
<Form.Group
as={Col}
md="3"
controlId="validationFormik104"
className="position-relative"
>
<Form.Label>Genre</Form.Label>
<Form.Control
type="text"
placeholder="Genre"
name="genre"
value={values.genre}
onChange={handleChange}
isInvalid={!!errors.genre}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.genre}
</Form.Control.Feedback>
</Form.Group>
<Form.Group
as={Col}
md="4"
controlId="validationFormik105"
className="position-relative"
>
<Form.Label>Publication Year</Form.Label>
<Form.Control
type="text"
placeholder="Publication Year"
name="publicationYear"
value={values.publicationYear}
onChange={handleChange}
isInvalid={!!errors.publicationYear}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.publicationYear}
</Form.Control.Feedback>
</Form.Group>
</Row>
<Row className="mb-3">
<Form.Group
as={Col}
md="7"
controlId="validationFormik105"
className="position-relative"
>
<Form.Label>Book Description</Form.Label>
<Form.Control
as="textarea"
rows={2}
name="bookDescription"
value={values.bookDescription}
onChange={handleChange}
isInvalid={!!errors.bookDescription}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.bookDescription}
</Form.Control.Feedback>
</Form.Group>
<Form.Group
as={Col}
md="4"
controlId="validationFormik103"
className="position-relative"
>
<Form.Label>Book Location</Form.Label>
<Form.Control
type="text"
placeholder="Book Location"
name="bookLocation"
value={values.bookLocation}
onChange={handleChange}
isInvalid={touched.bookLocation && !!errors.bookLocation}
/>
<Form.Control.Feedback type="invalid" tooltip>
{errors.bookLocation}
</Form.Control.Feedback>
</Form.Group>
</Row>
<Button type="submit" onClick={() => onAddBook(values)}>
Add Book
</Button>
</Form>
)}
</Formik>
</div>
</>
);
};
export default AddBook;
In this code:
- We import the necessary components and libraries from Formik and Yup.
- We define the AddBook functional component, which contains the book entry form.
- We set up the initial form values, validation schema, and a function to handle the form submission.
- Inside the Formik component, we render form fields using the Field component and display validation errors using the ErrorMessage component.
- We use the validationSchema to specify validation rules for each form field.
After submitting the form, as of now the data will be stored in the localStorage and it will look something like this:
Display the AddBook Component
In your application, import and display the AddBook component where you want to provide the book entry form.
import React from 'react';
import AddBook from './AddBook'; // Import the AddBook component
function App() {
return (
<div className="App">
<AddBook /> {/* Display the AddBook component */}
</div>
);
}
export default App;
Style the Form
You can apply CSS styles to your form to make it visually appealing and user-friendly. You can use your preferred CSS framework or write custom styles.
Test and Validate
Run your React application and navigate to the page where the AddBook component is displayed. You should see the book entry form with validation. Try submitting the form with valid and invalid data to ensure that validation works as expected. Ensuring the validations whether it works as expected, results are as shown below:
Conclusion
You’ve successfully created an AddBook component with Formik and added form validation. This component can serve as a starting point for adding books to your library management system. You can further extend it by adding functionality to submit book data to a backend server or store it in your application’s state.