Cascading dropdowns returning only one value

Hi,

I have below custom render to select country and based on country the region. But when I get the data for the form, I only get {country: “Surrey”} {country: “TX”} , which is like property I registered this custom render for and region value. Can you please let me know how can I return both country and region value in data?

e.g. {country: “US”, region: “tx” }

import { withJsonFormsControlProps } from "@jsonforms/react";
import { ControlProps, rankWith, scopeEndsWith } from "@jsonforms/core";
import { Hidden } from "@material-ui/core";
import { Unwrapped } from "@jsonforms/material-renderers";
import { useState } from "react";
const { MaterialEnumControl } = Unwrapped;

export const CasDropdownTester = rankWith(1000, scopeEndsWith("country"));

const countryOptions = [
  { label: "USA", value: "US" },
  { label: "United Kingdon", value: "UK" },
];
const regionOptions = {
  US: [
    { label: "IOWA", value: "IOWA" },
    { label: "Texas", value: "TX" },
  ],
  UK: [
    { label: "Bedford", value: "Bedford" },
    { label: "Surrey", value: "Surrey" },
  ],
};

const CasDropdownRenderer = (props: ControlProps) => {
  const { visible } = props;
  const [regions, setRegions] = useState([]);
  const [country, setCountry] = useState<string>();
  const onCountryChanged = (path: string, value: string) => {
    setCountry(value);
    setRegions(regionOptions[value]);
  };
  return (
    <Hidden xsUp={!visible}>
      <MaterialEnumControl
        {...props}
        label={"Country"}
        options={countryOptions}
        handleChange={onCountryChanged}
        data={country}
      />

      <MaterialEnumControl {...props} label={"Region"} options={regions} />
    </Hidden>
  );
};

export default withJsonFormsControlProps(CasDropdownRenderer);

Hi @shridhar, the bindings will only resolve the data which corresponds to the control the renderer was invoked for. In your case this seems to be country. I don’t know for sure as I don’t know your schema / UI Schema.

There are two ways to solve this:

  • Restructure the data so they are contained by the same object. Then you can register a custom renderer for this object. As the object contains both entries, you can access both.
  • Access the data from your existing renderer. You can access the data of the whole form via
const ctx = useJsonForms();
const data = ctx.core.data;
  • In case you want to also change other parts of the data you can use the update action (Actions.update(path, () => newValue)) and dispatch via ctx.dispatch(youraction).

Thanks @sdirix for explanation.