From be2660a9fb19e3e45e265ab28455ade85d530702 Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Mon, 8 Jul 2024 15:53:48 +0200 Subject: [PATCH] :sparkles: [open-formulieren/open-forms#4431] Field validation for AddressNL the following components can now be validated using regex: * postcode * house number * street name * city --- .../ComponentConfiguration.stories.tsx | 34 +++ src/registry/addressNL/edit.tsx | 203 +++++++++++++++++- 2 files changed, 236 insertions(+), 1 deletion(-) diff --git a/src/components/ComponentConfiguration.stories.tsx b/src/components/ComponentConfiguration.stories.tsx index c30a33cc..00db91c9 100644 --- a/src/components/ComponentConfiguration.stories.tsx +++ b/src/components/ComponentConfiguration.stories.tsx @@ -2222,6 +2222,40 @@ export const AddressNL: Story = { }, deriveAddress: false, layout: 'singleColumn', + components: { + postcode: { + validate: {pattern: '1015 [a-zA-Z]{2}'}, + translatedErrors: { + nl: { + pattern: 'Must be at 1015 XX', + }, + }, + }, + houseNumber: { + validate: {pattern: '(0|[1-9][0-9]?|100)'}, + translatedErrors: { + nl: { + pattern: 'Must be between 1 and 100', + }, + }, + }, + streetName: { + validate: {pattern: '(Keizersgracht|Prinsengracht)'}, + translatedErrors: { + nl: { + pattern: 'Must be at Keizersgracht or Prinsengracht', + }, + }, + }, + city: { + validate: {pattern: 'Amsterdam'}, + translatedErrors: { + nl: { + pattern: 'Must be in Amsterdam', + }, + }, + }, + }, }, builderInfo: { title: 'Address Field', diff --git a/src/registry/addressNL/edit.tsx b/src/registry/addressNL/edit.tsx index 3951c84f..a8f89f36 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({ @@ -128,6 +189,146 @@ 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', + })} + /> + + + {/* House number field validation */} + + } + tooltip={intl.formatMessage({ + description: 'Tooltip house number field validation panel', + defaultMessage: 'Validation for the house number field', + })} + collapsible + initialCollapsed + > + + } + tooltip={intl.formatMessage({ + description: "Tooltip for 'validate.pattern' builder field", + defaultMessage: + 'The regular expression pattern test that the house number field value must pass before the form can be submitted.', + })} + placeholder={intl.formatMessage({ + description: "Placeholder for 'validate.pattern' builder field", + defaultMessage: 'Regular expression for house number', + })} + /> + + + {/* Street name field validation */} + + } + tooltip={intl.formatMessage({ + description: 'Tooltip street name field validation panel', + defaultMessage: 'Validation for the street name field', + })} + collapsible + initialCollapsed + > + + } + tooltip={intl.formatMessage({ + description: "Tooltip for 'validate.pattern' builder field", + defaultMessage: + 'The regular expression pattern test that the street name field value must pass before the form can be submitted.', + })} + placeholder={intl.formatMessage({ + description: "Placeholder for 'validate.pattern' builder field", + defaultMessage: 'Regular expression for street name', + })} + /> + + + {/* 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 */}