FormGen ANDP >= 8.2 – Customizing
More freedom – without major effort: In version >= 8.2, ANDP establishes a clear separation between the core and customer-specific code. This allows you to adapt forms, interfaces, and workflows precisely to your business processes while remaining compatible with future releases.
Core Functions at a Glance
-
Customizable Elements: Register new or replaced form controls via
ElementDefinitions.tsxandElementTypes.tsx. -
Lifecycle Hooks: Implement own logic before/after submit, validation, or page changes.
-
Configurable Buttons: UX-optimized navigation without modifying the core system.
-
Dynamic Overlays: Centrally control loading, error, or info dialogs.
-
Modular Screens: Interchangeably register payment, summary, or success screens.
-
Update Safety: The core remains unchanged and update-compatible.
Getting Started in Three Steps
-
Prepare folder
packages/feature-formgen/src/custom/Place all customer-specific files in this structure. -
Implement component or hook Example:
custom/elements/FancyDate.tsx. -
Add mapping Add keys in the corresponding
*Types.tsxfiles — immediately usable without core changes.
Detailed sections on Elements, Hooks, Buttons, Overlays, and Screens follow below.
FormGen Customizing - (ANDP >= 8.2)
ANDP 8.2 allows you to overwrite existing elements or create completely new types that are selectable in FormGrid.
The files can be found under packages/feature-formgen/src/custom/.
1. Central Files
| File | Purpose |
|---|---|
|
Exports all React-Native elements |
|
Mapping Data-/ActaNova-Type → Component |
2. Example Mapping (Excerpt)
export const elementTypes = {
boolean: Elements.BooleanElement,
string: Elements.InputElement,
number: Elements.InputElement,
datetime: Elements.DateTimeElement,
// custom type:
fancydate: Elements.FancyDatePickerElement,
};
3. Create New Element
-
Implement component
FancyDatePickerElement.tsx. -
Export in
ElementDefinitions.tsx. -
Map the new key in
ElementTypes.tsx. -
Add
"type": "fancydate"in FormGrid.
4. Best Practices
-
Implement methods
.validate&.getSummaryValue. -
No long `await`s in the render path.
-
I18n keys for all visible texts.
Lifecycle Hooks
The file custom/HooksUtils.tsx provides 14 asynchronous hooks to inject business logic before or after central actions — without changing the core.
1. Hook Matrix
| Hook | Timing | Important Parameters | Typical Use Cases |
|---|---|---|---|
|
Directly before submit |
|
Extra validation, Data enrichment, Captcha check |
|
After successful submit |
(same as above) |
Audit trail, Email sending, Redirect |
Page Change (Within Form) |
|||
|
Before page |
|
Saving, Analytics event |
|
After page |
(same as above) |
Scroll reset, Set focus |
|
Before page - |
(same as above) |
Caching, Show warnings |
|
After page - |
(same as above) |
i.a. Analytics |
Page Change (FormFlow) |
|||
|
Before flow page |
|
Feature flags, Tracking |
|
After flow page |
(same as above) |
i.a. Scroll reset |
|
Before flow page - |
|
Confirmation "Really go back?" |
|
After flow page - |
(same as above) |
Analytics event |
Validation |
|||
|
Before validation run |
|
Load external rules |
|
After validation |
(same as above) |
Error logging, Success banner |
Form Init |
|||
|
Before loading form |
|
Pre-filling values, Session check |
|
After loading form |
|
Welcome overlay, Analytics |
2. Implementation Template
export async function preSubmitForm(
formid, data, formState, uiState, updateState, restService
) {
// 1 | Validation
if (restService.captchaValidation(formState, data) != true) {
throw new Error('Please solve Captcha!');
}
// 3 | UI Update (Show spinner)
uiState.loading = true;
updateState(StatesToUpdateEnum.UI);
}
3. Best Practices
-
All hook functions are
async→ returnPromise<void>. -
throwaborts the flow in a controlled manner. -
console.log()only for debugging.
Buttons
All form buttons can be replaced or extended with custom variants.
1. Central Files
| File | Purpose |
|---|---|
|
Exports of custom button components |
|
Mapping Key → Component |
2. Register New Button
-
Create component
MyNextPageButton.tsx. -
Export in
ButtonComponentDefinitions.tsx. -
Map in
ButtonComponentsTypes.tsx. -
Use in Flow under
buttonDefinition.
Overlays
From ANDP 8.2 onwards, overlays can be flexibly extended or replaced.
1. Central Files and their Tasks
| File | Purpose |
|---|---|
|
Exports of all overlay components |
|
Enum + Mapping |
|
API for showing / hiding |
1.1 custom/OverlayDefinition.tsx
Task: Exports all individually created overlay components in a central place. Procedure: Every new overlay component you implement must be imported and exported here to be available throughout the project.
1.2 custom/OverlayTypes.ts
Contains two essential parts:
1. OverlayTypeEnum: An enumeration of all overlay names.
2. overlayTypes: A mapping (Record<OverlayTypeEnum, React.ComponentType<any>>) linking the Enum value to the React Native component.
export const overlayTypes = {
[OverlayTypeEnum.FULL_SCREEN_LOADING]: Overlay.FullScreenOverlay,
// ... further mappings
};
2. Standard Overlay: DefaultOverlay.tsx
All "Standard Overlays" build upon the DefaultOverlay component.
-
Header Area:
title,closeAble,onClose. -
Body Area:
contentMessages,contentElementNodes,buttonList,buttonObjects. -
Footer Area:
footerMessages.
Example:
return (
<DefaultOverlay
{...props}
title={t('form_OverlayErrorTitle')}
contentMessages={[t('form_OverlayErrorContent')]}
footerMessages={[
t('form_error_overlay__first_line'),
t('form_error_overlay__second_line'),
]}
onClose={extraProps.onClose}
closeAble={extraProps.closeAble}
/>
);
3. Overlay Control: OverlayUtils.tsx
Three central methods are available:
-
setOverlay: Shows the specified overlay.-
Example:
overlayUtils.setOverlay( uiState, formState, OverlayTypeEnum.FULL_SCREEN_LOADING, updateState, {loadingText: IOverlayFullScreenTextEnum.FileUpload} );
-
-
hideOverlay: Hides the currently displayed overlay.
4. Procedure for Adding or Replacing Overlays
4.1 Create New Overlay Type
-
Create Component: Create a React Native component and export it in
custom/OverlayDefinition.tsx. -
Extend OverlayTypeEnum: Add a new entry in
custom/OverlayTypes.ts. -
Add Mapping: Add the mapping in
overlayTypes. -
Show Programmatically: Call
overlayUtils.setOverlay(…).
4.2 Replace Existing Overlay
-
Identify the desired Enum entry in
custom/OverlayTypes.ts. -
Replace the referenced React Native component in
overlayTypeswith your new one (ensure compatible props).
5. Specifics and Tips
-
Feature Flag "feature_debug": If active, debug sections are added to the overlay.
-
Additional Parameters: Use the
additionalobject insetOverlay(…)for context-specific data. -
Rerender Issues: In forms, use a
useEffecthook to ensure the overlay is displayed after state changes.
Screens
Register custom screens (Payment, Summary V2 …) and use them in FormFlow.
1. Central Files
| File | Purpose |
|---|---|
|
Exports of all screens |
|
Mapping Key → Component |
2. Create New Screen
-
Create component
SummaryScreenV2.tsx. -
Export in
ScreenDefinitions.tsx. -
Map in
ScreenComponents.tsx. -
Set
"reactClass": "SummaryScreenV2"informFlowStepsJSON.
Customizing Elements - Versions < 8.2
(Legacy Support for Gentics ANDP Version 2.3 to 2.5)
Allows customizing existing elements and PreSubmit & PostSubmit hooks.
Step 1 to 3: Setup
-
Navigate to
~/YOUR_PROJECT/portal/formgen/src/custom. -
Relevant files:
ElementDefinitions.tsx(names/paths) andElementTypes.tsx(ActaNova type assignment).
Step 4: Implementation Example
import React from "react";
import * as interfaces from "../utils/Interfaces";
import { IFormComponentAttributes } from "../utils/Interfaces";
import { TFunction } from "i18next";
function CustomElementExample(props: IFormComponentAttributes) {
return (
<div>
<h1>ExampleElement</h1>
</div>
);
};
CustomElementExample.validate = function (
state: interfaces.IState,
jsonpath: string,
id: string,
updateErrorMessages: boolean,
t: TFunction,
formGridOptions?: interfaces.IFormGridOptions
) {
return true;
};
CustomElementExample.getSummaryValue = function (
state: interfaces.IState,
jsonpath: string,
id: string,
t: TFunction,
formGridOptions?: interfaces.IFormGridOptions
) {
return "summary value";
};
export default CustomElementExample;
Step 5 & 6: Assignment
-
Export in
ElementDefinitions.tsx:export { default as CustomElementExample } from '../custom/CustomElementExample'; -
Assign the type in
ElementTypes.tsx.
Hooks (Legacy)
PreSubmit Hook
Executes logic before the form is sent. Throw an exception to stop the submit process.
export async function preSubmitForm(
formid: any,
data: FormData,
state: IState,
callback: (res: Response) => void,
error: any
): Promise {
// Insert async logic here
}
PostSubmit Hook
Executes logic after successful transmission (e.g., triggering workflows).
export async function postSubmitForm(
formid: any,
data: FormData,
state: IState,
callback: (res: Response) => void,
error: any
): Promise {
// Insert async logic here
}
