'ReactJS Formik Validation
I have some troubles with my validations.
I have the following validation schema:
private accountDetailsSchema = Yup.object().shape({
ebillingMail: Yup.string()
.max(255, this.props.t("errors.common.errorTooLong255"))
.matches(regex.email, this.props.t("errors.common.invalidEmail"))
.matches(/^(?!\s+$)/g, this.props.t("errors.common.errorNoWhitespace")),
dunningMail: Yup.string()
.max(255, this.props.t("errors.common.errorTooLong255"))
.matches(regex.email, this.props.t("errors.common.invalidEmail"))
.matches(/^(?!\s+$)/g, this.props.t("errors.common.errorNoWhitespace")),
estatementMail: Yup.string()
.max(255, this.props.t("errors.common.errorTooLong255"))
.matches(regex.email, this.props.t("errors.common.invalidEmail"))
.matches(/^(?!\s+$)/g, this.props.t("errors.common.errorNoWhitespace")),
});
and I use it this way in Formik:
<Formik
initialValues={{
ebillingMail: this.state.account.ebillingMail,
dunningMail: this.state.account.edunningMail,
estatementMail: this.state.account.estatementMail,
}}
validationSchema={this.accountDetailsSchema}
validateOnChange={true}
validateOnBlur={true}
onSubmit={() => {
console.log("state", this.state);
}}
>
{({ touched, errors, setFieldTouched}) => (
<div id="eBillingDunning">
{this.getReadOnlyHistoryFields(
touched,
errors,
setFieldTouched
)}
</div>
</Formik>
the method getReadOnlyHistoryFields is the following:
protected getReadOnlyHistoryFields = (
touched,
errors,
setFieldTouched
): JSX.Element[] => {
const fields: FieldElement[] = [
//dunning new
{
label: "p-float-label",
id: "account-dunning",
name: "dunning",
translation: "entityAccounts.properties.dunning",
transformTo: "YesNo",
},
//ebilling new
{
label: "p-float-label",
id: "account-ebilling",
name: "ebilling",
translation: "entityAccounts.properties.ebilling",
transformTo: "YesNo",
},
//edunning new
{
label: "p-float-label",
id: "account-edunning",
name: "edunning",
translation: "entityAccounts.properties.edunning",
transformTo: "YesNo",
},
//estatement mail new
{
label: "p-float-label",
id: "account-estatementMail",
name: "estatementMail",
translation: "entityAccounts.properties.estatementMail",
},
//ebilling mail new
{
label: "p-float-label",
id: "account-ebillingMail",
name: "ebillingMail",
translation: "entityAccounts.properties.ebillingMail",
},
//edunning mail new
{
label: "p-float-label",
id: "account-edunningMail",
name: "edunningMail",
translation: "entityAccounts.properties.edunningMail",
},
//dunning last requested at
{
label: "p-float-label",
id: "account-dunningLastRequestedAt",
name: "dunningLastRequestedAt",
translation: "entityAccounts.properties.lastDunningRequestDate",
},
//dunning last requested by
{
label: "p-float-label",
id: "account-dunningLastRequestedBy",
name: "dunningLastRequestedBy",
translation: "entityAccounts.properties.lastDunningId",
},
];
return fields.map((field: FieldElement, i: number) => {
return (
<span
className={field.label}
style={{ background: "none", border: "none" }}
>
{field.name === "dunning" ||
field.name === "ebilling" ||
field.name === "edunning" ? (
<Dropdown
id="dunning-filter"
optionLabel="label"
optionValue="value"
options={filterOptions[field.name]}
className="account-details-field small"
value={this.state.account[field.name]}
placeholder={this.transformValue(field.name, field.transformTo)}
onChange={(e: any) => this.changeField(field, e, true)}
/>
) : (
<InputText
disabled={!editableFields.includes(field.name) && true}
id={field.id}
onBlur={(e: any) => {
setFieldTouched(field.name, false);
console.log("errors after blur", errors[field.name])
this.clicked(field, e, errors[field.name]);
}}
onFocus={()=>{setFieldTouched(field.name)}}
onChange={(e: any) => {
console.log("change field", errors[field.name])
this.changeField(field, e)
}}
className={`account-details-field small ${
touched[field.name] == true && errors[field.name] ? "is-invalid" : ""
}`}
value={
!editableFields.includes(field.name)
? this.transformValue(field.name, field.transformTo)
: this.state.account[field.name]
}
tooltip={
this.transformValue(field.name, field.transformTo).length > 20
? this.transformValue(field.name, field.transformTo)
: ""
}
name={field.name}
/>
)}
<label className="small" htmlFor={field.name}>
{this.props.t(`${field.translation}`)}
{editableFields.includes(field.name) && (
<i id="editIcon" className="pi pi-pencil"></i>
)}
</label>
{errors[field.name] && touched[field.name] && (
<small className="p-error p-d-block">{errors[field.name]}</small>
)}
</span>
);
});
};
When the email is invalid, it shows the error message. But it doesnt work in the following occasions:
- When I have an invalid email and change it to valid, it is not saved, when I click outside of the field.
- When I have a valid email and change it to invalid, it doesn't show the error message.
Could you give me some ideas how can I fix this? I will be very grateful.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
