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.

Hi Can you please explain this useJsonForms in brief I have tried to use it and ctx.core.data is returning an empty object

This is still the easiest way to access the form-wide state. Note that it’s only available within (custom) renderers. There is nothing special about it, so it should always work. If it doesn’t then something is fundamentally wrong in your setup.