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.tsx and ElementTypes.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

  1. Prepare folder packages/feature-formgen/src/custom/ Place all customer-specific files in this structure.

  2. Implement component or hook Example: custom/elements/FancyDate.tsx.

  3. Add mapping Add keys in the corresponding *Types.tsx files — 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

custom/ElementDefinitions.tsx

Exports all React-Native elements

custom/ElementTypes.tsx

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

  1. Implement component FancyDatePickerElement.tsx.

  2. Export in ElementDefinitions.tsx.

  3. Map the new key in ElementTypes.tsx.

  4. 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

preSubmitForm

Directly before submit

formid, data, formState, uiState, updateState, restService

Extra validation, Data enrichment, Captcha check

postSubmitForm

After successful submit

(same as above)

Audit trail, Email sending, Redirect

Page Change (Within Form)

preHandleNextFormPageChange

Before page

formState, uiState, restService, updateState, mockForm?

Saving, Analytics event

postHandleNextFormPageChange

After page

(same as above)

Scroll reset, Set focus

preHandlePreviousFormPageChange

Before page -

(same as above)

Caching, Show warnings

postHandlePreviousFormPageChange

After page -

(same as above)

i.a. Analytics

Page Change (FormFlow)

preHandleNextFormFlowPageChange

Before flow page

uiState, updateState

Feature flags, Tracking

postHandleFormFlowPageChange

After flow page

(same as above)

i.a. Scroll reset

preHandlePreviousFormFlowPageChange

Before flow page -

uiState, updateState

Confirmation "Really go back?"

postHandlePreviousFormFlowPageChange

After flow page -

(same as above)

Analytics event

Validation

preLoadValidation

Before validation run

restService, formState, uiState, updateState, afterValidation, jsonPath, mockForm, updateOnChange

Load external rules

postLoadValidation

After validation

(same as above)

Error logging, Success banner

Form Init

preInitForm

Before loading form

uiState, formState,newFormId?

Pre-filling values, Session check

postInitForm

After loading form

uiState, formState, responseFromInitForm, newFormId?

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 → return Promise<void>.

  • throw aborts 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

custom/ButtonComponentDefinitions.tsx

Exports of custom button components

custom/ButtonComponentsTypes.tsx

Mapping Key → Component

2. Register New Button

  1. Create component MyNextPageButton.tsx.

  2. Export in ButtonComponentDefinitions.tsx.

  3. Map in ButtonComponentsTypes.tsx.

  4. 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

custom/OverlayDefinition.tsx

Exports of all overlay components

custom/OverlayTypes.ts

Enum + Mapping OverlayTypeEnum → Component

services/OverlayUtils.tsx

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:

  1. setOverlay: Shows the specified overlay.

    • Example:

      overlayUtils.setOverlay(
        uiState,
        formState,
        OverlayTypeEnum.FULL_SCREEN_LOADING,
        updateState,
        {loadingText: IOverlayFullScreenTextEnum.FileUpload}
      );
  2. hideOverlay: Hides the currently displayed overlay.

4. Procedure for Adding or Replacing Overlays

4.1 Create New Overlay Type

  1. Create Component: Create a React Native component and export it in custom/OverlayDefinition.tsx.

  2. Extend OverlayTypeEnum: Add a new entry in custom/OverlayTypes.ts.

  3. Add Mapping: Add the mapping in overlayTypes.

  4. Show Programmatically: Call overlayUtils.setOverlay(…​).

4.2 Replace Existing Overlay

  1. Identify the desired Enum entry in custom/OverlayTypes.ts.

  2. Replace the referenced React Native component in overlayTypes with 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 additional object in setOverlay(…​) for context-specific data.

  • Rerender Issues: In forms, use a useEffect hook 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

custom/ScreenDefinitions.tsx

Exports of all screens

custom/ScreenComponents.tsx

Mapping Key → Component

2. Create New Screen

  1. Create component SummaryScreenV2.tsx.

  2. Export in ScreenDefinitions.tsx.

  3. Map in ScreenComponents.tsx.

  4. Set "reactClass": "SummaryScreenV2" in formFlowSteps JSON.

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) and ElementTypes.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

  1. Export in ElementDefinitions.tsx: export { default as CustomElementExample } from '../custom/CustomElementExample';

  2. 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
}