Dynamische Formulare für List/Tree Einträge in 7.0

Ich würde gerne das im Webinar angesprochene Beispiel umsetzten, dass basierend auf der Wahl des Typs eines Listeneintrages, ein anderes Formular für diesen Eintrag angezeigt wird.
Im SymconTest Modul habe ich dazu noch kein Beispiel gefunden, gibt es dafür irgendwo schon eines?

Wie reagiere ich auf die Werte von den Parameter, um das Formular anzupassen (also wenn in form PHP-code übergeben wird) ? Erfolgt das so wie bei den Aktionen, dass die Werte der Parameter dann in $_IPS[NAMES_DES_PARAMETERS] bereitstehen?
Wie aktualisiert man das Formular, wenn der Wert des Typs geändert wird?

So, Schritt für Schritt

  • Ein Beispiel dafür findest du in SymconTest und zwar hier: https://github.com/symcon/SymconTest/tree/master/ListDynamicEditFormTest
  • Das ausgeführte PHP-Skript zum Auswerten des Edit-Formulars funktioniert genau wie onClick vom Button etc., du kannst also im Skript auf die Variable $NameDerListe zugreifen und via $NameDerListe[‚spaltenName‘] auf die einzelnen gespeicherten Werte zugreifen
  • Das Formular sollte (auch wenn ich das zugegebenerweise noch nicht getestet habe) ganz regulär via Dynamik geändert werden können, also $this->UpdateFormField(‚NameDerSpalte‘, ‚Parameter‘, $NeuerWert)

Ich bin gespannt auf dein Feedback!

Ich habe das mal mit folgendem Formular getestet. Wie es scheint, wird die Variable $List zwar gesetzt, sie ist aber leer ( im Feld List dump steht: null).
Die Werte werden aber korrekt in der Property gespeichert und über den Button „Show List“ angezeigt.

{
    "elements": [
        {
            "caption": "List with dynamic Form",
            "type": "List",
            "name": "List",
            "add": true,
            "delete": true,
            "rowCount": 5,
            "columns": [
                {
                    "caption": "Type",
                    "name": "Type",
                    "width": "500px",
                    "edit": {
                        "type": "Select",
                        "options": [
                            { "caption": "Variable", "value": 0 },
                            { "caption": "Value", "value": 1 }
                        ]
                    },
                    "add": 0
                }
            ],
            "values": [
            ],
            "form": [
                "$form = [];",
                
                "$form[] = [",
                "   'type'=> 'Select',",
                "   'name'=> 'Type',",
                "   'caption'=> 'Type',",
                "   'options'=> [",
                "       ['caption' => 'Variable', 'value'=> 0 ],",
                "       ['caption' => 'Value', 'value' => 1 ]",
                "   ]", 
                "];", 

                "if (isset($List['Type']) && $List['Type'] == 0 ) {",
                "   $form[] = [",
                "      'type'=> 'SelectVariable',",
                "      'name'=> 'VariableID',",
                "      'caption'=> 'VariableID'",
                "   ];",
                "}",

                "   $form[] = [",
                "      'type'=> 'NumberSpinner',",
                "      'name'=> 'Value',",
                "      'caption'=> 'Value'",
                "   ];",

                "if (isset($List)) {",
                "   $form[] = [",
                "      'type'=> 'ValidationTextBox',",
                "      'caption'=> 'List dump',",
                "      'value' => json_encode($List)",
                "   ];",
                "}",

                "return $form;"
            ]
        },
        {
            "type": "Button",
            "caption": "Show List",
            "onClick": "echo IPS_GetProperty($id, 'List');"
        }
    ],
    "actions": [],
    "status": []
}

Ich schaue mir das nachher mal an. Das sieht auf den ersten Blick auf jeden Fall von deiner Seite her korrekt aus.

Edit:
So, ich habe mir das nochmal angeschaut. Tatsächlich bezieht sich der Aufruf aktuell noch auf die aktuell ausgewählte Zeile, welche sich beim Klick auf „Bearbeiten“ nicht ändert. Für den aktuellen Test müsstest du also einfach die Zeile auswählen und dann bearbeiten. Fix dazu kommt in der nächsten Version. Dann wird auch angepasst, dass falls keine Zeile ausgewählt ist (beispielsweise beim Hinzufügen einer Zeile) du auf die „add“-Werte der Liste zugreifst und nicht alles explodiert :slight_smile: .

1 „Gefällt mir“

Mit der neuen 7.0 von gestern Abend funktioniert es nun!

1 „Gefällt mir“

Beim Ausprobieren der neuen Möglichkeiten ist mir aufgefallen, dass ich eigentlich ein andere Feature für meinen Anwendungsfall benötigen würde:

Anwendungsfall: Basierend auf der Auswahl eines Typs sollen im Listen-Formular verschiedene Felder dargestellt werden.
Hier meine Beispiel-Implementierung: GitHub - roastedelectrons/ConfigurationFormTest

Für das Listen-Fomular ergeben sich nun zwei unterschiedliche Fälle:

  1. Neue Zeile wird hinzugefügt:
    In diesem Fall lässt sich die Dynamik direkt mittels ‚onChange‘ und UpdateFormField realisieren (z.B. durch Ändern des visible Parameters). Das funktionierte ja bisher auch schon.

  2. Bearbeitung einer bestehende Zeile:
    In diesem Fall gab es bislang das Problem, dass das Formular statisch war und somit nicht die gespeicherten Werte (z.B. des Typs) bei der Darstellung berücksichtigt wurden. Zusätzlich gab es das Problem, dass wenn man eine Zeile bearbeitet hat und dabei UpdateFormField ausgeführt wurde, dieses geänderte Formular auch bei der Bearbeitung einer anderen Zeile verwendet wurde.
    Mit der neuen Möglichkeit PHP Code im Form zu verwenden, kann man nun das Formular basierend auf den gespeicherten Werten korrekt gestalten.

Beim Testen ist mir aber aufgefallen, dass das programmieren der Forms mittels PHP-Code der als String geschrieben werden muss, sehr fehleranfällig ist. Muss man in diesem String mit PHP-Code noch einen weiteren String mit PHP-Code unterbringen (wie beim onChange) wird es schon kritisch (aber noch handhabbar, wenn man die Anführungszeichen richtig escaped). Bei einer Verschachtelten Liste (also eine weitere Liste in einer Zeile einer Liste), die ihrerseits eine dynamisches PHP-Formular hat, scheint mir dies schon fast unmöglich fehlerfrei umzusetzen.

Lange Rede kurzer Sinn:
Eigentlich benötige ich für diesen Anwendungsfall keinen PHP-Code in Formularen (auch wenn es schön ist das zu haben), sondern es müsste eigentlich nur das onChange-Event (oder ein neues onLoad-Event) auch aufgerufen werden, wenn das Listen-Formular geladen wird. Damit würde das Formular auch beim Öffnen gespeicherter Zeilen über UpdateFormField gleich korrekt geladen werden.