-
Notifications
You must be signed in to change notification settings - Fork 2.3k
fix: ui:emptyValue behavior #2457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -286,6 +288,22 @@ declare module '@rjsf/core' { | |||
|
|||
export module utils { | |||
|
|||
type UseEmptyValueOnChangeProps = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm definitely not super strong at typescript. If someone has a suggestion how to clean this up, it would be much appreciated.
@@ -14,7 +14,7 @@ | |||
"precommit": "lint-staged", | |||
"publish-to-npm": "npm run build && npm publish", | |||
"start": "concurrently \"npm:build:* -- --watch\"", | |||
"tdd": "cross-env NODE_ENV=test mocha --require @babel/register --watch --require ./test/setup-jsdom.js test/**/*_test.js", | |||
"tdd": "cross-env BABEL_ENV=test NODE_ENV=test mocha --require @babel/register --watch --require ./test/setup-jsdom.js test/**/*_test.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This command does not work without the BABEL_ENV
being set.
@@ -208,6 +208,21 @@ describe("StringField", () => { | |||
}); | |||
}); | |||
|
|||
it("should render ui:EmptyValue when formData is emptyString and ui:EmptyValue is defined", () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the most important test in this PR. The act(() => {})
gives the chance for the hook to run.
@@ -221,7 +236,7 @@ describe("StringField", () => { | |||
}); | |||
|
|||
sinon.assert.calledWithMatch(onChange.lastCall, { | |||
formData: undefined, | |||
formData: "", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These were previously undefined because options.emptyValue
was undefined. If the user enters the empty string, I believe we should call onChange
with the empty string.
@@ -7,6 +7,11 @@ import jsonpointer from "jsonpointer"; | |||
import fields from "./components/fields"; | |||
import widgets from "./components/widgets"; | |||
import validateFormData, { isValid } from "./validate"; | |||
import useEmptyValueOnChange from './hooks/useEmptyValueOnChange'; | |||
|
|||
export const hooks = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tacked the hooks onto the utils. If there is a better place, let me know.
return rawOnChange(newValue); | ||
}, [rawOnChange]); | ||
|
||
useEffect(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This useEffect takes care of the inital render state.
|
||
useEffect(() => { | ||
if (value === mergeValues(value)){ | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in this guard clause because I was seeing tests fail for onChange
getting called multiple times if the value wasn't empty.
Trying to understand why we need to change this though -- isn't populating data on the first form render what I think that when Maybe could you further explain your use case so we can see if this PR is the best solution or there is another alternative that may work better? |
@epicfaace default value does not work properly. Here is a a small example demonstrating it: I think default is the behavior I want. It wasn't documented and I only found the syntax in the playground. My use case is that when I initially render the form with empty data, I'd like to have certain fields have pre-populated values as defined in the schema. |
@ssbyoung can you share the issue with |
@epicfaace Can you take a look at the example I sent? I think there might be an issue with the consumer of this library using react 17 and this library using react 16. I'm also unsure how to modify the playground with the issue I'm seeing. |
I think you could make a codepen here (https://codepen.io/epicfaace/pen/WNjvBrb) and put in your desired versions of React / rjsf |
@epicfaace I'm having a hard time getting a codepen with [email protected]. Do you have an example with one that uses the latest version? |
@epicfaace is the playground https://rjsf-team.github.io/react-jsonschema-form/ running on version 3.0.0? |
Oh, I think codepens with v3 an issue because of #2447. Could you try using a codepen with the latest version of v2 instead? I'm guessing the issue will also appear in that version. |
@ssbyoung https://codepen.io/ssbyoung/pen/NWjdNjv?editors=1111 is a codepen showing this same issue. |
Hmm -- why is the original formData set to { prop1: undefined }? If you
just set formData to {}, then the default properly gets set.
…--
Ashwin Ramaswami
On Tue, Jul 13, 2021 at 1:02 PM Broderick Young ***@***.***> wrote:
@ssbyoung <https://github.com/ssbyoung>
https://codepen.io/ssbyoung/pen/NWjdNjv?editors=1111 is a codepen showing
this same issue.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2457 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAM4MX4AXAK5KZ2MREQPYXTTXRWSNANCNFSM47VKA6QQ>
.
|
As a consumer I'd expect all falsey values to to get replaced. Does it explicitly not have to be set in the object for the default to appear? |
@epicfaace after trying default with my code, the current implementation works as is. I will be closing this PR as well as the other one related to this change. |
Please note that this PR relies on #2456 being merged and released
Reasons for making this change
Fixes #2449
By default, if a form has a field with an empty string and
ui:emptyValue
is filled out, the empty value will not appear until the user interacts with the form. I believe that this is incorrect. This change makes it so thatui:emptyValue
will be populated on the first form render.I also refactored everywhere this logic lived to use a hook inside of @rjsf/core. Because it is a hook it requires the user to be on at least react 16.8.0, hence the need for #2456 . I also updated all the peer dependencies to 3.0.0. If PR #2456 goes through as a major version. All of these files will need to be updated.
Important Changes
ui:emptyValue
will be populated for empty form fieldsui:emptyValue
is not populated AND the user enters the empty stringonChange
will be called with the empty string instead of undefined.Checklist