I have the following object defined as a button:
javascript.0.gw18.toggle-garagentor
{
"_id": "javascript.0.gw18.toggle-garagentor",
"common": {
"name": "Toggle Garagentor",
"type": "boolean",
"role": "button",
"read": false,
"write": true
},
"native": {},
"type": "state",
"from": "system.adapter.javascript.0",
"user": "system.user.admin",
"ts": 1774957334533,
"acl": {
"object": 1636,
"state": 1636,
"owner": "system.user.admin",
"ownerGroup": "system.group.administrator"
}
}
It works when I click the button in the object tree.
However, there are two bugs with the button mode in vis2 material:
Bug 1: button detection is broken in auto mode
when defined like this:
{
"tpl": "tplMaterial2Switches",
"data": {
"count": "1",
"g_common": true,
"type": "lines",
"allSwitch": true,
"orientation": "horizontal",
"buttonsWidth": 100,
"buttonsHeight": 40,
"widgetTitle": "Garage",
"bindings": [],
"oid1": "javascript.0.gw18.toggle-garagentor",
"type1": "auto",
"title1": "Garagentor",
"noIcon1": null,
"icon1": null,
"iconSmall1": null,
"iconEnabled1": null,
"iconEnabledSmall1": null,
"color1": null,
"colorEnabled1": null,
"unit1": null,
"step1": null,
"hideChart1": null,
"buttonText1": null,
"buttonIcon1": null,
"buttonImage1": null,
"buttonIconActive1": null,
"buttonImageActive1": null,
"infoInactiveText1": null,
"infoActiveText1": null,
"infoInactiveIcon1": null,
"infoActiveIcon1": null,
"infoInactiveImage1": null,
"infoActiveImage1": null,
"infoInactiveColor1": null,
"infoActiveColor1": null,
"widget1": null,
"height1": null,
"position1": null,
"hide1": null,
"actual1": null,
"boost1": null,
"party1": null,
"switch1": null,
"brightness1": null,
"rgbType1": null,
"red1": null,
"green1": null,
"blue1": null,
"white1": null,
"color_temperature1": null,
"ct_min1": null,
"ct_max1": null,
"hue1": null,
"saturation1": null,
"luminance1": null,
"hideBrightness1": null,
"whiteMode1": null,
"noRgbPalette1": null,
"open1": null,
"working1": null,
"sensor1": null,
"pincode1": null,
"oid-pincode1": null,
"doNotConfirm1": null,
"noLockAnimation1": null,
"lockColor1": null,
"vacuum-status-oid1": null,
"vacuum-battery-oid1": null,
"vacuum-is-charging-oid1": null,
"vacuum-fan-speed-oid1": null,
"vacuum-sensors-left-oid1": null,
"vacuum-filter-left-oid1": null,
"vacuum-main-brush-left-oid1": null,
"vacuum-side-brush-left-oid1": null,
"vacuum-cleaning-count-oid1": null,
"vacuum-use-rooms1": null,
"vacuum-map64-oid1": null,
"vacuum-own-image1": null,
"vacuum-start-oid1": null,
"vacuum-home-oid1": null,
"vacuum-pause-oid1": null,
"undefined1": null,
"visibility-oid1": null,
"slideInvert1": null,
"chartPeriod1": 60,
"pincodeReturnButton1": "submit",
"timeout1": 500,
"vacuum-use-default-picture1": true,
"visibility-cond1": "==",
"visibility-val1": "1",
"g_switch-1": true
},
"style": {
"left": 0,
"top": 0,
"bindings": [],
"position": "relative"
},
"widgetSet": "vis-2-widgets-material"
}
It renders as a switch.
It does work, however, as seen in the following debug output:
javascript.0 2026-03-31 14:04:01.067 info script.js.gw18: Toggle Garagentor: true
javascript.0 2026-03-31 14:04:00.268 info script.js.gw18: Toggle Garagentor: false
Appearently the reason is this auto detection code, which can never reach the button case:
https://github.com/ioBroker/ioBroker.vis-2-widgets-material/blob/main/src-widgets/src/Switches.tsx#L1625-L1642
The auto-detection checks conditions in this order:
The "button" condition (type === 'boolean' && read === false) can never be reached because the switch condition (type === 'boolean' && write !== false) is checked first. For any boolean state:
- If
write === false => matches "info"
- If
write !== false (including true, null, undefined) => matches "switch"
- The
button check is therefore dead code
Expected behavior: A state with { type: 'boolean', role: 'button', read: false, write: true } should auto-detect as widgetType = 'button'.
Not sure what the correct fix is. Either swap the order (check button before switch) or introduce an additional check against common.role of the object state?
Bug 2: Button in lines mode uses onKeyDown/onKeyUp instead of onClick
When I manually specify the type as button:
Then nothing happens on click. Expected behavior: The button should also respond to touch/click events in lines mode.
However, if I use the keyboard and use TAB and SPACE key to manually trigger the button with keyboard keys, it works.
javascript.0 2026-03-31 14:14:24.845 info script.js.gw18: Toggle Garagentor: false
javascript.0 2026-03-31 14:14:23.262 info script.js.gw18: Toggle Garagentor: true
The reason seems to be the Button widget itself when in lines mode:
https://github.com/ioBroker/ioBroker.vis-2-widgets-material/blob/main/src-widgets/src/Switches.tsx#L2497-L2498
This only responds to keyboard events. On touchscreen and/or mouse devices), the button does nothing when activated. There is no onClick, onTouchStart, or onMouseDown handler.
In contrast, the same button type in buttons mode (renderButton, L2375) correctly uses onClick:
onClick={() => this.changeSwitch(index)}
Most notable, if I change the mode to buttons mode, the toggle works.
javascript.0 2026-03-31 14:17:04.816 info script.js.gw18: Toggle Garagentor: true
I have the following object defined as a button:
javascript.0.gw18.toggle-garagentorIt works when I click the button in the object tree.
However, there are two bugs with the button mode in vis2 material:
Bug 1:
buttondetection is broken inautomodewhen defined like this:
It renders as a switch.
It does work, however, as seen in the following debug output:
Appearently the reason is this auto detection code, which can never reach the
buttoncase:https://github.com/ioBroker/ioBroker.vis-2-widgets-material/blob/main/src-widgets/src/Switches.tsx#L1625-L1642
The auto-detection checks conditions in this order:
The "button" condition
(type === 'boolean' && read === false)can never be reached because theswitchcondition(type === 'boolean' && write !== false)is checked first. For any boolean state:write === false=> matches "info"write !== false(includingtrue,null,undefined) => matches "switch"buttoncheck is therefore dead codeExpected behavior: A state with { type: 'boolean', role: 'button', read: false, write: true } should auto-detect as widgetType = 'button'.
Not sure what the correct fix is. Either swap the order (check button before switch) or introduce an additional check against
common.roleof the object state?Bug 2: Button in
linesmode usesonKeyDown/onKeyUpinstead ofonClickWhen I manually specify the type as
button:Then nothing happens on click. Expected behavior: The button should also respond to touch/click events in lines mode.
However, if I use the keyboard and use
TABandSPACEkey to manually trigger the button with keyboard keys, it works.The reason seems to be the Button widget itself when in lines mode:
https://github.com/ioBroker/ioBroker.vis-2-widgets-material/blob/main/src-widgets/src/Switches.tsx#L2497-L2498
This only responds to keyboard events. On touchscreen and/or mouse devices), the button does nothing when activated. There is no
onClick,onTouchStart, oronMouseDownhandler.In contrast, the same button type in buttons mode (renderButton, L2375) correctly uses onClick:
Most notable, if I change the mode to buttons mode, the toggle works.