Is there any way of showing options in one selector based on choose in another one?

I have two properties “select1” and “select2”:

{
  "type": "object",
  "properties": {
    "select1": {
      "type": "object",
      "title": "Select1",
      "oneOf": [
        {
          "const": {
            "name": "select1_option1",
            "title": "Select1_Option1"
          }
        },
        {
          "const": {
            "name": "select1_option2",
            "title": "Select1_Option2"
          }
        }
      ]
    },
    "select2": {
      "type": "object",
      "title": "Select2",
      "oneOf": [
        {
          "const": {
            "name": "select2_option1",
            "title": "Select2_Option1"
          }
        },
        {
          "const": {
            "name": "select2_option2",
            "title": "Select2_Option2"
          }
        },
        {
          "const": {
            "name": "select2_option3",
            "title": "Select2_Option3"
          }
        }
      ]
    }
  }
}

So I want my “select2” to show only options corresponding to the selection from another select.
e.g. property “select1” is now

{
    "name": "select1_option1",
    "title": "Select1_Option1"
}

and the select2 can be (and show) only

{
    "const": {
        "name": "select2_option1",
        "title": "Select2_Option1"
      }
},
{
    "const": {
        "name": "select2_option2",
        "title": "Select2_Option2"
      }
}

but not

{
    "const": {
        "name": "select2_option3",
        "title": "Select2_Option3"
      }
}

is there any way to make it work as I want :frowning:

Hi @dartalex969,

In general there is no support in JSON Schema to refer to other instance values. In this simple example you could express what you want in JSON Schema by modeling only the valid options, i.e. a oneOf wrapping both your properties and only allowing valid combinations, e.g.

{
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "select1": {
          "type": "object",
          "title": "Select1",
          "const": {
            "name": "select1_option1",
            "title": "Select1_Option1"
          }
        },
        "select2": {
          "type": "object",
          "title": "Select2",
          "oneOf": [
            {
              "const": {
                "name": "select2_option1",
                "title": "Select2_Option1"
              }
            },
            {
              "const": {
                "name": "select2_option2",
                "title": "Select2_Option2"
              }
            }
          ]
        }
      }
    },
    {
      "type": "object",
      "properties": {
        "select1": {
          "type": "object",
          "title": "Select1",
          "const": {
            "name": "select1_option2",
            "title": "Select1_Option2"
          }
        },
        "select2": {
          "type": "object",
          "title": "Select2",
          "oneOf": [
            {
              "const": {
                "name": "select2_option2",
                "title": "Select2_Option2"
              }
            },
            {
              "const": {
                "name": "select2_option3",
                "title": "Select2_Option3"
              }
            }
          ]
        }
      }
    }
  ]
}

However the UI for this will by default not be nice to use as our support for generic oneOf only comes with a generic basic UI. So for a good usability you would then need to create a custom renderer for this.

If you are not required to express your valid selections via JSON Schema but are fine with coding them into the UI then you can just create a custom renderer for the second property of your original schema. This custom renderer can just reuse our existing oneOfEnum renderer but filter the options accordingly to the current selection in the other control.


Unrelated to the issue at hand, but you probably don’t want to place the title property into the const but rather outside of it.

1 Like