Phoenix LiveView bietet eine moderne Möglichkeit, dynamische und interaktive Webanwendungen mit Elixir zu bauen, ohne viel JavaScript schreiben zu müssen. Besonders spannend wird es bei verschachtelten Formularen, also solchen, die mehrere miteinander verbundene Datensätze in einem Formular bearbeiten. Hierbei ermöglicht LiveView die Bearbeitung von komplexen Datenstrukturen, wie etwa einem Rezept mit integriertem Management von Zutaten und Anleitungen. Doch der klassische Einsatz von verschachtelten Formularen mit <.inputs_for> reicht häufig nicht aus, sobald komplexere Anforderungen wie Sortierbarkeit, dynamisches Hinzufügen oder Entfernen sowie gezielte Interaktionen gefragt sind.
Besonders Entwickler, die über die Standardimplementierung hinausgehen möchten, finden sich oft in einem undurchsichtigen Gebiet wieder. Die Dokumentation bietet zwar eine solide Grundlage mit Funktionen wie cast_assoc/3, die den Umgang mit assoziierten Daten erleichtern, doch weiterführende Beispiele mit erweiterten Funktionen sind rar. Dennoch gibt es einige bewährte Tricks und fortschrittliche Techniken, die den Umgang mit verschachtelten Formularen in Phoenix LiveView deutlich verbessern können. Ein praktisches Beispiel ist die Bearbeitung eines Rezepts, das viele Zutaten (ingredients) enthält und bei dem diese Zutaten nicht nur hinzugefügt oder entfernt, sondern auch sortiert werden können. Die Implementierung nutzt ein besonderes Feature von Ecto, nämlich die Parameter :sort_param und :drop_param, die in der Funktion cast_assoc integriert sind.
So kann man beispielsweise über ein unsichtbares Feld die Reihenfolge der Zutaten steuern oder einzelne Zutaten gezielt aus der Datenstruktur entfernen. Allerdings ergibt sich daraus auch eine Komplexität auf der Frontend-Seite. Denn das Layout des Formulars spielt eine wichtige Rolle für das korrekte Funktionieren der Sortierung und das Hinzufügen neuer Elemente. So ist die Positionierung der Schaltfläche zum Hinzufügen neuer Zutaten entscheidend: Wird diese Schaltfläche an den Anfang der Liste gesetzt, fügt Ecto das neue Element oben hinzu; ist sie hingegen am Ende platziert, erscheint das neue Element darunter. Mit einem kleinen Trick lässt sich diese Verknüpfung aber lösen.
Statt dass die Schaltfläche selbst das Ereignis auslöst, kann sie ein verstecktes Element anstoßen, welches wiederum die Änderung auslöst, wodurch die Reihenfolge kontrolliert und der Button an beliebiger Stelle positioniert werden kann. Ein weiterer wichtiger Aspekt ist die Verwaltung von Zuständen, insbesondere wenn man neben den reinen Formulardaten auch weitere Informationen anzeigen möchte. Beispielsweise ist es sehr hilfreich, die Anzahl der Zutaten separat zu speichern und zu verwalten, anstatt diese kompliziert aus dem Form-Status auszulesen. Damit die Oberfläche immer synchron bleibt, bietet es sich an, in den LiveView-Callback-Funktionen wie handle_event das Zutaten-Count zu aktualisieren und diesen Wert als eigenes Assign zu führen. So wird der Wert an einer zentralen Stelle gepflegt und kann einfach im Template dargestellt werden.
Zudem bietet LiveView durch die Nutzung von "_target" im Event-Handling eine elegante Möglichkeit, kontextspezifische Aktionen auszulösen. So kann etwa eine Schaltfläche zum Löschen aller Zutaten einen eigenen Ereignis-Handler aufrufen, der anhand des speziellen Targets die Aktion erkennt und entsprechend reagiert. Auch ohne eigenes JavaScript können so komplexe Interaktionen realisiert werden, die sonst eine aufwändige Event-Verwaltung erforderlich machen würden. Für Entwickler bedeutet das eine enorme Vereinfachung und einen klareren Code in der LiveView-Komponente. Nicht zuletzt unterstreicht die Verwendung von versteckten Buttons und gezielten JS.
dispatch-Aufrufen die Flexibilität von LiveView. Mit solchen Techniken lässt sich Frontend- und Backend-Logik elegant entkoppeln und die User Experience deutlich verbessern. Der Einsatz von Sortable.js oder anderen Client-basierten Bibliotheken lässt sich nahtlos mit LiveView kombinieren, indem Drag-and-Drop-Operationen als Sortiervorgänge an den Server gemeldet und über die Ecto-Changseets verarbeitet werden. Dabei zeigt das gezeigte Beispiel aus der Praxis des Coox-Projekts, wie man auch komplexe Formularstrukturen mit verschachtelten eingebetteten Datensätzen effektiv bearbeiten kann.
Ein abschließender wichtiger Hinweis betrifft die Stabilität und Wartbarkeit solcher komplexen LiveView-Module. Es empfiehlt sich, alle erweiterten Logiken klar zu strukturieren und getrennt zu testen, um unerwartete Nebeneffekte zu vermeiden. Auch die Dokumentation im Code ist essentiell, da verschachtelte Formulare mit dynamischen Elementen rasch zu schwer nachvollziehbaren Zuständen führen können. Zusammengefasst erweitern die beschriebenen Tricks den Umgang mit verschachtelten Formularen in Phoenix LiveView deutlich. Sie ermöglichen es, benutzerfreundlichere, flexiblere und reaktionsschnellere Formulare zu gestalten, ohne auf umfangreiches eigenes JavaScript zurückgreifen zu müssen.
Die Kombination aus Ecto-Features, LiveView-Events und DOM-Manipulation über JS.dispatch öffnet den Weg für komplexe Anwendungen und macht Phoenix LiveView zu einem starken Werkzeug für moderne Webentwicklung mit Elixir.