In this article, we will understand the ReactJS form validation for React Bootstrap UI form components using the Rect Hook Form library.
Create ReactJS Application:
Let's create a simple ReactJS application to accomplish our demo.
npx create-react-app name-of-your-app
Install React Bootstrap Library:
Let's install React Bootstrap UI library.
npm install react-bootstrap bootstrap
Import the bootstrap CSS file reference onto the 'index.js' file
src/index.js:
import 'bootstrap/dist/css/bootstrap.min.css';
Install React Hook From Library:
Install the React Hook Form Library.
npm install react-hook-form
A Simple React Bootstrap Form Using React Hook Form Library:
Let's create a simple Rect bootstrap Form and integrate the React Hook Form library to read the form data.
src/App.js:
import "./App.css"; import Row from "react-bootstrap/Row"; import Button from "react-bootstrap/Button"; import Col from "react-bootstrap/Col"; import Form from "react-bootstrap/Form"; import { Container } from "react-bootstrap"; import { Controller, useForm } from "react-hook-form"; function App() { const { control, handleSubmit } = useForm({ defaultValues:{ firstName:'' } }); const submitForm = (data) => { console.log(data); }; return ( <> <Container> <Form noValidate onSubmit={handleSubmit(submitForm)}> <Row className="mb-3"> <Form.Group as={Col} md="4" controlId="validationCustom01"> <Form.Label>First Name</Form.Label> <Controller name="firstName" control={control} render={({ field }) => ( <Form.Control {...field} type="text" placeholder="First name" /> )} /> </Form.Group> </Row> <Button type="submit">Submit form</Button> </Form> </Container> </> ); } export default App;
- (Line: 10-14) The 'useForm' loads from the 'react-hook-form' library. Here we define our field name eg- 'firstName' with default values inside of the 'defaultValues' object. From the 'useForm' we read values like 'control' and 'handleSubmit'. The 'control' variable will be used on the 'Controller' element tag(from 'react-hook-form') so that form has control over the actual element inside of it. The 'handleSubmit' has to be registered with the forms 'onSubmit' event so that it can read the form data.
- (Line: 16-18) The 'submitForm' is our custom function. It will be passed as an input parameter to the 'handleSubmit'. The 'data' input parameter will be our form data.
- (Line: 23) The 'onSubmit' event registered with 'handleSubmit'.
- (Line: 28-38) The 'Form.Control' is react-bootstrap component. So to integrate any third-party library components with 'React Hook Forms' we have to use the 'Controller' element(from the 'react-hook-form' library). Here 'control' attribute of the 'Controller' element is assigned with our 'control' variable from the 'useForm'. Here 'name' attribute of the 'Controller' element must match with the default field name in the 'useForm'. Here 'render' attribute of the 'Controller' element is assigned to the pre-define arrow function that returns our 'Form.Control'. The 'field' value has to add to the 'Form.Control'.
Required Field Validation:
Let's implement the required field validation in our form.
src/App.js:
import "./App.css"; import Row from "react-bootstrap/Row"; import Button from "react-bootstrap/Button"; import Col from "react-bootstrap/Col"; import Form from "react-bootstrap/Form"; import { Container } from "react-bootstrap"; import { Controller, useForm } from "react-hook-form"; function App() { const { control, handleSubmit, formState: { errors }, } = useForm({ defaultValues: { firstName: "", }, }); const submitForm = (data) => { console.log(data); }; return ( <> <Container> <Form noValidate onSubmit={handleSubmit(submitForm)}> <Row className="mb-3"> <Form.Group as={Col} md="4" controlId="validationCustom01"> <Form.Label>First Name</Form.Label> <Controller name="firstName" control={control} rules={{ required: true }} render={({ field }) => ( <Form.Control {...field} type="text" placeholder="First name" isInvalid={errors.firstName} /> )} /> {errors.firstName && ( <Form.Control.Feedback type="invalid"> First Name is required </Form.Control.Feedback> )} </Form.Group> </Row> <Button type="submit">Submit form</Button> </Form> </Container> </> ); } export default App;
- (Line: 13) Here 'formState:{errors}' from 'useForm' to handle and store the error messages.
- (Line: 34) Here 'rules' attribute of 'Controller' element to specify the validation rules. Here we added 'required' validator.
- (Line: 40) The 'isInvalid' property on 'Form.Control' represents the red-colored border to the element. So here to check 'firstName' field errors using the 'errors.firstName'.
- (Line: 44-48) If the 'firstName' field is invalid then will render the error message.
Min & Max Range Validations:
Let's implement the 'Min' & 'Max' range validations.
src/App.js:
import "./App.css"; import Row from "react-bootstrap/Row"; import Button from "react-bootstrap/Button"; import Col from "react-bootstrap/Col"; import Form from "react-bootstrap/Form"; import { Container } from "react-bootstrap"; import { Controller, useForm } from "react-hook-form"; function App() { const { control, handleSubmit, formState: { errors }, } = useForm({ defaultValues: { age: "", }, }); const submitForm = (data) => { console.log(data); }; return ( <> <Container> <Form noValidate onSubmit={handleSubmit(submitForm)}> <Row className="mb-3"> <Form.Group as={Col} md="4" controlId="validationCustom01"> <Form.Label>Age</Form.Label> <Controller name="age" control={control} rules={{ min:10, max:30 }} render={({ field }) => ( <Form.Control {...field} type="text" placeholder="Age" isInvalid={errors.age} /> )} /> {errors.age?.type == "min" && ( <Form.Control.Feedback type="invalid"> Minimum age is 10 </Form.Control.Feedback> )} {errors.age?.type == "max" && ( <Form.Control.Feedback type="invalid"> Maximum age is 30 </Form.Control.Feedback> )} </Form.Group> </Row> <Button type="submit">Submit form</Button> </Form> </Container> </> ); } export default App;
- (Line: 16) Registered a form field name like 'age' with a default value.
- (Line: 32) The 'name' attribute value of the 'Controller' element must match with field names registered in 'useForm'.
- (Line: 34) The 'rules' attribute is registered with 'max' and 'min' validation rules.
- (Line: 40) Checking for validation errors like 'errors.age'
- (Line: 44) Checking for 'min' validation.
- (Line: 49) Checking for 'max' validation.
Pattern Matching Validations:
Let's implement an email validation using 'Pattern' matching.
src/App.js:
import "./App.css"; import Row from "react-bootstrap/Row"; import Button from "react-bootstrap/Button"; import Col from "react-bootstrap/Col"; import Form from "react-bootstrap/Form"; import { Container } from "react-bootstrap"; import { Controller, useForm } from "react-hook-form"; function App() { const { control, handleSubmit, formState: { errors }, } = useForm({ defaultValues: { email: "", }, }); const submitForm = (data) => { console.log(data); }; return ( <> <Container> <Form noValidate onSubmit={handleSubmit(submitForm)}> <Row className="mb-3"> <Form.Group as={Col} md="4" controlId="validationCustom01"> <Form.Label>Email</Form.Label> <Controller name="email" control={control} rules={{ required:true, pattern: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ }} render={({ field }) => ( <Form.Control {...field} type="text" placeholder="email" isInvalid={errors.email} /> )} /> {errors.email?.type == "pattern" && ( <Form.Control.Feedback type="invalid"> Invalid email </Form.Control.Feedback> )} {errors.email?.type == "required" && ( <Form.Control.Feedback type="invalid"> Email required </Form.Control.Feedback> )} </Form.Group> </Row> <Button type="submit">Submit form</Button> </Form> </Container> </> ); } export default App;
- (Line: 16)Registered a form field name like 'email' with a default value.
- (Line: 32) The 'name' attribute value of the 'Controller' element must match with field names registered in 'useForm'.
- (Line: 34) The 'rules' attribute registered with 'pattern' validation. Here we check the email pattern.
- (Line: 44-48) Display the email validation error message.
Custom Validation:
Let's implement the custom validation by comparing 2 input fields like they should not have the same value.
src/App.js:
import "./App.css"; import Row from "react-bootstrap/Row"; import Button from "react-bootstrap/Button"; import Col from "react-bootstrap/Col"; import Form from "react-bootstrap/Form"; import { Container } from "react-bootstrap"; import { Controller, useForm } from "react-hook-form"; function App() { const { control, handleSubmit, formState: { errors }, getValues, } = useForm({ defaultValues: { phone1: "", phone2: "", }, }); const submitForm = (data) => { console.log(data); }; const phone1AndPhone2ShouldNotMatch = (value) => { return value !== getValues("phone1"); }; return ( <> <Container> <Form noValidate onSubmit={handleSubmit(submitForm)}> <Row className="mb-3"> <Form.Group as={Col} md="4" controlId="validationCustom01"> <Form.Label>Phone</Form.Label> <Controller name="phone1" control={control} render={({ field }) => ( <Form.Control {...field} type="text" placeholder="Phone 1" /> )} /> </Form.Group> <Form.Group as={Col} md="4" controlId="validationCustom01"> <Form.Label>Phone 2</Form.Label> <Controller name="phone2" control={control} rules={{ validate: phone1AndPhone2ShouldNotMatch }} render={({ field }) => ( <Form.Control {...field} type="text" placeholder="Phone 2" isInvalid={errors.phone2} /> )} /> {errors.phone2?.type == "validate" && ( <Form.Control.Feedback type="invalid"> Phone1 and Phone2 can't be same </Form.Control.Feedback> )} </Form.Group> </Row> <Button type="submit">Submit form</Button> </Form> </Container> </> ); } export default App;
- (Line: 14) The 'getValues' from the 'useForm' helps to read any field value in the form.
- (Line: 17&18) The 'phone1' & 'phone2' are form field names.
- (Line: 26-28) The 'phone1AndPhone2ShouldNotMatch' is our custom validation method. This method should return a boolean value, 'false' means validation failed, 'true' means validation success.
- (Line: 50) Oure 'phone1AndPhone2ShoutlNotMatch' assigned to the 'validate' rule.
- (Line: 60) To display our error message check the validation type like 'validate'.
Support Me!
Buy Me A Coffee
PayPal Me
Video Session:
Wrapping Up:
Hopefully, I think this article delivered some useful information on the React JS(v18) Form Validations Using React Hook Form Library with React Bootstrap UI components. I love to have your feedback, suggestions, and better techniques in the comment section below.
Cheto, gracias!!
ReplyDelete