react-jsonschema-form
react-jsonschema-form copied to clipboard
FormData Does Not Update on Change for Dependent Properties
Prerequisites
- [X] I have searched the existing issues
- [X] I understand that providing a SSCCE example is tremendously useful to the maintainers.
- [X] I have read the documentation
- [X] Ideally, I'm providing a sample JSFiddle, Codesandbox.io or preferably a shared playground link demonstrating the issue.
What theme are you using?
material-ui
Version
5.12.0
Current Behavior
I am struggling with a bug that seems inherent to the use of conditional logic to render different enum options for one property based on the value of a different property. In my current setup, essentially, property 1 = value 1 allows property 2 to have enum 1 or enum 2 while property 1 = value 2 only allows property 2 to have enum 2 . My default values are property 1 = value 1 and property 2 = enum 1.
The problem that I'm running into is that changing property 1's value to value 2 does not update property 2's value to enum 2 in the resulting formData (the form renders appropriately - it just doesn't match it's formData) and subsequently the field for property 2 acts basically as a read only field (i.e. selecting enum 2 - the only choice - from that dropdown doesn't update the formData value either).
I have created the schema using both if...then syntax and dependencies - both methods run into this same formData bug.
As this is an important feature for our company, if there is some way for us to sponsor this issue we would be happy to pay $250 to the developer responsible for its resolution.
Expected Behavior
When updating property 1's value (da) to enum 2 (DA 50) in the form, the field for property 2 (t) should update its corresponding formData value to the only available enum 2.
Steps To Reproduce
In this playground...
- Change the Domain Authority dropdown to "DA 50."
- Note that the Traffic dropdown now only shows one enum option ("Traffic 5,000") but the corresponding "Product\PackageDefinitions\LinkOutreach\DomainAuthorityAndTraffic::t" value in formData is still 1000.
- Also note that selecting "Traffic 5,000" from the Traffic dropdown does not update the formData either.
Environment
- OS: macOS Ventura 13.4.1 (c)
- Node: 20.4.0
- npm: 9.7.2
Anything else?
In this playground you can find an equivalent schema using "dependencies" rather than "if...then" syntax. It presents the same behavior - formData does not update for property 2 when property 1's value changes.
You can actually see this bug, or at least a simplified version of it, in the built-in examples on the playground - go to the playground, then pick the "If Then Else" button. Now, select "Fish" for animal, "worms" for food, "lake" for water. Then, change animal to "Cat". Notice the formData output still says:
{
"animal": "Cat",
"food": "worms",
"water": "lake"
}
which is invalid.
Similarly, if you go to the playground and go to the "If Then Else" example, but this time select the "Omit extra data" and "Live omit" options, then perform the same test (Fish, worms, lake, then Cat), you'll see that RJSF is at least removing the non-relevant key "water" from the formData, but still leaves an invalid value for "food" until one is selected:
{
"animal": "Cat",
"food": "worms"
}
I am not an expert in RJSF but I think it is user's responsibility to pass a consistent formData prop to Form component. You can use onChange event to set correct default value in formData when you select DA 50 in the form. At least this is what I do. I would be happy to listen from developers if there is a better way to do it.
@mahendrapaipuri it appears to be a bug as it even happens with the examples right in the playground. The issue is that the SelectWidget doesn't reset (or more accurately, un-set) it's value when the available options change
The most simple solution may be to just try to fix this for enums--if an enum field's set of enumerations no longer contains the current value, then reset that part of the formData to pick the default.
It could be more interesting/useful to fix the general case. If a data value no longer matches the current type (maybe my string field is now a number field), then reset that field with the default formData value.
It might be fairly complicated to build, because I don't think we have a mechanism to get the expected type of a property and validate the current type against it. I'm not sure if using the JSON Schema validator (AJV) would be appropriate for this purpose; I think you just want to clear and pick data with a valid type (or null), regardless of any complex validation criteria the schema may also include.
Any news?