PrimeReact components can be easily used/integrated with React Hook Form. In this example, a register panel is simulated using React Hook Form.
import React, { useEffect, useState } from 'react';
import { useForm, Controller } from 'react-hook-form';
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 ReactHookFormDemo = () => {
const [countries, setCountries] = useState([]);
const [showMessage, setShowMessage] = useState(false);
const [formData, setFormData] = useState({});
const countryservice = new CountryService();
const defaultValues = {
name: '',
email: '',
password: '',
date: null,
country: null,
accept: false
}
useEffect(() => {
countryservice.getCountries().then(data => setCountries(data));
}, []); // eslint-disable-line react-hooks/exhaustive-deps
const { control, formState: { errors }, handleSubmit, reset } = useForm({ defaultValues });
const onSubmit = (data) => {
setFormData(data);
setShowMessage(true);
reset();
};
const getFormErrorMessage = (name) => {
return errors[name] && <small className="p-error">{errors[name].message}</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 justify-content-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={handleSubmit(onSubmit)} className="p-fluid">
<div className="field">
<span className="p-float-label">
<Controller name="name" control={control} rules={{ required: 'Name is required.' }} render={({ field, fieldState }) => (
<InputText id={field.name} {...field} autoFocus className={classNames({ 'p-invalid': fieldState.invalid })} />
)} />
<label htmlFor="name" className={classNames({ 'p-error': errors.name })}>Name*</label>
</span>
{getFormErrorMessage('name')}
</div>
<div className="field">
<span className="p-float-label p-input-icon-right">
<i className="pi pi-envelope" />
<Controller name="email" control={control}
rules={{ required: 'Email is required.', pattern: { value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i, message: 'Invalid email address. E.g. [email protected]' }}}
render={({ field, fieldState }) => (
<InputText id={field.name} {...field} className={classNames({ 'p-invalid': fieldState.invalid })} />
)} />
<label htmlFor="email" className={classNames({ 'p-error': !!errors.email })}>Email*</label>
</span>
{getFormErrorMessage('email')}
</div>
<div className="field">
<span className="p-float-label">
<Controller name="password" control={control} rules={{ required: 'Password is required.' }} render={({ field, fieldState }) => (
<Password id={field.name} {...field} toggleMask className={classNames({ 'p-invalid': fieldState.invalid })} header={passwordHeader} footer={passwordFooter} />
)} />
<label htmlFor="password" className={classNames({ 'p-error': errors.password })}>Password*</label>
</span>
{getFormErrorMessage('password')}
</div>
<div className="field">
<span className="p-float-label">
<Controller name="date" control={control} render={({ field }) => (
<Calendar id={field.name} value={field.value} onChange={(e) => field.onChange(e.value)} dateFormat="dd/mm/yy" mask="99/99/9999" showIcon />
)} />
<label htmlFor="date">Birthday</label>
</span>
</div>
<div className="field">
<span className="p-float-label">
<Controller name="country" control={control} render={({ field }) => (
<Dropdown id={field.name} value={field.value} onChange={(e) => field.onChange(e.value)} options={countries} optionLabel="name" />
)} />
<label htmlFor="country">Country</label>
</span>
</div>
<div className="field-checkbox">
<Controller name="accept" control={control} rules={{ required: true }} render={({ field, fieldState }) => (
<Checkbox inputId={field.name} onChange={(e) => field.onChange(e.checked)} checked={field.value} className={classNames({ 'p-invalid': fieldState.invalid })} />
)} />
<label htmlFor="accept" className={classNames({ 'p-error': errors.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.