Skip to content

Buttons broken in line mode #614

@lngr

Description

@lngr

I have the following object defined as a button:

javascript.0.gw18.toggle-garagentor

Image
{
         "_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:

Image
{
       "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.

Image

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:

Image

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.

Image Image
javascript.0 2026-03-31 14:17:04.816	info	script.js.gw18: Toggle Garagentor: true

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions