ANDP Formular Generator - Custom Code Implementation 

FormGen ANDP 8.2 – Customizing

Mehr Spielraum – ohne großen Aufwand: In Version 8.2 stellt ANDP eine klare Trennung zwischen Core und kunden­individuellem Code her. So passen Sie Formulare, Oberflächen und Abläufe exakt an Ihre Geschäftsprozesse an, bleiben aber weiterhin kompatibel zu künftigen Releases.

Kern­funktionen auf einen Blick

  • Anpassbare Elemente – neue oder ersetzte Form-Controls über ElementDefinitions.tsx und ElementTypes.tsx
  • Lifecycle-Hooks – eigene Logik vor / nach Submit, Validierung, Seiten­wechsel
  • Konfigurierbare Buttons – UX-optimierte Navigation ohne Änderung des Kern­systems
  • Dynamische Overlays – Lade-, Fehler- oder Info-Dialoge zentral steuern
  • Modulare Screens – Payment-, Summary- oder Success-Screens austauschbar registrieren
  • Updatesicherheit – der Core bleibt unverändert und updatefähig

Einstieg in drei Schritten

  1. Ordner packages/feature-formgen/src/custom/vorbereiten 
    Platzieren Sie alle kunden­spezifischen Dateien in dieser Struktur.
  2. Komponente oder Hook implementieren
    Beispiel: custom/elements/FancyDate.tsx
  3. Mapping ergänzen
    Schlüssel in den entsprechenden *Types.tsx-Dateien hinzufügen — sofort einsetzbar, ohne Core-Änderungen.

Im Anschluss finden Sie detaillierte Abschnitte zu Elementen, Hooks, Buttons, Overlays und Screens.


FormGen Customizing - ANDP-8.2

ANDP 8.2 ermöglicht es, bestehende Elemente zu überschreiben oder vollständig neue Typen anzulegen, die in FormGrid auswählbar sind.

Die Dateien können unter packages/feature-formgen/src/custom/ gefunden werden.

1 | Zentrale Dateien

DateiZweck
custom/ElementDefinitions.tsxExportiert alle React-Native-Elemente
custom/ElementTypes.tsxMapping Daten-/ActaNova-Typ → Komponente

2 | Beispiel-Mapping (Auszug)

export const elementTypes = {
  boolean:  Elements.BooleanElement,
  string:   Elements.InputElement,
  number:   Elements.InputElement,
  datetime: Elements.DateTimeElement,
  // eigener Typ:
  fancydate: Elements.FancyDatePickerElement,
};

3 | Neues Element anlegen

  1. Komponente FancyDatePickerElement.tsx implementieren.
  2. In ElementDefinitions.tsx exportieren.
  3. In ElementTypes.tsx den neuen Key mappen.
  4. Im FormGrid  "type": "fancydate" hinzufügen. (Siehe: FormGrid Custom Element)

4 | Best Practices

  • Methoden .validate & .getSummaryValue implementieren.
  • Keine langen awaits im Render-Pfad.
  • I18n-Keys für alle sichtbaren Texte.


Lifecycle-Hooks

Die Datei custom/HooksUtils.tsx stellt 14 asynchrone Hooks bereit, mit denen Sie Geschäftslogik vor oder nach zentralen Aktionen einschleusen können – ohne den Core zu verändern.

1 | Hook-Matrix

Hook Zeitpunkt Wichtige Parameter Typische Einsatzzwecke
preSubmitForm direkt vor Submit formid, data, formState, uiState, updateState, restService Extra-Validierung, Daten-Enrichment, Captcha-Check
postSubmitForm nach erfolgreichem Submit wie oben Audit-Trail, E-Mail-Versand, Redirect
Seitenwechsel (Innerhalb vom Formular
preHandleNextFormPageChange vor Seite + formState, uiState, restService, updateState, mockForm?
Speichern, Analytics-Event
postHandleNextFormPageChange nach Seite + wie oben Scroll-Reset, Fokus setzen
preHandlePreviousFormPageChange vor Seite – wie oben Caching, Warnungen anzeigen
postHandlePreviousFormPageChange nach Seite – wie oben u. a. Analytics
Seitenwechsel (FormFlow)
preHandleNextFormFlowPageChange vor Flow-Seite + uiState, updateState Feature-Flags, Tracking
postHandleFormFlowPageChange nach Flow-Seite + wie oben u. a. Scroll-Reset
preHandlePreviousFormFlowPageChange vor Flow-Seite – uiState, updateState Bestätigung „Wirklich zurück?“
postHandlePreviousFormFlowPageChange nach Flow-Seite – wie oben Analytics-Event
Validierung
preLoadValidation vor Validierungslauf restService, formState, uiState, updateState, afterValidation, jsonPath, mockForm
externe Regeln laden
postLoadValidation nach Validierung wie oben Error-Logging, Success-Banner
Formular-Init
preInitForm vor Laden des Formulars data?, newFormId? Vorbelegen von Werten, Session-Check
postInitForm nach Laden des Formulars wie oben Willkommens-Overlay, Analytics

2 | Implementations-Template




export async function preSubmitForm(
formid, data, formState, uiState, updateState, restService
) {
// 1 | Validierung
if (restService.captchaValidation(formState, data) != true) {
throw new Error('Bitte Captcha lösen!');
}

// 3 | UI-Update (Spinner zeigen)
uiState.loading = true;
updateState(StatesToUpdateEnum.UI);
}


3 | Best Practices

  • Alle Hook-Funktionen sind async → geben Promise<void> zurück.
  • throw bricht den Flow kontrolliert ab.
  • console.log() nur für Debug.


Buttons

Sämtliche Formular-Buttons können durch eigene Varianten ersetzt oder erweitert werden.

1 | Zentrale Dateien

DateiZweck
custom/ButtonComponentDefinitions.tsxExporte eigener Button-Komponenten
custom/ButtonComponentsTypes.tsxMapping Key → Komponente

2 | Neuen Button registrieren

  1. Komponente MyNextPageButton.tsx anlegen.
  2. In ButtonComponentDefinitions.tsx exportieren.
  3. In ButtonComponentsTypes.tsx mappen.
  4. Im Flow unter buttonDefinition nutzen. (Siehe: Formular Flow)


Overlays

Ab ANDP 8.2 lassen sich Overlays flexibel erweitern oder ersetzen.

Einführung

Ab Version ANDP-8.2 können Overlays deutlich flexibler und dynamischer gestaltet werden. Im Folgenden finden Sie eine strukturierte Übersicht aller relevanten Dateien, Konfigurationspunkte und Methoden, die zur Erstellung, Anpassung und Steuerung von Overlays genutzt werden.

1. Zentrale Dateien und deren Aufgaben

DateiZweck
custom/OverlayDefinition.tsxExporte aller Overlay-Komponenten
custom/OverlayTypes.tsEnum + Mapping OverlayTypeEnum → Komponente
services/OverlayUtils.tsxAPI zum An- / Ausblenden

1.1 custom/OverlayDefinition.tsx

Aufgabe: Exportiert alle individuell erstellten Overlay-Komponenten an einer zentralen Stelle.

Vorgehen: Jede neue Overlay-Komponente, die Sie implementieren, muss hier importiert und exportiert werden, damit sie im gesamten Projekt verfügbar ist.

1.2 custom/OverlayTypes.ts

Diese Datei enthält zwei wesentliche Bestandteile:

  • OverlayTypeEnum
    • Eine Aufzählung aller Overlay-Namen (Enum-Typ).
    • Jeder Eintrag steht für einen spezifischen Overlay-Typ, den man später programmgesteuert anzeigen kann.
  • overlayTypes
    • Ein Mapping (Record<OverlayTypeEnum, React.ComponentType<any>>), das jeden Wert aus OverlayTypeEnum mit der entsprechenden React-Native-Komponente verknüpft, die in OverlayDefinition.tsx exportiert wird.
    • Beispiel aus Ihren Vorgaben (verkürzt dargestellt, um nur das Prinzip zu zeigen):
    export const overlayTypes = {
      [OverlayTypeEnum.FULL_SCREEN_LOADING]: Overlay.FullScreenOverlay,
      // … weitere Zuordnungen
    };

Hinweis: Möchten Sie beispielsweise das Overlay vom Typ FULL_SCREEN_LOADING nutzen, stellen Sie sicher, dass dieser Schlüssel in overlayTypes auf genau den von Ihnen in OverlayDefinition.tsx exportierten React-Native-Komponenten-Namen zeigt.

2. Standard-Overlay: DefaultOverlay.tsx

Alle „Standard-Overlays“ bauen auf der Komponente DefaultOverlay auf. Hier finden Sie eine generische Struktur, um Header, Body und Footer eines Overlays zu konfigurieren.

2.1 Aufbau von DefaultOverlay

Header-Bereich

  • title (String): Titel, der oben im Overlay angezeigt wird.
  • closeAble (Boolean, Standard: false): Legt fest, ob ein Schließen-Button (X) eingeblendet wird.
  • onClose (Function): Callback, das ausgeführt wird, wenn das Overlay geschlossen wird.

Body-Bereich

  • contentMessages: Liste von Textzeilen, die nacheinander im Body gerendert werden.
  • contentElementNodes: Eigene React-Native-Komponenten, die anstelle reiner Texte eingefügt werden können.
  • buttonList (Liste von Objekten mit { text: string; onPress: () => void }): Definition von Buttons (Beschriftung und zugehörige Klick-Handler).
  • buttonObjects (React-Element-Array): Individuell erstellte Button-Komponenten mit eigenem Styling/Verhalten.

Footer-Bereich

  • footerMessages (String[]): Liste von Textzeilen, die im unteren Bereich des Overlays angezeigt werden.

2.2 Beispiel eines Standard-Overlays (aus Ihrer Vorlage)

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-Steuerung: OverlayUtils.tsx

Um Overlays anzuzeigen oder zu verbergen, stehen Ihnen drei zentrale Methoden zur Verfügung. Diese sind die einzigen „offiziellen“ Schnittstellen, um Overlays systemweit ein- oder auszublenden.

setOverlay

Zeigt das jeweils angegebene Overlay an. Es gibt keine weitere Debug-Logik, das heißt: Es wird genau das Overlay genutzt, das als Typ übergeben wurde.

Wichtig:

  • uiState und formState sind interne State-Objekte, über die der Overlay-Status gesteuert wird.
  • updateState ist eine Funktion, die den notwendigen State-Update triggert, damit das Overlay tatsächlich gerendert wird.
  • Das optionale additional-Objekt dient dazu, overlay-spezifische Parameter wie Texte oder Icons zu übergeben.
  • Wenn das Feature-Flag "feature_debug" aktiviert ist, dann werden bei einem E die Debugsections "Stack Trace, Message, Requestbody" usw zum jeweiligen Overlay hinzugefügt, wenn sie vorhanden sind. 

Beispiel


overlayUtils.setOverlay( uiState, formState, OverlayTypeEnum.FULL_SCREEN_LOADING, updateState, {loadingText: IOverlayFullScreenTextEnum.FileUpload} );


hideOverlay

Blendet das aktuell angezeigte Overlay wieder aus.

Hinweis: Alle drei Methoden führen das Rerendering erst aus, wenn updateState (oder entsprechender State-Update) ausgeführt wurde. Achten Sie also darauf, die übergebene Funktion korrekt aufzurufen, damit die UI synchronisiert wird.

4. Vorgehen beim Hinzufügen oder Ersetzen von Overlays

4.1 Neuen Overlay-Typen anlegen

Komponente erstellen

  • Legen Sie eine neue React-Native-Komponente an.
  • Wenn Sie das Standard-Layout von DefaultOverlay nutzen, reichen die Props title, contentMessages, footerMessages, buttonList usw. aus. Andernfalls können Sie komplett eigene JSX-Strukturen implementieren.
  • Wichtig: Exportieren Sie die Komponente in custom/OverlayDefinition.tsx.

OverlayTypeEnum erweitern

Ergänzen Sie in custom/OverlayTypes.ts einen neuen Eintrag für Ihren Overlay-Namen.

Beispiel (nur Enum-Teil):

export enum OverlayTypeEnum {
  // … bestehende Einträge
  MEIN_NEUER_OVERLAY = 'MEIN_NEUER_OVERLAY',
}

Mapping in overlayTypes ergänzen

Fügen Sie in demselben File unter overlayTypes einen neuen Eintrag hinzu, der Ihren neuen Enum-Wert auf die soeben exportierte Komponente verweist.

Beispiel (nur Mapping-Teil):

[OverlayTypeEnum.MEIN_NEUER_OVERLAY]: Overlays.MeinNeuerOverlayComponent,

Overlay programmatisch anzeigen

Rufen Sie overlayUtils.setOverlay(...) auf, um Ihr neues Overlay anzuzeigen. Verzichten Sie auf eigene Mechanismen zum Einblenden; nutzen Sie ausschließlich die Methoden in OverlayUtils.tsx, damit die State-Logik korrekt funktioniert.

Beispiel (generisch):

setOverlay(
  uiState,
  formState,
  OverlayTypeEnum.<IHR_OVERLAY_TYP>,
  updateState,
  { /* zusätzliche Parameter */ }
);

4.2 Vorhandenes Overlay ersetzen

Overlay-Typ identifizieren

Suchen Sie in custom/OverlayTypes.ts nach dem gewünschten Enum-Eintrag.

Komponente austauschen

Ersetzen Sie in overlayTypes die referenzierte React-Native-Komponente durch Ihre neue. Achten Sie darauf, dass Ihre neue Komponente dieselben Props (z. B. onClose, contentMessages, footerMessages) unterstützt, um Kompatibilität mit bereits existierendem Code sicherzustellen.

5. Besonderheiten und Tipps

Feature-Flag „feature_debug“ beachten

Wenn das Feature aktiv ist, dann werden mehrere Debugsections zum eigentlichen Overlay hinzugefügt, welche die aufgetauchten Fehler klarer darstellt. 

Zusätzliche Parameter („additional“) nutzen

Für viele Overlays müssen kontextspezifische Daten (z. B. unterschiedliche Texte, Icons oder Timer) übergeben werden. Tun Sie dies immer über das additional-Objekt in setOverlay(...). Dokumentieren Sie klar, welche Schlüssel Ihr Overlay erwartet (z. B. loadingText).

Rerender-Problematik in Formularen

Gerade in Formularen („Formgen“) kommt es häufig dazu, dass State-Updates von außen Ihren Overlay-Aufruf überschreiben. Wenn ein Overlay nicht zuverlässig angezeigt wird, sollten Sie in der betreffenden Screen-Komponente (z. B. in RenderScreen.tsx oder dem jeweiligen Container) einen useEffect-Hook nutzen, um das Overlay nach einem bestimmten State-Change einzublenden. So stellen Sie sicher, dass Ihr Aufruf nicht unmittelbar wieder überschrieben wird.

6. Zusammenfassung

  • Neues Overlay erstellen
    • Komponente in custom/OverlayDefinition.tsx exportieren.
    • OverlayTypeEnum um einen neuen Wert erweitern.
    • overlayTypes so anpassen, dass der neue Enum-Wert auf Ihre Komponente verweist.
  • Bestehendes Overlay ersetzen
    • In overlayTypes den Eintrag auf Ihre neue Komponente ändern (unter Beibehaltung derselben Props).
  • Overlay anzeigen/verbergen
    • Anzeigen:  overlayUtils.setOverlay(...)
    • Verbergen: overlayUtils.hideOverlay(...).
  • State-Management & Rerendering
    • Overlays werden nur gerendert, wenn updateState ausgeführt wird.
    • Bei unzuverlässigen Overlay-Anzeigen (z. B. in Formularscreens) empfiehlt sich ein useEffect-Hook, um Overlay-Aufrufe nach relevanten State-Änderungen sicherzustellen.


Screens

Eigene Screens (Payment, Summary V2 …) registrieren und im FormFlow nutzen.

1 | Zentrale Dateien

DateiZweck
custom/ScreenDefinitions.tsxExporte aller Screens
custom/ScreenComponents.tsxMapping Key → Komponente

2 | Neuen Screen anlegen

  1. Komponente SummaryScreenV2.tsx erstellen.
  2. In ScreenDefinitions.tsx exportieren.
  3. In ScreenComponents.tsx mappen.
  4. Im formFlowSteps JSON "reactClass": "SummaryScreenV2" setzen. (Siehe: Formular Flow)



Customizing von Elementen - Versionen < 8.2

Mit Gentics ANDP Version 2.3 (bis ANDP-2.5), haben Sie jetzt die Möglichkeit, bestehende Elemente, den PreSubmit- &  PostSubmit Hook anzupassen. Diese Erweiterungen bieten Ihnen umfassende Kontrolle und Flexibilität bei der Gestaltung und Verarbeitung Ihrer Formulare.

Sie können bestehende Formularelemente anpassen oder vollständig neue Elemente erstellen, um den speziellen Anforderungen Ihrer Anwendungen gerecht zu werden. Dies umfasst die Anpassung des Layouts, der Validierungslogik und der Datenverarbeitung. Dadurch können Sie sicherstellen, dass Ihre Formulare exakt so funktionieren, wie es Ihre Geschäftsprozesse erfordern.

Maßgeschneiderte Lösungen: Custom-Elemente statt Standard-Elemente

Das Ersetzen bestehender Elemente durch Custom-Elemente ermöglicht es Ihnen, spezifische Funktionen, individuelle Validierungen, maßgeschneiderte Designs und angepasste Geschäftslogiken zu integrieren. So stellen Sie sicher, dass Ihre Anwendung nicht nur funktional, sondern auch optimal auf Ihre Anforderungen abgestimmt ist. Custom-Elemente bieten die Flexibilität, komplexe Anforderungen präzise umzusetzen und eine nahtlose Integration in Ihre bestehenden Prozesse zu gewährleisten.

In den folgenden Schritten zeigen wir Ihnen, wie einfach es ist, bestehende Elemente durch Custom-Elemente zu ersetzen und Ihre Anwendung optimal an Ihre Bedürfnisse anzupassen.

Schritt 1

Öffnen Sie Ihr ANDP-Projekt und navigieren Sie zum Verzeichnis ~/DEIN_PROJEKT/portal/formgen/src/

Schritt 2

Sie sollten die folgenden drei Ordner vorfinden:

  • custom: Dieser Abschnitt ist speziell für Sie vorgesehen, um Ihren eigenen Code einzufügen.
  • elements: Dieser Bereich enthält alle vorhandenen Elemente. Bitte nehmen Sie keine Änderungen an den bestehenden Elementen vor. Es steht Ihnen jedoch frei, eigene Elemente hinzuzufügen, wir empfehlen jedoch, eigene Element in dem Verzeichnis custom hinzuzufügen.
  • utils: In diesem Bereich sollten keine Änderungen vorgenommen werden.
Öffnen Sie das folgende Verzeichnis ~/DEIN_PROJEKT/portal/formgen/src/custom.

Schritt 3 

Im Verzeichnis „custom“ sollten die folgenden Dateien vorhanden sein:
  • ElementDefinitions.tsx: In dieser Datei sind alle Elemente mit ihren TypeScript-Namen sowie den jeweiligen Pfaden definiert.
  • ElementTypes.tsx: In dieser Datei werden die Elemente aus ElementDefinitions.tsx den entsprechenden ActaNova/FormGrid-Elementtypen zugewiesen.
  • HooksUtils.tsx: In dieser Datei befinden sich der Pre-Submit- & Post-Submit-Hook.

Für die Implementierung von Custom-Elementen werden ausschließlich die Dateien ElementDefinitions.tsx und ElementTypes.tsx benötigt. Erstellen Sie anschließend Ihr Custom-Element im Verzeichnis custom. In diesem Beispiel nenne ich die Datei CustomElementExample.tsx.

Schritt 4 

In diesem Schritt zeige ich Ihnen, wie die Klasse CustomElementExample aufgebaut sein sollte und welche Methoden Ihnen zur Verfügung stehen.
So sieht eine Beispiel-Implementierung für ein Custom-Element aus:



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;



 Folgende Methoden müssen immer implementiert werden:

  • .validate: Diese Funktion wird bei jeder Validierung des Formulars aufgerufen. Hier können Sie eine speziell auf das Custom-Element abgestimmte Validierung implementieren.
  • .getSummaryValue

Mithilfe des CustomElementExample können Sie nun Ihr eigenes maßgeschneidertes Element implementieren und optimal an Ihren Bedürfnissen anpassen.

Schritt 5


Nachdem Sie Ihr Custom-Element implementiert haben, können Sie es einem vorhandenen ActaNova/FormGrid-Typ zuweisen. 

Dazu definieren Sie zunächst den Pfad und die Bezeichnung des Elements in ElementDefinitions:



export { default as CustomElementExample } from '../custom/CustomElementExample';


Schritt 6


Im letzten Schritt ordnen Sie im ElementTypes.tsx den entsprechenden ElementType Ihrem neuen Custom-Element zu. Wenn alle Schritte korrekt ausgeführt wurden, sollte Ihr neues Custom-Element nach dem Build beim Start eines Formulars, das den angepassten ActaNova-Typ verwendet, angezeigt werden.

Hooks

Mit Pre-Submit und Post-Submit Hooks können Sie die Kontrolle über den Ablauf des Formularprozesses erweitern und spezifische Geschäftslogiken implementieren. Durch den Einsatz von Pre- und Post-Submit Hooks lassen sich Ihre Formulare nahtlos in bestehende Geschäftsprozesse integrieren und individuell an die Anforderungen Ihres Unternehmens anpassen.

Die folgenden Parameter könnten für dich nützlich sein:
  • formid: Die ID des Formulars
  • data: Die Daten der einzelnen ActaNova-Elemente
  • state: Eine Sammlung von Daten und Methoden, mit denen du außerhalb der HooksUtils.tsx mit der FormGen-App kommunizieren kannst.

PreSubmit Hook

Der PreSubmit-Hook ermöglicht es Ihnen, benutzerdefinierte Logik auszuführen, bevor ein Formular abgesendet wird. Hier können Sie zusätzliche Validierungen implementieren, Daten vor der Übermittlung transformieren oder andere spezifische Aktionen durchführen, die vor dem Senden des Formulars an den Server notwendig sind.

Innerhalb der Methode PreSubmitHook kannst du eigenen Code einfügen, der vor dem Absenden des Formulars ausgeführt wird. Wenn du den gesamten Vorgang bereits in der PreSubmitHook stoppen möchtest, kannst du eine benutzerdefinierte Ausnahme (Exception) auslösen. Andernfalls wird der Submit-Vorgang immer durchgeführt.



export async function preSubmitForm(
formid: any,
data: FormData,
state: IState,
callback: (res: Response) => void,
error: any
): Promise {
// Füge hier asynchrone Logik ein, die vor dem eigentlichen Funktionsaufruf ausgeführt werden soll
}


PostSubmit Hook

Der PostSubmit Hook ergänzt die Anpassungsmöglichkeiten, indem er es Ihnen ermöglicht, benutzerdefinierte Logik nach der erfolgreichen Übermittlung eines Formulars auszuführen. Mit diesem Hook können Sie Aktionen auslösen, die nach dem Speichern oder Verarbeiten der Formulardaten notwendig sind, wie z.B. das Triggern von Workflows oder die Ausführung zusätzlicher Datenverarbeitungsprozesse.



export async function postSubmitForm(
formid: any,
data: FormData,
state: IState,
callback: (res: Response) => void,
error: any
): Promise {
// Füge hier asynchrone Logik ein, die nach dem eigentlichen Funktionsaufruf ausgeführt werden soll
}



Durch diese neuen Anpassungsmöglichkeiten in Gentics FormGen können Sie sicherstellen, dass Ihre Formulare optimal an Ihre Geschäftsprozesse angepasst sind und genau die gewünschten Ergebnisse liefern. Nutzen Sie diese Features, um Ihre Formulare auf das nächste Level zu bringen.