Dokumentation
PopupButton
Benötigt: Symcon >= 5.0
Erstellt einen Button, welcher durch einen Klick ein Popup öffnet, welches weitere Formularfelder enthält.

Allgemeine Parameter
| Parameter | Beschreibung |
|---|---|
| caption | Sichtbare Beschriftung des Buttons |
| download (optional) | (default: "") Ist dieser Parameter nicht leer und beinhaltet die Ausgabe des onClick-Skriptes eine Data-URL, so wird die Rückgabe als Textdatei mit dem Namen das download-Parameters heruntergeladen. (ab Symcon 7.0) |
| enabled (optional) | (default: true) Bei true kann der Button verwendet werden, ansonsten wird er deaktiviert dargestellt. Dieser Parameter hat keine Auswirkung auf ein möglicherweise geöffnetes Popup (ab Symcon 5.2) |
| link (optional) | (default: false) Ist dieser Parameter true, dann wird die Ausgabe des onClick-Skriptes als Link geöffnet. Ist er false, so wird die Ausgabe als Dialog im Konfigurationsformular angezeigt. (ab Symcon 6.0) |
| name (optional) | Name des PopupButtons |
| onClick (optional) | (default: "") Skript, welches bei einem Klick auf den Button ausgeführt wird. Sofern das Skript aus mehreren Zeilen besteht, können die einzelnen Zeilen auch als Array übergeben werden (Arrays werden ab Version 6.0 unterstützt). Es hat die gleichen Eigenschaften wie onClick des Button (ab Symcon 5.3) |
| popup | Definition des zu öffnenden Popups (Parameter sind ab Symcon 6.1 änderbar durch Verknüpfung der Paramternamen, beispielsweise popup.closeCaption) |
| type | PopupButton |
| visible (optional) | (default: true) Bei true ist der Button sichtbar, ansonsten ist er unsichtbar. Dieser Parameter hat keine Auswirkung auf ein möglicherweise geöffnetes Popup (ab Symcon 5.2) |
| width (optional) | Feste Breite des Buttons in Pixel oder % als String, z.B. "40%" oder "250px". Ist der Wert nicht gesetzt oder "", wird die Breite automatisch auf Basis der Beschriftung gewählt (ab Symcon 5.2) |
Parameter für popup
| Parameter | Beschreibung |
|---|---|
| buttons (optional) | (default: []) Eine Liste von Buttons welche im Popup unten rechts dargestellt wird. An erster Stelle wird immer der Schließen-Button dargestellt, danach folgen die hier beschriebenen Buttons in Reihenfolge (ab Symcon 6.1) |
| caption (optional) | (default: "") Sichtbarer Titel des Popups |
| closeCaption (optional) | (default: "Schließen", bei mehreren (link: ./#Parameter_für_pages text: pages) "Abbrechen") Die Beschriftung des Schließen-Buttons unten rechts im Popup (ab Version 6.1) |
| initialPage (optional) | (default: 0) Eine Referenz auf die Seite aus pages, welche beim Öffnen des Popups angezeigt werden soll. Dies kann eine Zahl sein, welche dem Index innerhalb der Liste pages entspricht, ein String, welcher dem Namen der Seite entspricht oder ein Skript, welches die Seite als Zahl oder String zurückgibt. Sofern das Skript aus mehreren Zeilen besteht, können die einzelnen Zeilen auch als Array übergeben werden. Es sind keine PHP-Tags erforderlich. Es hat die gleichen Eigenschaften wie onClick des Button. Existiert die definierte Seite nicht, so wird die erste Seite angezeigt. Eine Änderung von initialPage wirkt sich erst beim nächsten Öffnen des Popups aus. (ab Symcon 9.1) |
| items | Auflistung von Formularfeldern im Popup (nicht änderbar). Alternativ kann PHP-Code als String oder Array aus Strings angegeben werden, welcher die Liste der Formularfelder per return zurückgibt (ab Symcon 9.1). Bei Nutzung von pages dient items als Standard für Seiten ohne eigene items und kann entfallen |
| pages (optional) | (default: []) Eine Liste von Seiten des Popups welche miteinander verkettet werden können und so die Funktionalität eines Wizards zu ermöglichen. Ist die Liste leer, so wird der regulär definierte Inhalt angezeigt. Siehe Wizard (ab Symcon 9.1) |
| width (optional) | (default: "") Initiale Breite des Popups in Pixel oder % als String, z.B. "40%" oder "250px". Prozentangaben beziehen sich auf die Breite des Browserfensters. Ist der Wert nicht gesetzt oder "", wird die Standardbreite verwendet (ab Symcon 9.0) |
Parameter für pages
Das Feld pages beinhaltet eine Liste von Objekten, welche jeweils eine Seite beschreiben. Enthält die Liste mindestens zwei Seiten, so werden bei den Buttons ganz rechts zusätzlich "Zurück" und "Weiter" bzw. "OK" angezeigt, worüber die Seiten gewechselt werden können. Der Schließen-Button ist dann standardmäßig mit "Abbrechen" beschriftet. Für den zweiten Button wird "Weiter" angezeigt, falls die über nextPage bestimmte Seite existiert, ansonsten "OK", welches das Popup schließt. "Zurück" ist aktiv, falls die aktuelle Seite über "Weiter" erreicht wurde. Wurde dabei eine Seite verlassen, welche ein Skript für "onConfirm", aber keines für "onUndo" definiert hat, so ist "Zurück" deaktiviert und keine der vorherigen Seiten kann wieder erreicht werden. Enthält die Liste nur eine Seite, so wird diese ohne "Zurück" und "Weiter" wie ein reguläres Popup angezeigt. Anwendungsfälle, der genaue Ablauf und Beispiele sind im Abschnitt Wizard beschrieben. Jedes dieser Objekte kann die folgenden Parameter nutzen:
| Parameter | Beschreibung |
|---|---|
| buttons (optional) | (default: buttons von popup) Eine Liste von Buttons, welche angezeigt werden, solange diese Seite aktiv ist |
| caption (optional) | (default: caption von popup) Sichtbarer Titel des Popups, solange diese Seite aktiv ist |
| items (optional) | (default: items von popup) Auflistung von Formularfeldern der Seite. Alternativ kann PHP-Code als String oder Array aus Strings angegeben werden, welcher die Liste der Formularfelder per return zurückgibt. Der Code wird ausgeführt, wenn auf die Seite gewechselt wird, und kann so Inhalte abhängig von vorherigen Eingaben erzeugen. Siehe Werte und Skripte |
| name (optional) | Ein eindeutiger Name zur Referenzierung, typischerweise für nextPage oder initialPage |
| nextPage (optional) | (default: nächste Seite) Eine Referenz auf die Seite, welche bei Klick auf "Weiter" gezeigt werden soll. Dies kann eine Zahl sein, welche dem Index innerhalb der Liste pages entspricht, ein String, welcher dem Namen der Seite entspricht oder Skript, welches die nächste Seite als Zahl oder String zurückgibt. Sofern das Skript aus mehreren Zeilen besteht, können die einzelnen Zeilen auch als Array übergeben werden. Es sind keine PHP-Tags erforderlich. Es hat die gleichen Eigenschaften wie onClick des Button. Existiert die definierte Seite nicht, z.B. bei -1, so wird "OK" angezeigt und der Klick darauf schließt das Popup. Ein String, der keinem Namen einer Seite entspricht, wird als Skript ausgeführt. Ein Index muss vom Skript als Zahl zurückgegeben werden, ein zurückgegebener String wird immer als Name interpretiert. Das Skript wird beim Anzeigen der Seite und nach jeder Änderung eines Wertes erneut ausgeführt, damit die Beschriftung "Weiter" bzw. "OK" immer passt. Wird das Skript erneut gestartet, bevor eine vorherige Ausführung beendet ist, so gilt nur das Ergebnis der zuletzt gestarteten Ausführung |
| onConfirm (optional) | (default: "") Skript das bei Betätigung von "Weiter" bzw. "OK" ausgeführt wird. Sofern das Skript aus mehreren Zeilen besteht, können die einzelnen Zeilen auch als Array übergeben werden. Es sind keine PHP-Tags erforderlich. Es hat die gleichen Eigenschaften wie onClick des Button. Sollte der Seitenwechsel durch validate verhindert werden, so wird onConfirm nicht ausgeführt. Eine Ausgabe des Skriptes wird als Meldung angezeigt, der Seitenwechsel findet trotzdem statt. Ist onConfirm ohne onUndo definiert, so ist nach dem Verlassen der Seite kein "Zurück" mehr möglich |
| onUndo (optional) | (default: "") Skript das bei Rückkehr auf diese Seite über "Zurück" ausgeführt wird. Sofern das Skript aus mehreren Zeilen besteht, können die einzelnen Zeilen auch als Array übergeben werden. Es sind keine PHP-Tags erforderlich. Es hat die gleichen Eigenschaften wie onClick des Button. Es sollte die Änderungen des onConfirm dieser Seite rückgängig machen. Die Formularfelder der Seite stehen dabei mit den Werten zur Verfügung, die sie beim Verlassen der Seite hatten. Nur ein nicht-leeres onUndo ermöglicht die Rückkehr auf eine Seite mit onConfirm. "onUndo": "" verhält sich wie ein fehlendes onUndo. Gibt es nichts rückgängig zu machen, soll "Zurück" aber möglich bleiben, so genügt ein Kommentar, z.B. "onUndo": "// Nichts rückgängig zu machen" |
| validate (optional) | (default: "") Skript das bei Betätigung von "Weiter" bzw. "OK" ausgeführt wird, nachdem die Formularfelder der Seite gültig sind, z.B. entsprechend validate einer ValidationTextBox. Sofern das Skript aus mehreren Zeilen besteht, können die einzelnen Zeilen auch als Array übergeben werden. Es sind keine PHP-Tags erforderlich. Es hat die gleichen Eigenschaften wie onClick des Button. Gibt das Skript per return einen nicht-leeren String zurück, so wird dieser als Fehler angezeigt und es findet kein Seitenwechsel statt und onConfirm wird nicht ausgeführt. Der String wird über die Übersetzungen des Moduls übersetzt. Das Skript darf keine Ausgabe, z.B. per echo, machen |
Die Parameter closeCaption und width gelten immer für das gesamte Popup und können nicht je Seite festgelegt werden.
| Parameter | Beschreibung |
|---|---|
| caption | Sichtbare Beschriftung des Buttons |
| onClick | Skript, welches bei einem Klick auf den Button ausgeführt wird. Sofern das Skript aus mehreren Zeilen besteht, können die einzelnen Zeilen auch als Array übergeben werden. Es sind keine PHP-Tags erforderlich. Es hat die gleichen Eigenschaften wie onClick des Button. Sofern das Skript keine Ausgabe macht, wird das Popup nach Abarbeitung des Skriptes geschlossen. Ansonsten wird die Ausgabe als rote Fehlermeldung unten im Popup angzeigt. Eine Ausnahme besteht hier wenn die Rückgabe mit dem Präfix "MESSAGE:" beginnt. In diesem Fall wird das Popup geschlossen und die Rückgabe hinter dem Präfix in einem Meldungsdialog angezeigt. |
| enabled (optional) | (default: true) Bei true kann der Button verwendet werden, ansonsten wird er deaktiviert dargestellt |
Wizard
Über den Parameter pages wird aus einem Popup ein Wizard (Assistent), welcher den Benutzer Schritt für Schritt durch einen Vorgang führt (ab Symcon 9.1). Jede Seite zeigt nur die Formularfelder, die für den aktuellen Schritt relevant sind. Eingaben können je Seite geprüft werden, die Reihenfolge der Seiten kann von vorherigen Eingaben abhängen und Aktionen werden erst ausgeführt, wenn der Benutzer einen Schritt bestätigt. Seiten stehen beim PopupButton und beim PopupAlert gleichermaßen zur Verfügung.
Anwendungsfälle
Ein Wizard bietet sich an, wenn
- ein Modul nach dem Anlegen eingerichtet werden muss. Ein PopupAlert kann den Einrichtungsassistenten automatisch öffnen, solange die Instanz noch nicht konfiguriert ist, siehe Einrichtungsassistent
- eine Konfiguration aus mehreren Schritten besteht und spätere Schritte von vorherigen Antworten abhängen, z.B. Adresse und Port bei einer Netzwerkverbindung, aber eine Schnittstelle bei einer seriellen Verbindung
- Eingaben geprüft werden sollen, bevor es weitergeht, z.B. ob ein Gerät unter der eingegebenen Adresse erreichbar ist
- Geräte gesucht oder Daten importiert werden und das Ergebnis auf einer eigenen Seite zur Auswahl angezeigt wird
- vor dem Übernehmen eine Zusammenfassung aller Eingaben angezeigt werden soll
- vor einer folgenreichen Aktion, z.B. dem Zurücksetzen eines Gerätes, Optionen abgefragt und eine Bestätigung eingeholt werden soll. Für eine reine Sicherheitsabfrage genügt ein Popup mit buttons
Einzelne Einstellungen ohne feste Reihenfolge gehören hingegen in ein reguläres Popup oder direkt in das Konfigurationsformular.
Ablauf
| Aktion | Verhalten |
|---|---|
| Öffnen | Die über initialPage bestimmte Seite wird angezeigt, standardmäßig die erste Seite. Beim PopupButton wird gleichzeitig onClick ausgeführt. "Zurück" ist deaktiviert |
| Weiter bzw. OK | 1. Die Formularfelder der aktuellen Seite werden geprüft, z.B. validate einer ValidationTextBox. 2. validate der Seite wird ausgeführt. Gibt es einen Fehler zurück, so bleibt die Seite stehen. 3. onConfirm der Seite wird ausgeführt. 4. Existiert die über nextPage bestimmte Seite, so wird sie angezeigt, ansonsten wird das Popup geschlossen |
| Zurück | Die zuletzt über "Weiter" verlassene Seite wird wieder angezeigt. Ihre Formularfelder erhalten die Werte, die sie beim Verlassen hatten, und ihr onUndo wird ausgeführt. validate und onConfirm der aktuellen Seite werden nicht ausgeführt |
| Abbrechen | Das Popup wird geschlossen. Es wird kein Skript ausgeführt und bereits ausgeführte onConfirm-Skripte werden nicht rückgängig gemacht |
| Erneut öffnen | Der Wizard beginnt wieder bei initialPage, "Zurück" ist deaktiviert. Die Eingaben des letzten Durchlaufs bleiben erhalten, bis das Konfigurationsformular neu geladen wird |
Die Eingaben im Wizard werden nicht automatisch gespeichert. Das Ergebnis wird typischerweise auf eine der folgenden Arten übernommen:
- Im onConfirm der letzten Seite werden die Eigenschaften direkt gesetzt, z.B. per IPS_SetProperty und IPS_ApplyChanges oder über eine Funktion des Moduls, siehe Beispiel 1 und 2.
- Im onConfirm werden die Werte per UpdateFormField in die Felder des Konfigurationsformulars geschrieben. Der Benutzer sieht die Werte und speichert sie wie gewohnt mit "Änderungen übernehmen", siehe das Beispiel beim PopupAlert.
- Jeder Schritt führt direkt eine Aktion aus, z.B. das Anlegen einer Instanz. Dann sollte onUndo diese Aktion rückgängig machen, siehe Beispiel 3.
Werte und Skripte
Die Skripte validate, onConfirm, onUndo, nextPage und initialPage sowie PHP-Code in items werden wie das onClick eines Button als eigenständiges Skript ausgeführt und nicht innerhalb des Moduls. $this steht daher nicht zur Verfügung, Funktionen des Moduls werden über ihren Präfix aufgerufen. Folgende Variablen stehen zur Verfügung:
| Variable | Inhalt |
|---|---|
| $id | ID der Instanz |
| $(Name eines Elements) | Der aktuelle Wert jedes benannten Formularfelds aller Seiten des Wizards sowie der übrigen Formularfelder im selben Bereich (elements bzw. actions). Formularfelder statisch definierter Seiten stehen schon zur Verfügung, bevor ihre Seite angezeigt wurde, und haben dann ihren Startwert. Formularfelder, die per PHP-Code in items erzeugt werden, stehen erst zur Verfügung, nachdem ihre Seite angezeigt wurde |
| Skript | Ergebnis |
|---|---|
| validate | Ein nicht-leerer String per return verhindert den Seitenwechsel und wird als Fehler angezeigt |
| nextPage, initialPage | Index als Zahl oder Name der Seite als String per return |
| items | Array von Formularfeldern per return |
| onConfirm, onUndo | Eine Ausgabe, z.B. per echo, wird als Meldung angezeigt. Ein Rückgabewert wird ignoriert |
Bei validate, nextPage, initialPage und items macht jede Ausgabe, z.B. per echo oder durch eine PHP-Warnung, das Ergebnis ungültig und wird als Fehler angezeigt.
Über UpdateFormField kann das Modul Formularfelder jeder Seite anpassen, auch wenn diese gerade nicht angezeigt wird. Die Änderung wird sichtbar, sobald auf die Seite gewechselt wird. So kann z.B. das onChange eines Select auf der ersten Seite die Optionen eines Select auf der zweiten Seite setzen, siehe Beispiel 3.
Seitenwechsel steuern
- Ohne nextPage folgt die nächste Seite der Liste. Auf der letzten Seite wird "OK" angezeigt.
- Mit einem Index oder Namen in nextPage wird auf eine feste Seite gesprungen, z.B. führen mehrere Zweige über "nextPage": "summary" wieder zur gleichen Zusammenfassung zusammen.
- Für eine Verzweigung gibt ein Skript den Namen der nächsten Seite zurück. Am einfachsten entsprechen die Werte der Optionen eines RadioButtonGroup oder Select den Namen der Seiten, z.B. "nextPage": "return $WizardConnection;". Da das Skript nach jeder Änderung eines Wertes ausgeführt wird, sollte es schnell sein und nichts verändern. Aufwändige Prüfungen, z.B. eine Verbindung zum Gerät, gehören in validate.
- Soll eine Seite den Wizard beenden, obwohl weitere Seiten in der Liste folgen, so wird "nextPage": -1 gesetzt. Statt "Weiter" wird dann "OK" angezeigt, welches das Popup schließt. Ein Skript in nextPage kann ebenso -1 zurückgeben. Das ist typisch für Abschlussseiten am Ende der Liste, welche über ihren Namen angesprungen werden, z.B. eine Zusammenfassung und ein Hinweis beim Überspringen der Einrichtung.
- Die aktuelle Seite eines geöffneten Wizards kann nicht direkt per UpdateFormField gewechselt werden. Soll das Modul über den Weg entscheiden, so ruft nextPage eine Funktion des Moduls auf, z.B. "nextPage": "return WIZ_UIGetNextPage($id, $WizardModel);". Über popup.initialPage kann das Modul die Startseite für das nächste Öffnen festlegen. Ein PopupAlert kann zusätzlich per UpdateFormField über visible geöffnet werden. Ist er bereits geöffnet, so beginnt er dadurch erneut auf der über popup.initialPage festgelegten Seite, siehe PopupAlert.
Hinweise zu Wizards
- Die Namen der Formularfelder müssen über alle Seiten eindeutig sein. Gleichnamige Formularfelder auf verschiedenen Seiten teilen sich einen Wert. Die Namen sollten sich zudem von den Eigenschaften und den übrigen Formularfeldern unterscheiden, z.B. durch das Präfix "Wizard".
- Der Benutzer kann jederzeit abbrechen. Dauerhafte Änderungen, z.B. das Anlegen einer Instanz oder das Senden an ein Gerät, sollten daher möglichst erst im onConfirm der letzten Seite erfolgen. Erfolgen sie früher, sollte onUndo sie rückgängig machen. Beim Abbrechen wird jedoch kein onUndo ausgeführt.
- Ein onConfirm ohne onUndo verhindert die Rückkehr auf alle vorherigen Seiten. Das ist sinnvoll, wenn ein Schritt nicht rückgängig gemacht werden kann.
- Eingaben bleiben beim erneuten Öffnen des Popups erhalten. Soll der Wizard jedes Mal leer beginnen, so können die Werte z.B. im onClick des PopupButtons per UpdateFormField zurückgesetzt oder das Formular per ReloadForm neu geladen werden.
- Die Liste pages kann nicht per UpdateFormField geändert werden. Hängen Anzahl oder Inhalt der Seiten von der Konfiguration ab, so werden die Seiten in GetConfigurationForm erzeugt oder ihre items per PHP-Code.
- Eine Fortschrittsanzeige gibt es nicht. Ein Titel wie "Schritt 2 von 3" in der caption der Seite zeigt dem Benutzer, wo er sich befindet.
Beispiele für Wizards
Beispiel 1: Linearer Wizard mit drei Schritten, welcher eine Grenzwertüberwachung einrichtet. Die erste Seite prüft per validate, ob eine Variable ausgewählt wurde, die zweite Seite nutzt die Validierung der ValidationTextBox. Die letzte Seite erzeugt per PHP-Code eine Zusammenfassung aus den Eingaben der vorherigen Seiten. Mit "OK" werden die Eigenschaften VariableID, Limit und Message gesetzt, welche das Modul in Create registriert.
// Beispiel 1: Linearer Wizard, z.B. unter actions
{
"type": "PopupButton",
"caption": "Grenzwertüberwachung einrichten",
"popup": {
"caption": "Grenzwertüberwachung einrichten",
"width": "600px",
"pages": [
{
"caption": "Schritt 1 von 3: Variable",
"items": [
{ "type": "Label", "caption": "Welche Variable soll überwacht werden?" },
{ "type": "SelectVariable", "name": "WizardVariableID", "caption": "Variable", "validVariableTypes": [1, 2] }
],
"validate": "if (!IPS_VariableExists($WizardVariableID)) { return 'Bitte eine Variable auswählen'; }"
},
{
"caption": "Schritt 2 von 3: Grenzwert",
"items": [
{ "type": "NumberSpinner", "name": "WizardLimit", "caption": "Grenzwert", "digits": 1 },
{ "type": "ValidationTextBox", "name": "WizardMessage", "caption": "Meldung bei Überschreitung", "validate": "^.+$" }
]
},
{
"caption": "Schritt 3 von 3: Zusammenfassung",
"items": [
"return [",
" ['type' => 'Label', 'caption' => 'Variable: ' . IPS_GetLocation($WizardVariableID)],",
" ['type' => 'Label', 'caption' => 'Grenzwert: ' . $WizardLimit],",
" ['type' => 'Label', 'caption' => 'Meldung: ' . $WizardMessage],",
" ['type' => 'Label', 'caption' => 'Mit OK wird die Überwachung aktiviert.']",
"];"
],
"onConfirm": [
"IPS_SetProperty($id, 'VariableID', $WizardVariableID);",
"IPS_SetProperty($id, 'Limit', $WizardLimit);",
"IPS_SetProperty($id, 'Message', $WizardMessage);",
"IPS_ApplyChanges($id);"
]
}
]
}
}
Beispiel 2: Verzweigung abhängig von einer Auswahl. Die Werte der RadioButtonGroup entsprechen den Namen der Seiten, sodass nextPage die Auswahl direkt zurückgeben kann. Beide Zweige führen über "nextPage": "summary" zur gleichen Zusammenfassung. Die Zusammenfassung wertet nur die Felder des gewählten Zweigs aus. Mit "OK" werden die Eigenschaften Connection, Host, Port und SerialPortID gesetzt.
// Beispiel 2: Verzweigung, z.B. unter actions
{
"type": "PopupButton",
"caption": "Verbindung einrichten",
"popup": {
"caption": "Verbindung einrichten",
"pages": [
{
"caption": "Verbindungsart",
"items": [
{
"type": "RadioButtonGroup",
"name": "WizardConnection",
"caption": "Wie ist das Gerät angeschlossen?",
"value": "network",
"options": [
{ "caption": "Netzwerk", "value": "network" },
{ "caption": "Serielle Schnittstelle", "value": "serial" }
]
}
],
"nextPage": "return $WizardConnection;"
},
{
"name": "network",
"caption": "Netzwerk",
"items": [
{ "type": "ValidationTextBox", "name": "WizardHost", "caption": "Host", "validate": "^[a-zA-Z0-9.:-]+$" },
{ "type": "NumberSpinner", "name": "WizardPort", "caption": "Port", "value": 502, "minimum": 1, "maximum": 65535 }
],
"nextPage": "summary"
},
{
"name": "serial",
"caption": "Serielle Schnittstelle",
"items": [
{ "type": "SelectInstance", "name": "WizardSerialPortID", "caption": "Serial Port", "validModules": ["{6DC3D946-0D31-450F-A8C6-C42DB8D7D4F1}"] }
],
"validate": "if (!IPS_InstanceExists($WizardSerialPortID)) { return 'Bitte einen Serial Port auswählen'; }",
"nextPage": "summary"
},
{
"name": "summary",
"caption": "Zusammenfassung",
"items": [
"if ($WizardConnection == 'network') {",
" $text = 'Netzwerk: ' . $WizardHost . ':' . $WizardPort;",
"} else {",
" $text = 'Seriell: ' . IPS_GetName($WizardSerialPortID);",
"}",
"return [['type' => 'Label', 'caption' => $text]];"
],
"onConfirm": [
"IPS_SetProperty($id, 'Connection', $WizardConnection);",
"IPS_SetProperty($id, 'Host', $WizardHost);",
"IPS_SetProperty($id, 'Port', $WizardPort);",
"IPS_SetProperty($id, 'SerialPortID', $WizardSerialPortID);",
"IPS_ApplyChanges($id);"
]
}
]
}
}
Beispiel 3: Ein Gerät hinzufügen, wobei die Inhalte vom Modul bestimmt werden. Die Hersteller werden in GetConfigurationForm eingetragen. Wird ein Hersteller gewählt, setzt das Modul per UpdateFormField die Modelle auf der zweiten Seite. validate der zweiten Seite prüft über das Modul, ob das Gerät erreichbar ist. onConfirm legt die Instanz an und onUndo löscht sie wieder, falls der Benutzer über "Zurück" auf diese Seite zurückkehrt. Die dritte Seite wird vom Modul anhand der angelegten Instanz erzeugt. Erst "OK" schließt die Einrichtung ab. Bricht der Benutzer auf der dritten Seite ab, so bleibt die angelegte Instanz bestehen.
// Beispiel 3: form.json
{
"actions": [
{
"type": "PopupButton",
"caption": "Gerät hinzufügen",
"popup": {
"caption": "Gerät hinzufügen",
"pages": [
{
"caption": "Schritt 1 von 3: Hersteller",
"items": [
{
"type": "Select",
"name": "WizardVendor",
"caption": "Hersteller",
"options": [],
"onChange": "WIZ_UIUpdateModels($id, $WizardVendor);"
}
],
"validate": "if ($WizardVendor == '') { return 'Bitte einen Hersteller auswählen'; }"
},
{
"caption": "Schritt 2 von 3: Gerät",
"items": [
{ "type": "Select", "name": "WizardModel", "caption": "Modell", "options": [] },
{ "type": "ValidationTextBox", "name": "WizardHost", "caption": "IP-Adresse" }
],
"validate": "return WIZ_UIValidateDevice($id, $WizardModel, $WizardHost);",
"onConfirm": "WIZ_UICreateDevice($id, $WizardModel, $WizardHost);",
"onUndo": "WIZ_UIDeleteDevice($id);"
},
{
"caption": "Schritt 3 von 3: Fertigstellen",
"items": "return json_decode(WIZ_UIGetFinishItems($id), true);",
"validate": "if (trim($WizardName) == '') { return 'Bitte einen Namen eingeben'; }",
"onConfirm": "WIZ_UIFinish($id, $WizardName);"
}
]
}
}
]
}
// Beispiel 3: module.php
<?php
declare(strict_types=1);
class DeviceWizard extends IPSModule
{
// GUID des Moduls, von dem Instanzen angelegt werden
private const DEVICE_MODULE = '{5A1C8F2E-3B7D-4C9A-9E61-2F4D8B0C7A13}';
// In einem echten Modul stammt diese Liste z.B. aus einer Datei mit Gerätevorlagen
private const VENDORS = [
'vendorA' => ['caption' => 'Hersteller A', 'models' => ['A100' => 'Sensor A100', 'A200' => 'Sensor A200']],
'vendorB' => ['caption' => 'Hersteller B', 'models' => ['B10' => 'Zähler B10']]
];
public function Create()
{
//Never delete this line!
parent::Create();
$this->RegisterAttributeInteger('WizardInstanceID', 0);
}
public function GetConfigurationForm()
{
$form = json_decode(file_get_contents(__DIR__ . '/form.json'), true);
$options = [['caption' => 'Bitte auswählen', 'value' => '']];
foreach (self::VENDORS as $vendor => $data) {
$options[] = ['caption' => $data['caption'], 'value' => $vendor];
}
$form['actions'][0]['popup']['pages'][0]['items'][0]['options'] = $options;
return json_encode($form);
}
// onChange auf Seite 1: Setzt die Modelle auf Seite 2, auch wenn diese noch nicht angezeigt wird
public function UIUpdateModels(string $Vendor)
{
$options = [];
foreach (self::VENDORS[$Vendor]['models'] ?? [] as $model => $caption) {
$options[] = ['caption' => $caption, 'value' => $model];
}
$this->UpdateFormField('WizardModel', 'options', json_encode($options));
$this->UpdateFormField('WizardModel', 'value', $options[0]['value'] ?? '');
}
// validate auf Seite 2: Ein leerer String erlaubt den Seitenwechsel
public function UIValidateDevice(string $Model, string $Host): string
{
if ($Model == '') {
return 'Bitte ein Modell auswählen';
}
if (!filter_var($Host, FILTER_VALIDATE_IP)) {
return 'Bitte eine gültige IP-Adresse eingeben';
}
if (!Sys_Ping($Host, 1000)) {
return 'Das Gerät antwortet nicht';
}
return '';
}
// onConfirm auf Seite 2
public function UICreateDevice(string $Model, string $Host)
{
$instanceID = IPS_CreateInstance(self::DEVICE_MODULE);
IPS_SetName($instanceID, $Model);
IPS_SetProperty($instanceID, 'Model', $Model);
IPS_SetProperty($instanceID, 'Host', $Host);
IPS_ApplyChanges($instanceID);
$this->WriteAttributeInteger('WizardInstanceID', $instanceID);
}
// onUndo auf Seite 2: Macht UICreateDevice rückgängig
public function UIDeleteDevice()
{
$instanceID = $this->ReadAttributeInteger('WizardInstanceID');
if (IPS_InstanceExists($instanceID)) {
IPS_DeleteInstance($instanceID);
}
$this->WriteAttributeInteger('WizardInstanceID', 0);
}
// items auf Seite 3: Wird beim Wechsel auf die Seite ausgeführt
public function UIGetFinishItems(): string
{
$instanceID = $this->ReadAttributeInteger('WizardInstanceID');
return json_encode([
[
'type' => 'Label',
'caption' => sprintf('Das Gerät wurde als Instanz #%d angelegt.', $instanceID)
],
[
'type' => 'ValidationTextBox',
'name' => 'WizardName',
'caption' => 'Name',
'value' => IPS_GetName($instanceID)
]
]);
}
// onConfirm auf Seite 3
public function UIFinish(string $Name)
{
$instanceID = $this->ReadAttributeInteger('WizardInstanceID');
IPS_SetName($instanceID, $Name);
$this->WriteAttributeInteger('WizardInstanceID', 0);
}
}
Beispiel
{
"type": "PopupButton",
"caption": "Open Popup",
"popup": {
"caption": "My Element Popup",
"items": [
{
"type": "SelectVariable",
"name": "VariableTest",
"caption": "Some Variable"
}
]
}
},
{
"type": "PopupButton",
"caption": "Wizard starten",
"popup": {
"caption": "Ein Titel, der nie gesehen wird, da jede Seite ihn überschreibt",
"closeCaption": "Schließe Dialog",
"items": [
{
"type": "Label",
"caption": "Dieses Element wird nie gesehen, da jede Seite ihre eigenen items hat"
}
],
"pages": [
{
"caption": "Start",
"items": [
{
"type": "Label",
"caption": "Nächste Seite: Auswahl"
}
],
"nextPage": 2
},
{
"caption": "Nie sichtbar",
"items": [
{
"type": "Label",
"caption": "Diese Seite wird nie angezeigt, da die Startseite direkt auf die Seite mit Index 2 springt, die Auswahl"
}
]
},
{
"caption": "Auswahl",
"items": [
{
"type": "Select",
"name": "NextPage",
"options": [
{"value": "page1", "caption": "Gehe zu Seite 1"},
{"value": "page2", "caption": "Gehe zu Seite 2"},
{"value": "close", "caption": "Fertig, schließen"}
],
"caption": "Wähle nächste Seite"
}
],
"nextPage": "return $NextPage;"
},
{
"name": "page1",
"caption": "Seite 1",
"items": [
{
"type": "Label",
"caption": "Dies ist Seite 1 mit 'Undo'"
}
],
"onUndo": "echo 'Seite 1 rückgängig machen';",
"onConfirm": "echo 'Seite 1 bestätigen';"
},
{
"name": "page2",
"caption": "Seite 2",
"items": [
{
"type": "Label",
"caption": "Dies ist Seite 2, es gibt kein 'Undo'. Dies ist auch die letzte Seite des Wizards."
}
],
"onConfirm": "echo 'Seite 2 bestätigen';"
}
]
}
}