'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