Documentation
PopupAlert
Require: Symcon >= 5.0
If the configuration form contains this element, it will be opened when the configuration page is loaded. After the popup has been closed, it is also possible to open it again using dynamics (visible to true).

General Parameters
| Parameters | Description |
|---|---|
| name (optional) | Name of the PopupAlert |
| popup | Definition of the popup to be opened (parameters can be changed since Symcon 6.1 by linking the parameter names, e.g. popup.closeCaption) |
| type | PopupAlert |
| visible (optional) | (default: true) If visible is initially true, the popup is opened when the instance configuration is opened, otherwise nothing happens. By changing to true, the popup can be opened afterwards. A change to false closes a currently open popup. (since Symcon 5.2) |
Parameters for popup
| Parameters | Description |
|---|---|
| buttons (optional) | (default: []) A list of buttons which is shown in the popup at the bottom right. The close button is always displayed first, followed by the buttons described here in sequence (since Symcon 6.1) |
| caption (optional) | (default: "") Visible title of the popup (since Symcon 8.2) |
| closeCaption (optional) | (default: "OK", "Cancel" if there are several (link: ./#Parameters_for_pages text: pages)) The caption of the close button at the bottom right of the popup |
| initialPage (optional) | (default: 0) A reference to the page from pages that is shown when the popup is opened. This can be a number corresponding to the index within the pages list, a string corresponding to the name of the page, or a script returning the page as a number or string. If the script consists of several lines, the individual lines can also be defined as an array. No PHP-tags are required. It has the same properties as onClick of the Button. If the defined page does not exist, the first page is shown. A change to initialPage only takes effect the next time the popup is opened. (since Symcon 9.1) |
| items | List of form fields in the popup (cannot be changed). Alternatively, PHP code can be specified as a string or an array of strings which returns the list of form fields via return (since Symcon 9.1). When using pages, items is the default for pages without their own items and can be omitted |
| pages (optional) | (default: []) A list of pages of the popup that can be linked together to enable the functionality of a wizard. If the list is empty, the regularly defined content is displayed. See Wizard (since Symcon 9.1) |
| width (optional) | (default: "") Initial width of the popup in pixels or % as a string, e.g. "40%" or "250px". Percentages refer to the width of the browser window. If the value is not set or "", the default width is used (since Symcon 9.0) |
Parameters for pages
The pages field contains a list of objects, each describing a page. If the list contains at least two pages, the buttons on the far right additionally show "Previous" and "Next" or "OK", which can be used to switch between pages. The close button is then labeled "Cancel" by default. For the second button, "Next" is displayed if the page determined by nextPage exists, otherwise "OK", which closes the popup. "Previous" is active if the current page was reached via "Next". If a page was left on the way that defines a script for "onConfirm" but none for "onUndo", "Previous" is deactivated and none of the previous pages can be reached again. If the list contains only one page, it is displayed like a regular popup without "Previous" and "Next". Use cases, the exact flow and examples are described in the section Wizard and in detail for the PopupButton. Each of these objects can use the following parameters:
| Parameter | Description |
|---|---|
| buttons (optional) | (default: buttons of popup) A list of buttons which is shown while this page is active |
| caption (optional) | (default: caption of popup) Visible title of the popup while this page is active |
| items (optional) | (default: items of popup) List of form fields of the page. Alternatively, PHP code can be specified as a string or an array of strings which returns the list of form fields via return. The code is executed when switching to the page and can thus generate content depending on previous inputs. See Values and scripts |
| name (optional) | A unique name for referencing, typically for nextPage or initialPage |
| nextPage (optional) | (default: next page) A reference to the page to be shown when "Next" is clicked. This can be a number corresponding to the index within the pages list, a string corresponding to the name of the page, or a script returning the next page as a number or string. If the script consists of several lines, the individual lines can also be defined as an array. No PHP-tags are required. It has the same properties as onClick of the Button. If the defined page does not exist, e.g. for -1, "OK" is shown and clicking it closes the popup. A string that does not match the name of a page is executed as a script. An index must be returned by the script as a number, a returned string is always interpreted as a name. The script is executed again when the page is shown and after every change of a value, so the caption "Next" or "OK" always fits. If the script is started again before a previous execution has finished, only the result of the most recently started execution is used |
| onConfirm (optional) | (default: "") Script that is executed when "Next" or "OK" is pressed. If the script consists of several lines, the individual lines can also be defined as an array. No PHP-tags are required. It has the same properties as onClick of the Button. If the page change is prevented by validate, onConfirm is not executed. An output of the script is shown as a message, the page change takes place anyway. If onConfirm is defined without onUndo, "Previous" is no longer possible after leaving the page |
| onUndo (optional) | (default: "") Script that is executed when returning to this page via "Previous". If the script consists of several lines, the individual lines can also be defined as an array. No PHP-tags are required. It has the same properties as onClick of the Button. It should revert the changes of the onConfirm of this page. The form fields of the page are available with the values they had when the page was left. Only a non-empty onUndo allows returning to a page with onConfirm. "onUndo": "" behaves like a missing onUndo. If there is nothing to revert but "Previous" should remain possible, a comment is sufficient, e.g. "onUndo": "// Nothing to revert" |
| validate (optional) | (default: "") Script that is executed when "Next" or "OK" is pressed, after the form fields of the page are valid, e.g. according to validate of a ValidationTextBox. If the script consists of several lines, the individual lines can also be defined as an array. No PHP-tags are required. It has the same properties as onClick of the Button. If the script returns a non-empty string via return, it is displayed as an error, no page change takes place and onConfirm is not executed. The string is translated using the translations of the module. The script must not produce any output, e.g. via echo |
The parameters closeCaption and width always apply to the whole popup and cannot be defined per page.
| Parameters | Description |
|---|---|
| caption | Visible caption of the button |
| onClick | Script that is executed when the button is clicked. If the script consists of several lines, the individual lines can also be defined as an array. No PHP-tags are required. It has the same properties as onClick of the Button. If the script does not produce any output, the popup is closed after the script has been processed. Otherwise the output is shown as a red error message at the bottom of the popup. There is an exception here if the return begins with the prefix "MESSAGE:". In this case the popup is closed and the return is displayed after the prefix in a message dialog. |
| enabled (optional) | (default: true) If true, the button can be used, otherwise it is displayed as deactivated |
Wizard
Using the parameter pages, the popup becomes a wizard which guides the user step by step through a process (since Symcon 9.1). The pages of the PopupAlert behave exactly like those of the PopupButton. Use cases, the flow of Next, Previous and Cancel, the available variables, controlling page changes, notes and further examples are described for the PopupButton.
In contrast to the PopupButton, the PopupAlert is opened without a click of the user:
- If visible is true when the configuration form is loaded, the wizard is opened immediately. If GetConfigurationForm sets visible depending on the configuration, the wizard appears exactly when the instance still has to be set up.
- The module can open the wizard at any time via UpdateFormField using visible, e.g. via a button "Start setup", and close it with false. The wizard then starts on the page defined by initialPage or popup.initialPage. This also applies if the wizard is already open: If the module first sets popup.initialPage and then visible to true, the wizard switches to this page, e.g. via $this->UpdateFormField('SetupWizard', 'popup.initialPage', 'settings') and $this->UpdateFormField('SetupWizard', 'visible', true). The inputs are kept, "Previous" is deactivated afterwards.
Setup wizard
A proven pattern for setting up a module:
- The wizard is placed in actions and is made visible in GetConfigurationForm as long as a required property is not set.
- The first page welcomes the user and asks via a RadioButtonGroup how the setup should be done. The values of the options correspond to the names of the following pages, so nextPage can return the selection directly. One option allows skipping the setup.
- One page shows the result of a search. Its items are generated by the module via PHP code, so the search is executed again every time the page is shown.
- The onConfirm of the last settings page writes the values into the fields of the configuration form via UpdateFormField. The user sees the result and saves it with "Apply changes". The onUndo resets the fields to the saved values.
- Final pages are placed at the end of the list and are reached via their name: a summary and a note when the setup is skipped. The summary ends the wizard via "nextPage": -1 as the page for skipping still follows.
- A button in actions opens the wizard again.
Example: Setup wizard for a device in the network. As long as the property Host is empty, the wizard opens when the instance configuration is opened.
// Example: form.json
{
"elements": [
{ "type": "ValidationTextBox", "name": "Host", "caption": "Host" },
{ "type": "NumberSpinner", "name": "Interval", "caption": "Update interval", "suffix": "seconds", "minimum": 10 }
],
"actions": [
{
"type": "Button",
"caption": "Start setup",
"onClick": "SET_UIOpenWizard($id);"
},
{
"type": "PopupAlert",
"name": "SetupWizard",
"visible": false,
"popup": {
"caption": "Setup",
"width": "600px",
"pages": [
{
"caption": "Welcome",
"items": [
{ "type": "Label", "caption": "This wizard sets up the connection to the device." },
{
"type": "RadioButtonGroup",
"name": "WizardStart",
"caption": "How should the device be found?",
"value": "search",
"options": [
{ "caption": "Search in the network", "value": "search" },
{ "caption": "Enter address manually", "value": "manual" },
{ "caption": "Skip setup", "value": "skip" }
]
}
],
"nextPage": "return $WizardStart;"
},
{
"name": "search",
"caption": "Devices found",
"items": "return json_decode(SET_UIGetSearchItems($id), true);",
"validate": "if (($WizardFoundHost ?? '') == '') { return 'Please select a device'; }",
"nextPage": "settings"
},
{
"name": "manual",
"caption": "Address",
"items": [
{ "type": "ValidationTextBox", "name": "WizardManualHost", "caption": "Host", "validate": "^[a-zA-Z0-9.:-]+$" }
]
},
{
"name": "settings",
"caption": "Settings",
"items": [
{ "type": "NumberSpinner", "name": "WizardInterval", "caption": "Update interval", "suffix": "seconds", "value": 60 }
],
"validate": "if ($WizardInterval < 10) { return 'The interval must be at least 10 seconds'; }",
"onConfirm": "SET_UIApply($id, ($WizardStart == 'search') ? ($WizardFoundHost ?? '') : $WizardManualHost, $WizardInterval);",
"onUndo": "SET_UIRevert($id);",
"nextPage": "summary"
},
{
"name": "summary",
"caption": "Done",
"items": [
{ "type": "Label", "caption": "The settings have been entered in the configuration form. Please save them with \"Apply changes\"." }
],
"nextPage": -1
},
{
"name": "skip",
"caption": "Setup skipped",
"items": [
{ "type": "Label", "caption": "Without a host, the instance does not work. The setup can be continued at any time via \"Start setup\"." }
]
}
]
}
}
]
}
// Example: module.php
<?php
declare(strict_types=1);
class SetupWizardDevice extends IPSModule
{
public function Create()
{
//Never delete this line!
parent::Create();
$this->RegisterPropertyString('Host', '');
$this->RegisterPropertyInteger('Interval', 60);
}
public function GetConfigurationForm()
{
$form = json_decode(file_get_contents(__DIR__ . '/form.json'), true);
// The wizard opens automatically as long as the instance is not set up
$form['actions'][1]['visible'] = ($this->ReadPropertyString('Host') == '');
return json_encode($form);
}
// Button "Start setup"
public function UIOpenWizard()
{
$this->UpdateFormField('SetupWizard', 'visible', true);
}
// items of the page "search": Executed every time the page is shown
public function UIGetSearchItems(): string
{
// In a real module, the devices are searched here, e.g. via DNS-SD
$devices = ['192.168.1.20' => 'Device in the living room', '192.168.1.21' => 'Device in the basement'];
if (count($devices) == 0) {
return json_encode([
['type' => 'Label', 'caption' => 'No device was found. Please go back and enter the address manually.']
]);
}
$options = [];
foreach ($devices as $host => $name) {
$options[] = ['caption' => $name . ' (' . $host . ')', 'value' => $host];
}
return json_encode([
['type' => 'Select', 'name' => 'WizardFoundHost', 'caption' => 'Device', 'options' => $options, 'value' => $options[0]['value']]
]);
}
// onConfirm of the page "settings": Enters the values in the configuration form
public function UIApply(string $Host, int $Interval)
{
$this->UpdateFormField('Host', 'value', $Host);
$this->UpdateFormField('Interval', 'value', $Interval);
}
// onUndo of the page "settings": Restores the saved values
public function UIRevert()
{
$this->UpdateFormField('Host', 'value', $this->ReadPropertyString('Host'));
$this->UpdateFormField('Interval', 'value', $this->ReadPropertyInteger('Interval'));
}
}
Example
{
"type": "PopupAlert",
"popup": {
"closeCaption": "I understand",
"items": [
{
"type": "Label",
"caption": "Be careful when configuring this instance. Even small changes can have significant impact!"
}
]
}
},
{
"type": "PopupAlert",
"popup": {
"items": [
{
"type": "SelectVariable",
"name": "VariableActionTest",
"caption": "Some Action Variable"
}
]
}
},
{
"type": "PopupAlert",
"popup": {
"caption": "A title that is never seen since every page overrides it",
"closeCaption": "Close dialog",
"items": [
{
"type": "Label",
"caption": "This element is never seen since every page has its own items"
}
],
"pages": [
{
"caption": "Start",
"items": [
{
"type": "Label",
"caption": "Next page: Selection"
}
],
"nextPage": 2
},
{
"caption": "Never visible",
"items": [
{
"type": "Label",
"caption": "This page is never shown since the start page jumps directly to the page at index 2, the selection"
}
]
},
{
"caption": "Selection",
"items": [
{
"type": "Select",
"name": "NextPage",
"options": [
{"value": "page1", "caption": "Go to page 1"},
{"value": "page2", "caption": "Go to page 2"},
{"value": "close", "caption": "Done, close"}
],
"caption": "Choose next page"
}
],
"nextPage": "return $NextPage;"
},
{
"name": "page1",
"caption": "Page 1",
"items": [
{
"type": "Label",
"caption": "This is page 1 with 'Undo'"
}
],
"onUndo": "echo 'Undo page 1';",
"onConfirm": "echo 'Confirm page 1';"
},
{
"name": "page2",
"caption": "Page 2",
"items": [
{
"type": "Label",
"caption": "This is page 2, there is no 'Undo'. This is also the last page of the wizard."
}
],
"onConfirm": "echo 'Confirm page 2';"
}
]
}
}