Dynamische Formulare in Angular

Dynamische Formulare in Angular

  • Beitrags-Autor:Timon G
  • Beitrags-Kommentare:0 Kommentare

Im Laufe der Zeit sind die Anforderungen an unsere Formulare und deren Komplexität deutlich angestiegen. Zusätzlich müssen diese Formulare immer wieder neue Geschäftslogiken abbilden. Da wir zuvor jedes Formular „Eingabefeld für Eingabefeld“ zusammenbauten stießen wir schnell an die Grenzen, die Angular mit dem ReactiveFormsModule bietet. Um uns in Zukunft das Leben zu erleichtern und die Entwicklung neuer Formulare deutlich zu erleichtern entwickelten wir eine neue Basis für alle zukünftigen Formulare – Die Dynamic Form.

Formular mit vielen Eingabefeldern

Mit Hilfe von dynamischen Formularen lassen sich Eingabefelder oder auch komplette UI-Komponenten je nach derzeitigem Use-Case ein-oder ausblenden. Durch eine einzige Konfiguration, in der alle möglichen Eingabefelder gelistet sind, muss das Formular Layout nun nicht mehr manuell ins HTML geschrieben werden. Die Dynamic Form kümmert sich darum und verkürzt die Entwicklungszeit gleich mit.

Je nach Dropdown-Auswahl erscheinen neue Felder oder vorher sichtbare Felder verschwinden

Wie funktioniert die Komponente?

Die verantwortliche Dynamic-Form Komponente hat einen relativ Simplen Aufbau. Sie erwartet mehrere Inputs, von denen die formDefinition die wichtigste ist. Diesem Input wird die Definition der kompletten Form, also die Eingabefelder und deren Konfiguration mitgegeben

Auszug aus der Dynamic Form Component

Im ngOnInit der Komponente wird nur das Formular zusammengestellt. Dort werden die Daten aus der formDefinition genommen und für jedes Feld eine neue FormControl registriert.

Erzeugung der FormGroup

Danach werden im afterContentChecked die Komponenten-Platzhalter aktualisiert. Dabei wir über den ComponentFactoryResolver von Angular eine neue Instanz der Komponente erzeugt. Diese wird danach in den entsprechenden View-Container gerendert und je nach Visibilität angezeigt.

Die Komponenten Klassen werden aufgelöst und eine Angular Component Instanz wird erzeugt

Das HTML der Dynamic Form Component sieht folgendermaßen aus:

Für jedes formElement wird ein Platzhalter generiert

Über die .intro-elements und .outro-elements Slots können zusätzliche Layout Elemente am Beginn und Ende der Form angezeigt werden, wie z.B. Überschriften oder ein Submit-Button.

Die Direktive componentPlaceholder in der die Komponenteninstanz gerendert wird enthält eine Referenz auf die ViewContainerRef und den Namen des Platzhalters.

Platzhalter Komponente mit viewContainerRef Referenz

Nutzung der Komponente

Um die Dynamic Form nun einzusetzen muss zuerst eine Form Definition erstellt werden. Als Namenskonvention eignet sich [form-name].definition.ts.

Diese exportiert die Definition als Array von Objekten:

export const myFormDefinition: IhFormDefinition = [
  {
    isFormInput: true,
    isVisible: true,
    elementName: 'my-text-input',
    defaultValue: 'hallo',
    validators: [Validators.required],
    componentClass: MyTextInputComponent,
    componentInputs: {
      textColor: '#000000',
    },
  },
  {
    isFormInput: true,
    isVisible: true,
    elementName: 'my-currency-input',
    defaultValue: '42',
    validators: [Validators.required, MyValidator],
    componentClass: MyCurrencyInputComponent,
    componentInputs: {
      currencySymbol: '€',
    },
  },
  ...etc,
];

Anschließend muss nur noch die Dynamic-Form Komponente im Template referenziert werden:

<dynamic-form
  [formClasses]="'my-form-class'"
  [formDefinition]="myFormDefinition"
  (formDataChanged)="updateFormData($event)"
  (createFormGroup)="setFormGroup($event)"
>
</dynamic-form>

Über den Output formDataChanged kann nun auf Änderungen der Eingaben reagiert werden und zusätzliche Felder ein- oder ausgeblendet werden.

Der Output createFormGroup gibt die zusammengebaute FormGroup zurück, um diese Referenz später im Code zu nutzen.

Schreibe einen Kommentar