From 78c9ade6a369ff03b8413303969bf55c7bed4cd4 Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Mon, 29 Jul 2024 15:56:58 +0200 Subject: [PATCH] :sparkles: [open-formulieren/open-forms#4420] Field validation for AddressNL the following components can now be validated using regex: * postcode * city --- .../ComponentConfiguration.stories.tsx | 10 ++ src/components/builder/validate/i18n.tsx | 6 +- src/registry/addressNL/edit.tsx | 146 +++++++++++++++++- 3 files changed, 158 insertions(+), 4 deletions(-) diff --git a/src/components/ComponentConfiguration.stories.tsx b/src/components/ComponentConfiguration.stories.tsx index c30a33cc..8c815f28 100644 --- a/src/components/ComponentConfiguration.stories.tsx +++ b/src/components/ComponentConfiguration.stories.tsx @@ -2222,6 +2222,16 @@ export const AddressNL: Story = { }, deriveAddress: false, layout: 'singleColumn', + ofComponents: { + postcode: { + validate: {pattern: '1015 [a-zA-Z]{2}'}, + translatedErrors: {}, + }, + city: { + validate: {pattern: 'Amsterdam'}, + translatedErrors: {}, + }, + }, }, builderInfo: { title: 'Address Field', diff --git a/src/components/builder/validate/i18n.tsx b/src/components/builder/validate/i18n.tsx index c5dcf442..d5606822 100644 --- a/src/components/builder/validate/i18n.tsx +++ b/src/components/builder/validate/i18n.tsx @@ -9,12 +9,12 @@ import {BuilderContext} from '@/context'; import {DataMap, Panel, Tab, TabList, TabPanel, Tabs, TextField} from '../../formio'; export function useManageValidatorsTranslations( - keys: PossibleValidatorErrorKeys[] + keys: PossibleValidatorErrorKeys[], + field: string = 'translatedErrors' ): void { const {supportedLanguageCodes} = useContext(BuilderContext); - const [{value}, , {setValue}] = useField('translatedErrors'); + const [{value}, , {setValue}] = useField(field); - // set any missing translations useEffect(() => { const newValue = value ? {...value} diff --git a/src/registry/addressNL/edit.tsx b/src/registry/addressNL/edit.tsx index 3951c84f..62319f38 100644 --- a/src/registry/addressNL/edit.tsx +++ b/src/registry/addressNL/edit.tsx @@ -1,4 +1,6 @@ import {AddressNLComponentSchema} from '@open-formulieren/types'; +import {TextField} from 'components/formio'; +import {useContext} from 'react'; import {FormattedMessage, useIntl} from 'react-intl'; import { @@ -19,12 +21,71 @@ import { } from '@/components/builder'; import {LABELS} from '@/components/builder/messages'; import {Checkbox} from '@/components/formio'; -import {TabList, TabPanel, Tabs} from '@/components/formio'; +import {DataMap, Panel, Tab, TabList, TabPanel, Tabs} from '@/components/formio'; import {Select} from '@/components/formio'; +import {BuilderContext} from '@/context'; import {useErrorChecker} from '@/utils/errors'; import {EditFormDefinition} from '../types'; +export interface SubcomponentValidationProps { + component: string; + label: React.ReactNode; + tooltip: string; + placeholder: string; +} + +const SubcomponentValidation: React.FC = ({ + component, + label, + tooltip, + placeholder, +}) => { + const {supportedLanguageCodes} = useContext(BuilderContext); + return ( + <> + + + + {supportedLanguageCodes.map(code => ( + {code.toUpperCase()} + ))} + + + {supportedLanguageCodes.map(code => ( + + + } + valueComponent={ + + } + /> + } + /> + + ))} + + + ); +}; + const DeriveAddress = () => { const intl = useIntl(); const tooltip = intl.formatMessage({ @@ -81,6 +142,9 @@ const EditForm: EditFormDefinition = () => { const [isKeyManuallySetRef, generatedKey] = useDeriveComponentKey(); const {hasAnyError} = useErrorChecker(); Validate.useManageValidatorsTranslations(['required']); + Validate.useManageValidatorsTranslations(['pattern'], `ofComponents.postcode.translatedErrors`); + Validate.useManageValidatorsTranslations(['pattern'], `ofComponents.city.translatedErrors`); + return ( @@ -128,6 +192,76 @@ const EditForm: EditFormDefinition = () => { + + {/* Postcode field validation */} + + } + tooltip={intl.formatMessage({ + description: 'Tooltip postcode field validation panel', + defaultMessage: 'Validation for the postcode field', + })} + collapsible + initialCollapsed + > + + } + tooltip={intl.formatMessage({ + description: "Tooltip for 'validate.pattern' builder field", + defaultMessage: + 'The regular expression pattern test that the postcode field value must pass before the form can be submitted.', + })} + placeholder={intl.formatMessage({ + description: "Placeholder for 'validate.pattern' builder field", + defaultMessage: 'Regular expression for postcode', + })} + /> + + + {/* City field validation */} + + } + tooltip={intl.formatMessage({ + description: 'Tooltip city field validation panel', + defaultMessage: 'Validation for the city field', + })} + collapsible + initialCollapsed + > + + } + tooltip={intl.formatMessage({ + description: "Tooltip for 'validate.pattern' builder field", + defaultMessage: + 'The regular expression pattern test that the city field value must pass before the form can be submitted.', + })} + placeholder={intl.formatMessage({ + description: "Placeholder for 'validate.pattern' builder field", + defaultMessage: 'Regular expression for city', + })} + /> + {/* Registration tab */} @@ -192,6 +326,16 @@ EditForm.defaultValues = { registration: { attribute: '', }, + ofComponents: { + postcode: { + validate: {pattern: ''}, + translatedErrors: {}, + }, + city: { + validate: {pattern: ''}, + translatedErrors: {}, + }, + }, }; export default EditForm;