I have a React form created with Formik & Yup and I have a little problem with the submit button.
The error message will be displayed if I try to click on an input field and leave. If an error message is displayed and I click the "Save" button, all the error messages will disappear, instead of showing all my empty inputs.
This is my yup validation schema:
export const refillSchema = object({
date: date().required('Date is required'),
refillType: string().required('Refill type is required'),
kilometers: number().required('Kilometers is required').min(0, 'Kilometers must be at least 0'),
price: number().required('Price is required').min(0, 'Price must be at least 0'),
liters: number().required('Liters is required').min(0, 'Liters must be at least 0'),
kWh: number().required('KWh is required').min(0, 'KWh must be at least 0')
})
And this is my component:
import React from 'react';
import { ChevronLeftIcon } from '@heroicons/react/20/solid';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import { refillInitialValues } from '../../../utils/constants';
import { refillSchema } from '../../../utils/yupSchemas';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
export default function HandleFuelConsumption({ refill, electricVehicle, resetHandleVehicle })
{
return (
<div>
<Formik
initialValues={refill || refillInitialValues}
validationSchema={refillSchema}
onSubmit={(values, { resetForm }) => {
const { date, kilometers, refillType, price, liters, kWh } = values;
console.log(date, kilometers, refillType, price, liters, kWh);
// Handle form submission
// For example, you can make an API call or update the state
resetForm(); // Reset the form after successful submission
}}
>
{({ errors, touched, setFieldValue }) => (
<Form>
<div id="actionsBar" className="p-2 border-b-2">
<div className="flex justify-between">
<div className="flex items-center cursor-pointer text-[#3300FF]" onClick={resetHandleVehicle}>
<ChevronLeftIcon className="w-[25px] h-auto" />
<p>Back</p>
</div>
<button type="submit" className="flex items-center cursor-pointer text-white blue-button hover:opacity-80">
<p>Save</p>
</button>
</div>
</div>
<div className="flex flex-wrap p-2 gap-x-6">
<div>
<label htmlFor="date" className="block text-sm font-medium text-gray-700">
Date
</label>
<Field name="date">
{({ field }) => (
<DatePicker
id="date"
selected={field.value}
onChange={(date) => setFieldValue('date', date)}
className={`${
errors.date && touched.date ? 'border-red-500' : ''
} cursor-default block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-primary focus:outline-none focus:ring-primary-hover sm:text-sm`}
showTimeSelect
dateFormat="yyyy-MM-dd HH:mm:ss"
timeFormat="HH:mm:ss"
/>
)}
</Field>
<ErrorMessage name="date" component="p" className="text-red-500 text-xs italic" />
</div>
<div>
<label htmlFor="kilometers" className="block text-sm font-medium text-gray-700">
Kilometers
</label>
<div className="mt-1">
<Field
id="kilometers"
name="kilometers"
type="number"
min="0"
className={`${
errors.kilometers && touched.kilometers ? 'border-red-500' : ''
} block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-primary focus:outline-none focus:ring-primary-hover sm:text-sm`}
/>
</div>
<ErrorMessage name="kilometers" component="p" className="text-red-500 text-xs italic" />
</div>
<div>
<label htmlFor="refillType" className="block text-sm font-medium text-gray-700">
Refill Type
</label>
<Field
as="select"
id="refillType"
name="refillType"
className={`${
errors.refillType && touched.refillType ? 'border-red-500' : ''
} min-w-[100px] mt-1 block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-primary focus:outline-none focus:ring-primary-hover sm:text-sm`}
>
<option value="Full">Full</option>
<option value="Partial">Partial</option>
</Field>
<ErrorMessage name="refillType" component="p" className="text-red-500 text-xs italic" />
</div>
</div>
<div className="flex flex-wrap p-2 gap-x-6">
<div>
<label htmlFor="price" className="block text-sm font-medium text-gray-700">
Price
</label>
<div className="mt-1">
<Field
id="price"
name="price"
type="number"
min="0"
className={`${
errors.price && touched.price ? 'border-red-500' : ''
} block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-primary focus:outline-none focus:ring-primary-hover sm:text-sm`}
/>
</div>
<ErrorMessage name="price" component="p" className="text-red-500 text-xs italic" />
</div>
{electricVehicle ? (
<div>
<label htmlFor="kWh" className="block text-sm font-medium text-gray-700">
KWh
</label>
<div className="mt-1">
<Field
id="kWh"
name="kWh"
type="number"
min="0"
className={`${
errors.kWh && touched.kWh ? 'border-red-500' : ''
} block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-primary focus:outline-none focus:ring-primary-hover sm:text-sm`}
/>
</div>
<ErrorMessage name="kWh" component="p" className="text-red-500 text-xs italic" />
</div>
) : (
<div>
<label htmlFor="liters" className="block text-sm font-medium text-gray-700">
Liters
</label>
<div className="mt-1">
<Field
id="liters"
name="liters"
type="number"
min="0"
className={`${
errors.liters && touched.liters ? 'border-red-500' : ''
} block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-primary focus:outline-none focus:ring-primary-hover sm:text-sm`}
/>
</div>
<ErrorMessage name="liters" component="p" className="text-red-500 text-xs italic" />
</div>
)}
</div>
</Form>
)}
</Formik>
</div>
);
}