PrimeReact components can be easily used/integrated with Formik. In this example, a register panel is simulated using Formik.
import React, { useEffect, useState } from 'react';
import { useFormik } from 'formik';
import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button';
import { Dropdown } from 'primereact/dropdown';
import { Calendar } from 'primereact/calendar';
import { Password } from 'primereact/password';
import { Checkbox } from 'primereact/checkbox';
import { Dialog } from 'primereact/dialog';
import { Divider } from 'primereact/divider';
import { classNames } from 'primereact/utils';
import { CountryService } from '../service/CountryService';
import './FormDemo.css';
export const FormikFormDemo = () => {
const [countries, setCountries] = useState([]);
const [showMessage, setShowMessage] = useState(false);
const [formData, setFormData] = useState({});
const countryservice = new CountryService();
useEffect(() => {
countryservice.getCountries().then(data => setCountries(data));
}, []); // eslint-disable-line react-hooks/exhaustive-deps
const formik = useFormik({
initialValues: {
name: '',
email: '',
password: '',
date: null,
country: null,
accept: false
},
validate: (data) => {
let errors = {};
if (!data.name) {
errors.name = 'Name is required.';
}
if (!data.email) {
errors.email = 'Email is required.';
}
else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(data.email)) {
errors.email = 'Invalid email address. E.g. [email protected]';
}
if (!data.password) {
errors.password = 'Password is required.';
}
if (!data.accept) {
errors.accept = 'You need to agree to the terms and conditions.';
}
return errors;
},
onSubmit: (data) => {
setFormData(data);
setShowMessage(true);
formik.resetForm();
}
});
const isFormFieldValid = (name) => !!(formik.touched[name] && formik.errors[name]);
const getFormErrorMessage = (name) => {
return isFormFieldValid(name) && <small className="p-error">{formik.errors[name]}</small>;
};
const dialogFooter = <div className="flex justify-content-center"><Button label="OK" className="p-button-text" autoFocus onClick={() => setShowMessage(false)} /></div>;
const passwordHeader = <h6>Pick a password</h6>;
const passwordFooter = (
<React.Fragment>
<Divider />
<p className="mt-2">Suggestions</p>
<ul className="pl-2 ml-2 mt-0" style={{ lineHeight: '1.5' }}>
<li>At least one lowercase</li>
<li>At least one uppercase</li>
<li>At least one numeric</li>
<li>Minimum 8 characters</li>
</ul>
</React.Fragment>
);
return (
<div className="form-demo">
<Dialog visible={showMessage} onHide={() => setShowMessage(false)} position="top" footer={dialogFooter} showHeader={false} breakpoints={{ '960px': '80vw' }} style={{ width: '30vw' }}>
<div className="flex align-items-center flex-column pt-6 px-3">
<i className="pi pi-check-circle" style={{ fontSize: '5rem', color: 'var(--green-500)' }}></i>
<h5>Registration Successful!</h5>
<p style={{ lineHeight: 1.5, textIndent: '1rem' }}>
Your account is registered under name <b>{formData.name}</b> ; it'll be valid next 30 days without activation. Please check <b>{formData.email}</b> for activation instructions.
</p>
</div>
</Dialog>
<div className="flex justify-content-center">
<div className="card">
<h5 className="text-center">Register</h5>
<form onSubmit={formik.handleSubmit} className="p-fluid">
<div className="field">
<span className="p-float-label">
<InputText id="name" name="name" value={formik.values.name} onChange={formik.handleChange} autoFocus className={classNames({ 'p-invalid': isFormFieldValid('name') })} />
<label htmlFor="name" className={classNames({ 'p-error': isFormFieldValid('name') })}>Name*</label>
</span>
{getFormErrorMessage('name')}
</div>
<div className="field">
<span className="p-float-label p-input-icon-right">
<i className="pi pi-envelope" />
<InputText id="email" name="email" value={formik.values.email} onChange={formik.handleChange} className={classNames({ 'p-invalid': isFormFieldValid('email') })} />
<label htmlFor="email" className={classNames({ 'p-error': isFormFieldValid('email') })}>Email*</label>
</span>
{getFormErrorMessage('email')}
</div>
<div className="field">
<span className="p-float-label">
<Password id="password" name="password" value={formik.values.password} onChange={formik.handleChange} toggleMask
className={classNames({ 'p-invalid': isFormFieldValid('password') })} header={passwordHeader} footer={passwordFooter} />
<label htmlFor="password" className={classNames({ 'p-error': isFormFieldValid('password') })}>Password*</label>
</span>
{getFormErrorMessage('password')}
</div>
<div className="field">
<span className="p-float-label">
<Calendar id="date" name="date" value={formik.values.date} onChange={formik.handleChange} dateFormat="dd/mm/yy" mask="99/99/9999" showIcon />
<label htmlFor="date">Birthday</label>
</span>
</div>
<div className="field">
<span className="p-float-label">
<Dropdown id="country" name="country" value={formik.values.country} onChange={formik.handleChange} options={countries} optionLabel="name" />
<label htmlFor="country">Country</label>
</span>
</div>
<div className="field-checkbox">
<Checkbox inputId="accept" name="accept" checked={formik.values.accept} onChange={formik.handleChange} className={classNames({ 'p-invalid': isFormFieldValid('accept') })} />
<label htmlFor="accept" className={classNames({ 'p-error': isFormFieldValid('accept') })}>I agree to the terms and conditions*</label>
</div>
<Button type="submit" label="Submit" className="mt-2" />
</form>
</div>
</div>
</div>
);
}
/* FormDemo.css */
.form-demo .card {
min-width: 450px;
}
.form-demo .card form {
margin-top: 2rem;
}
.form-demo .card .field {
margin-bottom: 1.5rem;
}
@media screen and (max-width: 960px) {
.form-demo .card {
width: 80%;
}
}
@media screen and (max-width: 640px) {
.form-demo .card {
width: 100%;
min-width: 0;
}
}
Built-in component themes created by the PrimeReact Theme Designer.
Premium themes are only available exclusively for PrimeReact Theme Designer subscribers and therefore not included in PrimeReact core.
Beautifully crafted premium create-react-app application templates by the PrimeTek design team.