rjsf-team / react-jsonschema-form

A React component for building Web forms from JSON Schema.
https://rjsf-team.github.io/react-jsonschema-form/
Apache License 2.0
14.33k stars 2.19k forks source link

Issue using oneof #4050

Open harrydoddnoble opened 9 months ago

harrydoddnoble commented 9 months ago

Prerequisites

What theme are you using?

core

Version

5.x

Current Behavior

I am using the following JSON with oneof:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "activityChoice": {
      "type": "string",
      "title": "Do you want to ski or swim?",
      "enum": [
        "ski",
        "swim"
      ],
      "piqRef": "Question 1"
    }
  },
  "required": [
    "activityChoice"
  ],
  "oneOf": [
    {
      "properties": {
        "activityChoice": {
          "const": "swim"
        },
        "swimTrunksColor": {
          "type": "string",
          "title": "What colour swimming trunks do you want?",
          "piqRef": "Question 2"
        }
      },
      "required": [
        "swimTrunksColor"
      ]
    },
    {
      "properties": {
        "activityChoice": {
          "const": "ski"
        },
        "skiLength": {
          "type": "number",
          "title": "What length skis do you want?",
          "piqRef": "Question 3"
        }
      },
      "required": [
        "skiLength"
      ]
    }
  ]
}

While the logic works on the playground but it also shows the drop down saying Option 1 and Option 2, and it also has an extra text box called activityChoice -

image

Expected Behavior

it should really just show the second text box question (the ski size or swimming trunks colour) depending on which option you select. Anyone able to advise on why this would happen? I can create a if-then-else but I already have a full schema so this isn't really an option.

Steps To Reproduce

No response

Environment

- OS:
- Node:
- npm:

Anything else?

No response

nickgros commented 9 months ago

@harrydoddnoble RJSF has no way of knowing that you discriminator on each oneOf field using that constant value. One change you could make is to give each of your oneOf schemas a title, and then use the UI Schema to hide the field that you don't want to show.

Here's a playground example.

harrydoddnoble commented 9 months ago

Amazing. Will check this out - thank you!

On Fri, 19 Jan 2024, 20:00 Nick Grosenbacher, @.***> wrote:

@harrydoddnoble https://github.com/harrydoddnoble RJSF has no way of knowing that you discriminator on each oneOf field using that constant value. One change you could make is to give each of your oneOf schemas a title, and then use the UI Schema to hide the field that you don't want to show.

Here's a playground example. https://rjsf-team.github.io/react-jsonschema-form/#eyJmb3JtRGF0YSI6eyJzd2ltVHJ1bmtzQ29sb3IiOiJmIiwiYWN0aXZpdHlDaG9pY2UiOiJmIn0sInNjaGVtYSI6eyIkc2NoZW1hIjoiaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjIiwidHlwZSI6Im9iamVjdCIsInByb3BlcnRpZXMiOnsiYWN0aXZpdHlDaG9pY2UiOnsidHlwZSI6InN0cmluZyIsInRpdGxlIjoiRG8geW91IHdhbnQgdG8gc2tpIG9yIHN3aW0/IiwiZW51bSI6WyJza2kiLCJzd2ltIl0sInBpcVJlZiI6IlF1ZXN0aW9uIDEifX0sInJlcXVpcmVkIjpbImFjdGl2aXR5Q2hvaWNlIl0sIm9uZU9mIjpbeyJ0aXRsZSI6InN3aW0iLCJwcm9wZXJ0aWVzIjp7ImFjdGl2aXR5Q2hvaWNlIjp7ImNvbnN0Ijoic3dpbSJ9LCJzd2ltVHJ1bmtzQ29sb3IiOnsidHlwZSI6InN0cmluZyIsInRpdGxlIjoiV2hhdCBjb2xvdXIgc3dpbW1pbmcgdHJ1bmtzIGRvIHlvdSB3YW50PyIsInBpcVJlZiI6IlF1ZXN0aW9uIDIifX0sInJlcXVpcmVkIjpbInN3aW1UcnVua3NDb2xvciJdfSx7InRpdGxlIjoic2tpIiwicHJvcGVydGllcyI6eyJhY3Rpdml0eUNob2ljZSI6eyJjb25zdCI6InNraSJ9LCJza2lMZW5ndGgiOnsidHlwZSI6Im51bWJlciIsInRpdGxlIjoiV2hhdCBsZW5ndGggc2tpcyBkbyB5b3Ugd2FudD8iLCJwaXFSZWYiOiJRdWVzdGlvbiAzIn19LCJyZXF1aXJlZCI6WyJza2lMZW5ndGgiXX1dfSwidWlTY2hlbWEiOnsiYWN0aXZpdHlDaG9pY2UiOnsidWk6d2lkZ2V0IjoiaGlkZGVuIn19LCJ0aGVtZSI6ImRlZmF1bHQiLCJsaXZlU2V0dGluZ3MiOnt9fQ==

— Reply to this email directly, view it on GitHub https://github.com/rjsf-team/react-jsonschema-form/issues/4050#issuecomment-1901028605, or unsubscribe https://github.com/notifications/unsubscribe-auth/A3HHMST3OWU2GAFDC4DHNLDYPLGGVAVCNFSM6AAAAABCAWNFMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMBRGAZDQNRQGU . You are receiving this because you were mentioned.Message ID: @.***>

harrydoddnoble commented 9 months ago

Aah I'm still struggling a bit with this one - with the given solution you lose the title of the ski/swim question. I'm also working with an existing JSON schema and I'm not sure I understand how to get this to work properly.. any help/ideas would be very welcome!

In the example below you are asked if you insure the property and there is some logic after that - it generally works from a logic point of view but the UI is quite confusing so I'm not sure what I need to change to correct it.

image
{
  "properties": {
    "insurance": {
      "baspiRef": "A8",
      "ta6Ref": "6",
      "title": "Insurance",
      "type": "object",
      "baspiRequired": [
        "isInsured"
      ],
      "ta6Required": [
        "isInsured"
      ],
      "properties": {
        "isInsured": {
          "baspiRef": "A8.1",
          "rdsRef": "Insurance/isInsured=no|yes|true|false",
          "ta6Ref": "6.1",
          "piqRef": "A8.2",
          "title": "Do you insure the property?",
          "type": "string",
          "enum": [
            "Yes",
            "No"
          ]
        }
      },
      "discriminator": {
        "propertyName": "isInsured"
      },
      "oneOf": [
        {
          "properties": {
            "isInsured": {
              "enum": [
                "No"
              ]
            },
            "details": {
              "baspiRef": "A8.1.1",
              "ta6Ref": "6.2",
              "title": "Why not?",
              "type": "string",
              "minLength": 1
            },
            "landlordInsuresIfFlat": {
              "baspiRef": "A8.1.2",
              "ta6Ref": "6.3",
              "title": "If the property is a flat, does the landlord insure the building?",
              "type": "string",
              "enum": [
                "Yes",
                "No",
                "Not applicable"
              ]
            }
          },
          "baspiRequired": [
            "details",
            "landlordInsuresIfFlat"
          ],
          "ta6Required": [
            "details",
            "landlordInsuresIfFlat"
          ]
        },
        {
          "properties": {
            "isInsured": {
              "enum": [
                "Yes"
              ]
            },
            "difficultiesObtainingInsurance": {
              "baspiRef": "A8.1.2.1",
              "rdsRef": "Insurance/Flags,Insurance/refusalReason=?",
              "ta6Ref": "6.4",
              "piqRef": "A8.1",
              "title": "Have you had any difficulty obtaining competitively priced building insurance due to the structure or location of the property or had insurance refused?",
              "type": "object",
              "baspiRequired": [
                "abnormalRiseInPremiums",
                "subjectToHighExcesses",
                "subjectToUnusualConditions",
                "refused"
              ],
              "ta6Required": [
                "abnormalRiseInPremiums",
                "subjectToHighExcesses",
                "subjectToUnusualConditions",
                "refused"
              ],
              "properties": {
                "abnormalRiseInPremiums": {
                  "baspiRef": "A8.1.2.1.1",
                  "ta6Ref": "6.4a",
                  "piqRef": "A8.1a",
                  "title": "Subject to abnormal rise in premiums?",
                  "type": "object",
                  "properties": {
                    "yesNo": {
                      "baspiRef": "A8.1.2.1.1.1",
                      "ta6Ref": "6.4a1",
                      "piqRef": "A8.1a1",
                      "type": "string",
                      "title": "",
                      "enum": [
                        "Yes",
                        "No"
                      ]
                    }
                  },
                  "baspiRequired": [
                    "yesNo"
                  ],
                  "ta6Required": [
                    "yesNo"
                  ],
                  "discriminator": {
                    "propertyName": "yesNo"
                  },
                  "oneOf": [
                    {
                      "properties": {
                        "yesNo": {
                          "enum": [
                            "No"
                          ]
                        }
                      }
                    },
                    {
                      "properties": {
                        "yesNo": {
                          "enum": [
                            "Yes"
                          ]
                        },
                        "details": {
                          "baspiRef": "A8.1.2.1.1.2",
                          "ta6Ref": "6.4.2",
                          "piqRef": "A8.1a1.1",
                          "title": "Provide details",
                          "type": "string",
                          "minLength": 1
                        }
                      },
                      "baspiRequired": [
                        "details"
                      ],
                      "ta6Required": [
                        "details"
                      ]
                    }
                  ]
                },
                "subjectToHighExcesses": {
                  "baspiRef": "A8.1.2.1.2",
                  "ta6Ref": "6.4b",
                  "piqRef": "A8.1b",
                  "title": "Subject to high excesses?",
                  "type": "object",
                  "properties": {
                    "yesNo": {
                      "baspiRef": "A8.1.2.1.2.1",
                      "ta6Ref": "6.4b1",
                      "piqRef": "A8.1b1",
                      "type": "string",
                      "title": "",
                      "enum": [
                        "Yes",
                        "No"
                      ]
                    }
                  },
                  "baspiRequired": [
                    "yesNo"
                  ],
                  "ta6Required": [
                    "yesNo"
                  ],
                  "discriminator": {
                    "propertyName": "yesNo"
                  },
                  "oneOf": [
                    {
                      "properties": {
                        "yesNo": {
                          "enum": [
                            "No"
                          ]
                        }
                      }
                    },
                    {
                      "properties": {
                        "yesNo": {
                          "enum": [
                            "Yes"
                          ]
                        },
                        "details": {
                          "baspiRef": "A8.1.2.1.2.2",
                          "ta6Ref": "6.4.2",
                          "piqRef": "A8.1b2",
                          "title": "Provide details",
                          "type": "string",
                          "minLength": 1
                        }
                      },
                      "baspiRequired": [
                        "details"
                      ],
                      "ta6Required": [
                        "details"
                      ]
                    }
                  ]
                },
                "subjectToUnusualConditions": {
                  "baspiRef": "A8.1.2.1.3",
                  "ta6Ref": "6.4c",
                  "piqRef": "A8.1c",
                  "title": "Subject to unusual conditions?",
                  "type": "object",
                  "properties": {
                    "yesNo": {
                      "baspiRef": "A8.1.2.1.3.1",
                      "ta6Ref": "6.4c1",
                      "piqRef": "A8.1c1",
                      "type": "string",
                      "title": "",
                      "enum": [
                        "Yes",
                        "No"
                      ]
                    }
                  },
                  "baspiRequired": [
                    "yesNo"
                  ],
                  "ta6Required": [
                    "yesNo"
                  ],
                  "discriminator": {
                    "propertyName": "yesNo"
                  },
                  "oneOf": [
                    {
                      "properties": {
                        "yesNo": {
                          "enum": [
                            "No"
                          ]
                        }
                      }
                    },
                    {
                      "properties": {
                        "yesNo": {
                          "enum": [
                            "Yes"
                          ]
                        },
                        "details": {
                          "baspiRef": "A8.1.2.1.3.2",
                          "ta6Ref": "6.4.2",
                          "piqRef": "A8.1c2",
                          "title": "Provide details",
                          "type": "string",
                          "minLength": 1
                        }
                      },
                      "baspiRequired": [
                        "details"
                      ],
                      "ta6Required": [
                        "details"
                      ]
                    }
                  ]
                },
                "refused": {
                  "baspiRef": "A8.1.2.1.4",
                  "ta6Ref": "6.4d",
                  "piqRef": "A8.1d",
                  "title": "Refused?",
                  "type": "object",
                  "properties": {
                    "yesNo": {
                      "baspiRef": "A8.1.2.1.4.1",
                      "ta6Ref": "6.4d1",
                      "piqRef": "A8.1d1",
                      "type": "string",
                      "title": "",
                      "enum": [
                        "Yes",
                        "No"
                      ]
                    }
                  },
                  "baspiRequired": [
                    "yesNo"
                  ],
                  "ta6Required": [
                    "yesNo"
                  ],
                  "discriminator": {
                    "propertyName": "yesNo"
                  },
                  "oneOf": [
                    {
                      "properties": {
                        "yesNo": {
                          "enum": [
                            "No"
                          ]
                        }
                      }
                    },
                    {
                      "properties": {
                        "yesNo": {
                          "enum": [
                            "Yes"
                          ]
                        },
                        "details": {
                          "baspiRef": "A8.1.2.1.4.2",
                          "ta6Ref": "6.4.2",
                          "piqRef": "A8.1d2",
                          "title": "Provide details",
                          "type": "string",
                          "minLength": 1
                        }
                      },
                      "baspiRequired": [
                        "details"
                      ],
                      "ta6Required": [
                        "details"
                      ]
                    }
                  ]
                }
              }
            },
            "insuranceClaims": {
              "baspiRef": "A8.2",
              "rdsRef": "Insurance/Claims",
              "ta6Ref": "6.5",
              "title": "Have you ever made a claim against your building insurance in relation to the property?",
              "type": "object",
              "properties": {
                "yesNo": {
                  "baspiRef": "A8.2.1",
                  "ta6Ref": "6.5.1",
                  "type": "string",
                  "title": "",
                  "enum": [
                    "Yes",
                    "No"
                  ]
                }
              },
              "baspiRequired": [
                "yesNo"
              ],
              "ta6Required": [
                "yesNo"
              ],
              "discriminator": {
                "propertyName": "yesNo"
              },
              "oneOf": [
                {
                  "properties": {
                    "yesNo": {
                      "enum": [
                        "No"
                      ]
                    }
                  }
                },
                {
                  "properties": {
                    "yesNo": {
                      "enum": [
                        "Yes"
                      ]
                    },
                    "details": {
                      "baspiRef": "A8.2.1",
                      "ta6Ref": "6.5.2",
                      "title": "Provide details",
                      "type": "string",
                      "minLength": 1
                    }
                  },
                  "baspiRequired": [
                    "details"
                  ],
                  "ta6Required": [
                    "details"
                  ]
                }
              ]
            }
          },
          "baspiRequired": [
            "difficultiesObtainingInsurance",
            "insuranceClaims"
          ],
          "ta6Required": [
            "difficultiesObtainingInsurance",
            "insuranceClaims"
          ]
        }
      ]
    }
  }
}
nickgros commented 9 months ago

You might be able to accomplish what you want with the uiSchema when we release a new version of RJSF that includes #4055

I spent a few minutes looking at your schema and was a bit overwhelmed. What you are trying to do is really best served by conditional logic in schemas. You said you can't use if/then/else, but could you use dependencies? This is another tool that you can use to implement conditional logic in your JSON Schema.

harrydoddnoble commented 9 months ago

It's an open source schema https://github.com/Property-Data-Trust-Framework/schemas/blob/master/src/schemas/v2/combined.json that we use so it's tricky to make too many changes - we could look at creating a script to run some transformations but obviously there is then a risk that as things change on the main schema things break our end! From a logic point of view everything currently works, eg. it shows the relevant fields when Yes/No is selected but it also shows duplications of the questions.

On Tue, 23 Jan 2024 at 00:23, Nick Grosenbacher @.***> wrote:

You might be able to accomplish what you want with the uiSchema when we release a new version of RJSF that includes #4055 https://github.com/rjsf-team/react-jsonschema-form/pull/4055

I spent a few minutes looking at your schema and was a bit overwhelmed. What you are trying to do is really best served by conditional logic in schemas. You said you can't use if/then/else, but could you use dependencies https://rjsf-team.github.io/react-jsonschema-form/docs/json-schema/dependencies#schema-dependencies? This is another tool that you can use to implement conditional logic in your JSON Schema.

— Reply to this email directly, view it on GitHub https://github.com/rjsf-team/react-jsonschema-form/issues/4050#issuecomment-1905070871, or unsubscribe https://github.com/notifications/unsubscribe-auth/A3HHMSW7TFG7BRY3INTRHXLYP37IXAVCNFSM6AAAAABCAWNFMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMBVGA3TAOBXGE . You are receiving this because you were mentioned.Message ID: @.***>

codisfy commented 9 months ago

You might be able to accomplish what you want with the uiSchema when we release a new version of RJSF that includes https://github.com/rjsf-team/react-jsonschema-form/pull/4055

@nickgros Do you know when will the next release be? I pulled a lot of hair today finally to realize that anyOf/oneOf on UISchema needed some updates and hasn't made to the release.

nickgros commented 9 months ago

@codisfy We released 5.17.0 yesterday, so you should be able to try out the new uiSchema functionality now

nickgros commented 9 months ago

@harrydoddnoble now that #4055 was added to 5.17.0, are you able to use the uiSchema to achieve your desired behavior?

harrydoddnoble commented 9 months ago

We are just updating the schema and then will try. It does appear to work with the logic but I'm still not quite sure how to hide the duplicated fields.

On Fri, 2 Feb 2024 at 15:22, Nick Grosenbacher @.***> wrote:

@harrydoddnoble https://github.com/harrydoddnoble now that #4055 https://github.com/rjsf-team/react-jsonschema-form/pull/4055 was added to 5.17.0, are you able to use the uiSchema to achieve your desired behavior?

— Reply to this email directly, view it on GitHub https://github.com/rjsf-team/react-jsonschema-form/issues/4050#issuecomment-1924092798, or unsubscribe https://github.com/notifications/unsubscribe-auth/A3HHMSV7WURL7A5VRSQVIK3YRUAETAVCNFSM6AAAAABCAWNFMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMRUGA4TENZZHA . You are receiving this because you were mentioned.Message ID: @.***>