homebridge / homebridge-config-ui-x

The Homebridge UI. Monitor, configure and backup Homebridge from a browser.
https://homebridge.io
MIT License
2.63k stars 383 forks source link

Config fields get populated in JSON config even if not displayed #2208

Open justjam2013 opened 1 month ago

justjam2013 commented 1 month ago

Describe The Bug

When creating a config schema, you can use the condition property to show or hide a field based on the value of another field.

For example, let's say that I have an iPad that may or may not have cellular capability. In the config schema I add a required checkbox (boolean) field named hasCellular. Then I add a non-required textbox (string) field named phoneNumber, with condition "return model.devices[arrayIndices].hasCellular === true;"

    ...
    "hasCellular": {
        "title": "iPad Has Cellular Capabilities",
        "type": "boolean",
        "required": true
    },
    "phoneNumber": {
        "title": "Phone Number",
        "type": "string",
        "required": false,
        "condition": {
            "functionBody": "return model.devices[arrayIndices].hasCellular === true;"
        }
    },
    ...

In Config UI, I go ahead and configure in the Plugin Config window an iPad that has cellular:

Then I realize my mistake: this iPad does not have cellular capability! So I uncheck hasCellular and the the field phoneNumber is hidden. I click the Save button. If in Config UI, I go to Settings -> General -> JSON Config and look at the json, it will show:

  ...
  "hasCellular": false,
  "phoneNumber": "0123456789",
...

While this is a valid configuration per the schema, it logically makes no sense. My expectation would be that if the field phoneNumber is not displayed, then it is not part of the configuration of this device, therefore it would not appear in the json.

Logs

No response

Config

No response

Homebridge UI Version

4.62.0

Homebridge Version

1.8.4

Node.js Version

22.9.0

Operating System

macOS

Environment Info

Using hb-service

Raspberry Pi Model

None

justjam2013 commented 1 month ago

Update: After re-reading the issue, I realized that there are problems when the form has hidden fields.

To clarify:

Maybe this could be done by removing the fields from the DOM and then adding them back (minus the user entered values).

justjam2013 commented 1 month ago

Per the Angular JSON schema documentation, I have tried using dependencies in the json:

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "dependentRequired": {
    "foo": ["bar"]
  }
}

If the "foo" property is present, then the "bar" property is required. This did not work.

I tried using the onChange event:

  {
    "key": "name",
    "onChange": "alert(Hello!)"
  },

but this didn't work

I tried assigning a function to the onChange event:

  {
    "key": "text",
    "onChange": function (evt) {
      var value = $(evt.target).val();
      if (value) alert(value);
    }
  },

This caused the entire form to fail to display.

I have tried this with the current config-ui, using ajsf I checked out the demos for onChange for both ajsf and ng-formworks in the demo and playgrounds and neither worked.

donavanbecker commented 1 month ago

I don't thinking dependencies is implemented into the framework.

justjam2013 commented 1 month ago

You are right, they are not fully implemented:

  • Note: The contains and dependencies validators are still in development, and do not yet work correctly.
justjam2013 commented 2 weeks ago

Update: default and required can be handled dynamically.

If any user entered value is deleted when a field is dynamically hidden, then dynamically hidden field values will not be submitted by the form.

Addendum: dynamically hidden via

    "condition": {
        "functionBody": "return model.devices[arrayIndices].myfield === true;"
    }

as the author meant to add/remove fields from the form. This should not apply to expandable/collapsible sections