Basic Usage:

1. Add imports

import { Formik, Form, useField, useFormik } from 'formik';
import * as Yup from 'yup';
import { MySelect, MyTexArea } from "../../components/utilities/FormFields";

2. Follow this format to add the JSX.

<Formik>
  <Form validate="true"></Form>
</Formik>

2.1 Example <Formik>

      <Formik
        enableReinitialize={true}
        initialValues={formValues}
        validationSchema={Yup.object({
          task_type: Yup.string().required('Please select a Task Type'),
          points: Yup.string().required('Please select points for this task'),
          task: Yup.string().required('Please enter the task description'),
        })}
        onSubmit={(postData, { setSubmitting }) => {
          console.log(`LINE 46 postData=`, postData);
          // Do Something....
        }}
      >

3. Example Fields Usage:

Select:

              <MySelect label="Points" name="points" className="form-control mb-3" required="required">
                <option>--Select Points--</option>
                {[...Array(10)].map((e, i) =>
                  <option value={i} key={i}>{i}</option>
                )}
              </MySelect>

 

Textarea:

<MyTexArea label="Task" name="task" placeholder="Write Task" className="form-control" />

 

Advanced:

Use this code to add a component hook to your React application to generate fields in your form with very simple code.

The code in this page included the hook "FormFeidsl.jsx" and TaskForm.jsx as examples on how to use.

Source: /g/xampp8/htdocs/laravel/StudentTodo/StudentTodoV2

  1. install FormIk and Yup
    $ npm install formik yup
  2. Create a new file called  - TaskForm.jsx see the full code below.
  3. Create a new file called  - FormFields.jsx see the full code below.

TaskForm.jsx

import React from 'react';
import { Formik, Form, useField, useFormik } from 'formik';
import * as Yup from 'yup';
import "./TaskForm.css"
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { useParams } from 'react-router';

// FOR NON LOGGED IN
import APIService from '/src/axios/http';
// FOR AUTHENTICATED
import axiosClient from "../../axios/client.js";
import MyModal from "../log/MyModal";
import { useStateContext } from "../../context/ContextProvider.jsx";
import { MySelect, MyTexArea } from "../../components/utilities/FormFields"
// And now we can use these
export function TaskForm() {

  const { task_id } = useParams();


  const [apiErrs, setApiErrs] = useState(null)
  const { modalContent, setModalContent } = useStateContext();
  const [errors, setErrors] = useState([])
  const [formValues, setFormValues] = useState({
    task_type: '',
    points: '',
    task: task_id ? 'Loading....' : '',
  })



  const showErrorMsg = (errorsArr, set) => {
    setErrors(errorsArr);
    if (typeof set.color == "undefined") set.color = 'primary'
    if (typeof set.title == "undefined") set.title = 'Modal Message'
    console.log(`LINE 186 errorsArr=`, errorsArr);
    let HTML = `<ol className="alert alert-${set.color} list-unstyled">`;
    errorsArr.forEach(erroMsg => {
      HTML += `<li className="m-3">${erroMsg}</li>`;
    });
    HTML += `</ol>`;
    // UPDATE THE CONTEXT TO SHOW THE MESSAGES IN THE MODAL
    setModalContent({
      ...modalContent,
      title: set.title,
      color: set.color,
      body: HTML,
      show: true,
      backdrop: 'static'
    });
  }

  const componentSettings = {
    nextRoute: "/NOTNEEDED", // /download/download/:fileSecret
    pageTitle: "Add Log",
    apiRoute: `/tasks`, // submit media files
    initApiRoute: '/NotNeeded' // inital route to validate fileSecret
  };
  document.title = componentSettings.pageTitle;
  const task_type = {
    ab: "yes/no",
    text: "text",
    link: "Link"
  }
  let task_typeArr = [];
  for (let [property, value] of Object.entries(task_type)) {
    task_typeArr.push(property);
  }



  if (task_id) {
    useEffect(() => {

      axiosClient.get(`/tasks/${task_id}`)
        .then(({ data }) => {
          console.log(`LINE 999 data=`, data);
          setFormValues(data);


          // const fields = ['task'];
          //fields.forEach(field => setFieldValue(field, data[field], false));

        })
        .catch(() => {

        })
    }, [])
  }

  return (
    <>
      <h1> Task Form: {task_id && task_id} | <Link to="/tasks" >All</Link></h1>
      {apiErrs && Object.entries(apiErrs).map(([errProp, errValue], index) => { return (<div key={index} className='alert alert-danger' title={errProp}>{errValue}</div>) }
      )}
      <Formik
        enableReinitialize={true}
        initialValues={formValues}
        validationSchema={Yup.object({
          task_type: Yup.string().required('Please select a Task Type'),
          points: Yup.string().required('Please select points for this task'),
          task: Yup.string().required('Please enter the task description'),
        })}
        onSubmit={(postData, { setSubmitting }) => {
          console.log(`LINE 46 postData=`, postData);
          postData.apiRoute = componentSettings.apiRoute;


          // ADD NEW  // EDIT ITEM task_id
          if (task_id) componentSettings.apiRoute = componentSettings.apiRoute + `/${task_id}`;

          axiosClient.put(componentSettings.apiRoute, postData)
            .then(({ res }) => {
              console.log(`LINE 99 =res`, res);

              showErrorMsg([`${task_id ? 'Edited' : 'Added'} successfuly`], { color: 'success', title: "Task Edded Successfully" });
            })
            .catch((err) => {
              console.log(`LINE 56 =err`, err);
              setApiErrs(err.response.data.errors);
            })
          setSubmitting(false);
        }}
      >
        <Form validate="true">
          <div className="row">
            <div className="col">
              <MySelect label="Points" name="points" className="form-control mb-3" required="required">
                <option>--Select Points--</option>
                {[...Array(10)].map((e, i) =>
                  <option value={i} key={i}>{i}</option>
                )}
              </MySelect>
            </div>
            <div className="col">
              <MySelect label="Task Type" name="task_type" className="form-control mb-3" required="required">
                <option>--Select Task Type--</option>
                {Object.entries(task_type).map(([task_name, task_value], index) =>
                  <option value={task_name} key={index}>{task_value}</option>
                )}
              </MySelect>
            </div>
          </div>
          <div className="row">
            <div className="col">
              <MyTexArea
                label="Task"
                name="task"
                placeholder="Write Task"
                className="form-control"
              />
            </div>
          </div>
          <button type="submit" className='btn btn-primary mt-3'>Submit</button>
        </Form>
      </Formik >
      <div><MyModal show={false} /></div>
    </>
  );
};
export default TaskForm

FormFields.jsx