Skip to content

jsonforms-renderers: dependent/cascading select control (filter options by a sibling field) #12

Description

@mushrafmim

Problem

There's no way to make one field's options depend on a sibling field's value — e.g. a "Manufacturer Email" dropdown that should only show emails belonging to whichever "Manufacturer Name" was just selected, inside the same array item.

This isn't specific to SelectControl — it's a gap in JSONForms itself. withJsonFormsControlProps resolves each control's schema prop once against the static JSON Schema document ($ref resolution only); it never re-evaluates if/then/allOf conditionals (or ajv's $data keyword) against the live form data to produce a new effective schema for rendering. Confirmed by reading SelectControl.tsx directly — it just does:

if (schema.enum) { options = schema.enum.map(...) }
else if (schema.oneOf) { options = schema.oneOf.map(...) }

So today, oneOf/enum is a fixed list regardless of what else is filled in on the form, even inside the same array item.

Motivating use case

one-trade-artifacts (CDA ASYCUDA kernel-product approval form): each kernel_products array entry has manufacturer_name (12 options) and manufacturer_email (38 options across all manufacturers). Right now the officer sees all 38 emails regardless of which manufacturer they picked, and has to know which ones are valid. It should filter down to just that manufacturer's emails once manufacturer_name is set.

Proposed approach (Option 1 from discussion — control reads sibling data itself)

JSONForms' React bindings expose a useJsonForms() hook giving access to the whole form's live core.data. A new control (or an extension to SelectControl) can use that plus its own path to look up a sibling field's current value at the same array index and filter its own oneOf accordingly. This is the right fix specifically because the dependency is per-array-item — an app-level "regenerate the whole schema on change" approach (the other common JSONForms workaround) doesn't work cleanly here since each kernel_products entry needs independently-filtered options.

Sketch of a schema convention

Extend the existing oneOf shape (matches how x-search/x-file already extend schemas in this package) rather than inventing a separate options-map:

{
  "manufacturer_email": {
    "type": "string",
    "x-depends-on": "manufacturer_name", // sibling property name, resolved relative to the same object (array item or otherwise)
    "oneOf": [
      { "const": "eoasorg@gmail.com", "title": "eoasorg@gmail.com", "x-group": "EOAS INTERNATIONAL PVT LTD" },
      { "const": "sampath@eoasorganics.com", "title": "sampath@eoasorganics.com", "x-group": "EOAS INTERNATIONAL PVT LTD" },
      { "const": "info@hddes.com", "title": "info@hddes.com", "x-group": "HDDES Extracts (Pvt) Ltd" }
      // ...
    ]
  }
}

A new DependentSelectControl (or SelectControl extended) would:

  1. Read schema['x-depends-on'] to get the sibling property name.
  2. Use useJsonForms() + the control's own path to resolve the sibling's current value at the same object/array-item level.
  3. Filter schema.oneOf to entries whose x-group matches that value (show none / a placeholder state if the sibling isn't set yet, or a disabled control until it is).
  4. Clear its own value if the previously-selected option is no longer in the filtered list once the sibling changes (similar to the existing useClearWhenHidden pattern used elsewhere in this package).

Open questions for whoever picks this up:

  • Exact schema keyword names (x-depends-on/x-group above are just a starting proposal).
  • Whether this should be a new tester+control, or a mode flag on the existing SelectControl.
  • Behavior when the sibling value has no matching group (empty vs. disabled vs. show-all).

References

  • packages/jsonforms-renderers/src/renderers/SelectControl.tsx — current static oneOf/enum handling.
  • packages/jsonforms-renderers/src/contexts/SearchServiceContext.tsx / SearchSelectControl.tsx — for reference on how this package has previously added an x-*-driven custom control.
  • packages/jsonforms-renderers/src/hooks/useClearWhenHidden.ts — existing precedent for a control clearing its own value based on external state changes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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