Form validation
More often than not form fields require validation. We can add validation in formik with Yup.
#
Basic exampleimport { useIntl } from 'react-intl';import * as yup from 'yup';
export const usePaymentMethodValidationSchema = () => { const intl = useIntl();
const validationSchema = yup.object().shape({ Name: yup .string() .required(intl.formatMessage({ id: 'generic.error.message.required' })) .min(2) .max(255), Code: yup .string() .required(intl.formatMessage({ id: 'generic.error.message.required' })) .min(2) .max(255), });
return validationSchema;};
#
Nested objectsconst validationSchema = yup.object().shape({ ProductID: yup.number().required(intl.formatMessage({ id: 'generic.error.message.required' })), Quantity: yup .number() .integer() .positive() .required(intl.formatMessage({ id: 'generic.error.message.required' })), UnitPrice: yup .number() .required(intl.formatMessage({ id: 'generic.error.message.required' })) .positive(intl.formatMessage({ id: 'generic.error.message.number.positive' })) .min(0, (val) => intl.formatMessage({ id: 'generic.error.message.number.min' }, { min: val.min }), ),});
#
Arraysconst validationSchema = Yup.object().shape({ tiers: Yup.array() .of( Yup.object().shape({ ... }), ) .required(),
#
Specific valueconst validationSchema = yup.object().shape({ name: yup.string().required( intl.formatMessage({ id: 'edit-discount.general-info.ou-details-dialog.tabs.create-ou-set.name.required', }), ), includedOrganiationUnitSets: yup.array().min( 1, intl.formatMessage({ id: 'edit-discount.general-info.ou-details-dialog.tabs.create-ou-set.included.required', }), ), type: yup.number().oneOf([OrganizationUnitSetType.AdHoc, OrganizationUnitSetType.Custom]),});
#
Numbersconst validationSchema = Yup.object().shape({ DiscountPercentage: Yup.number() .required(intl.formatMessage({ id: 'generic.error.message.required' })) .positive(intl.formatMessage({ id: 'generic.error.message.number.positive' })) .max(100, ({ max }) => intl.formatMessage({ id: 'generic.error.message.number.max' }, { max })) .min(0, ({ min }) => intl.formatMessage({ id: 'generic.error.message.number.min' }, { min })),});
#
Conditional validation based on other fieldsconst validationSchema = Yup.object().shape({ percentageTiers: Yup.array().when( 'discountType', (discountType: SlidingDiscountType, schema: any) => discountType === SlidingDiscountType.OrderTieredDiscountPercentage ? schema.required().min(1) : schema.nullable(), ), amountTiers: Yup.array().when('discountType', (discountType: SlidingDiscountType, schema: any) => discountType === SlidingDiscountType.OrderTieredDiscountAmount ? schema.required().min(1) : schema.nullable(), ), isProductSetValid: Yup.bool().when( 'discountFocus', (discountFocus: SlidingDiscountFocus, schema: any) => discountFocus === SlidingDiscountFocus.ProductQuantity ? schema.oneOf([true]) : schema.oneOf([true, false]), ),});
#
Cyclic validationSometimes there are fields that are co-dependent with regards to validation
const validationSchema = yup.object().shape( { Name: yup.string().required( intl.formatMessage({ id: 'price-lists.details.general-info.name.required', }), ), CurrencyID: yup.string().required( intl.formatMessage({ id: 'price-lists.details.general-info.currency-id.required', }), ), IncludingVat: yup.boolean().required(), IsActive: yup.boolean().required(), BackendID: yup.string().when('BackendSystemID', (backendSystemID: string, schema: any) => backendSystemID ? schema.required( intl.formatMessage({ id: 'price-lists.details.general-info.backend-id.required', }), ) : schema.nullable(), ), BackendSystemID: yup.string().when('BackendID', (backendId: string, schema: any) => backendId ? schema.required( intl.formatMessage({ id: 'price-lists.details.general-info.backend-system-id.required', }), ) : schema.nullable(), ), }, [['BackendID', 'BackendSystemID']],);