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:
A new DependentSelectControl (or SelectControl extended) would:
- Read
schema['x-depends-on'] to get the sibling property name.
- Use
useJsonForms() + the control's own path to resolve the sibling's current value at the same object/array-item level.
- 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).
- 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.
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.withJsonFormsControlPropsresolves each control'sschemaprop once against the static JSON Schema document ($refresolution only); it never re-evaluatesif/then/allOfconditionals (or ajv's$datakeyword) against the live form data to produce a new effective schema for rendering. Confirmed by readingSelectControl.tsxdirectly — it just does:So today,
oneOf/enumis 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): eachkernel_productsarray entry hasmanufacturer_name(12 options) andmanufacturer_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 oncemanufacturer_nameis 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 livecore.data. A new control (or an extension toSelectControl) can use that plus its ownpathto look up a sibling field's current value at the same array index and filter its ownoneOfaccordingly. 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 eachkernel_productsentry needs independently-filtered options.Sketch of a schema convention
Extend the existing
oneOfshape (matches howx-search/x-filealready 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(orSelectControlextended) would:schema['x-depends-on']to get the sibling property name.useJsonForms()+ the control's ownpathto resolve the sibling's current value at the same object/array-item level.schema.oneOfto entries whosex-groupmatches that value (show none / a placeholder state if the sibling isn't set yet, or a disabled control until it is).useClearWhenHiddenpattern used elsewhere in this package).Open questions for whoever picks this up:
x-depends-on/x-groupabove are just a starting proposal).SelectControl.References
packages/jsonforms-renderers/src/renderers/SelectControl.tsx— current staticoneOf/enumhandling.packages/jsonforms-renderers/src/contexts/SearchServiceContext.tsx/SearchSelectControl.tsx— for reference on how this package has previously added anx-*-driven custom control.packages/jsonforms-renderers/src/hooks/useClearWhenHidden.ts— existing precedent for a control clearing its own value based on external state changes.