Forms Validation Part-2


This is Continuation to our previos article in which we have discussed about building Forms and Validating Forms in React using useFormik function. In this article, we will understand the Formik Component.

If we look at the code what we have written in our last session, though we have tried to make our code better by using getProps method, still we have to pass that to each input and we have to the code written for displaying the Validation Messages. To save us even more time and to make our code much better and easier, Formik comes with few built in components. They are <Formik />, <Form />, <Field />, and <ErrorMessage /><Formik/> is a component that helps us with building forms. Internally, Formik uses useFormik function to create the <Formik> component. useFormik() is a custom React hook that will return all Formik state and helpers directly. Despite its name, it is not meant for the majority of use cases.

Let's now swap out the useFormik() hook for the Formik's <Formik> component. Since it's a component, we'll convert the object passed to useFormik() to JSX, with each key becoming a prop. That means initialValues, validationSchema and onSubmit will be passed to this Formik Component as properties. Lets go to Index.js file from our demo project, in our EmployeeComponent’s return Method, Call a Component Called as Formik and to this Component, lets pass initialValues, validationSchema and onSubmit as properties. We will pass the same values we have used in useFormik function object.

return (

    <Formik initialValues= {{

      Id: '',

      Name: '',

      Location: '',

      Salary:'',

      EmailId:''

    }} validationSchema={yup.object({

      Name:yup.string().max(20,'Name should not exceed 20 Characters').

      required('Please Enter Employee Name'),

      Location: yup.string()

        .required('Please Enter Employee Location'),

      EmailId: yup.string()

        .email('Invalid email address')

        .required('Please Enter Email Id')

    })} onSubmit= {values => {

      alert(JSON.stringify(values));

    }}>

Lets add a div container and with in this Container, place a h2 tag with text as New Employee Form. Now lets call Form Component as Child Component from this Formik Component. Add a paragraph tag and place a label with Text as Employee ID. Now instead of placing an input, We will use another Component called as Field. To this field we will pass what type of input we want like text or number or email.

<p>

          <label htmlFor="Id">Employee ID </label>

          <Field name="Id" type="text"></Field>

</p>

Now lets repeat the same for Rest of the Form inputs like Name, Location, Salary and Email ID. Now We should display the Error messages when there is any Validation Error. In order to do this, we will use another Component called as ErrorMessage and specify property name for which the error should be displayed. We use an attribute called as name to specify the Property Name from our Formik values object. Now we will repeat the same for Location and Email ID as well. Lets save our changes, navigate to the browser. 

As we keep playing with the form inputs, respective validation messages are displayed. When we click on the button, we can see that forms data is displayed in an alert as a json object. Now if we look at the Code, Formik is the Parent Component and it has a nesting of Child Components. They are Form, Field and Error Message. Formik uses React Context internally to pass the data between these Components. 

We may think of using useFormik function if we don’t want to make use of React Context because we may want to use some other ways to share the data. In rest of the cases, it is recommended to use Formik Component. One must remember that We cant use Form, field, Error Message Components inside useFormik function. In our example we have used Field for generating the input elements. We can use Field Component to generate other html elements as well.

Now lets say we want to have a dropdownlist using which we can select the designation of the Employee. Lets add a new Property to our initialValues Object with a Name called Designation and initialize it to empty. Now with in our Form, add a new Field, assign the name as designation and to this field add a new attribute called as as and set the value as select. Add the respective options we want. For example, lets say we want to have Software Engineer, Senior Software Engineer and Lead as Designations.

Save these changes, navigate to the browser. Now we can see the dropdownlist available for us. Fill the form, click on the button. We can see the designation is added to our JSOn object as well.

Now lets say we want to disable the submit button if the form data is invalid. Formik Component has several Properties and we have used few properties like initialValues, validationSchema and onSubmit. Formik has another property called as isValid. IsValid Returns true if there are no errors  or if the errors Object is empty. And returns false if otherwise.

But in order to access any of the property from the Formik Component, we have to make a change. With in Formik Component, we will write an arrow function and properties of this formic component will be passed as a parameter to this function and this function will have our UI Code. Lets move all of our Form Code into this function.  Now to the button, add a new attribute called disabled and pass the isValid property. Now save these changes, navigate to the browser. We can see that button gets disabled when there are validation errors.

import React from 'react';

import ReactDOM from 'react-dom';

import { useFormik, Formik, Form, Field, ErrorMessage } from 'formik';

import * as yup from 'yup';



const EmployeeComponent =()=> {

  return (

    <Formik initialValues= {{

      Id: '',

      Name: '',

      Location: '',

      Salary:'',

      EmailId:'',

      Designation:''

    }} validationSchema={yup.object({

      Name:yup.string().max(20,'Name should not exceed 20 Characters').

      required('Please Enter Employee Name'),

      Location: yup.string()

        .required('Please Enter Employee Location'),

      EmailId: yup.string()

        .email('Invalid email address')

        .required('Please Enter Email Id')

    })} onSubmit= {values => {

      alert(JSON.stringify(values));

    }}>

      {props=>(

        <div>

    <h2>Enter Employee Details...</h2>

    <Form>

      <p>

          <label htmlFor="Id">Employee ID </label>

          <Field name="Id" type="text"></Field>

      </p>

      <p>

          <label htmlFor="Name">Employee Name </label>

          <Field name="Name" type="text"></Field>

          <ErrorMessage name="Name"></ErrorMessage>

      </p>

      <p>

          <label htmlFor="Location">Employee Location </label>

          <Field name="Location" type="text"></Field>

          <ErrorMessage name="Location"></ErrorMessage>

      </p>

      <p>

          <label htmlFor="Salary">Employee Salary </label>

          <Field name="Salary" type="text"></Field>

      </p>

      <p>

          <label htmlFor="EmailId">Employee Email ID </label>

          <Field name="EmailId" type="text"></Field>

          <ErrorMessage name="EmailId"></ErrorMessage>

      </p>

      <p>

        <label>Employee Designation : 

        <Field name="Designation" as="select">

  <option value="red">Software Engineer</option>

  <option value="green">Senior Software Engineer</option>

  <option value="blue">Lead</option>

</Field>

        </label>
      </p>
      <button type="submit" disabled={props.isValid==false}>Submit</button>

    </Form>

    </div>

      )}

    </Formik>
  );
}

const element=<EmployeeComponent></EmployeeComponent>

ReactDOM.render(element,document.getElementById("root"));

Video Reference





© 2020 Pragimtech. All Rights Reserved.