Skip to content
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

Fix/datepicker validation #2200

Merged
merged 1 commit into from
Jan 22, 2024

Conversation

LukasBoll
Copy link
Contributor

@LukasBoll LukasBoll commented Oct 27, 2023

Previously, data wasn't cleared when the input field was emptied.
This commit will set the value to 'undefined' when the input is empty or
invalid upon blurring. During editing, the data is only updated when the
current input is valid.

Closes #2183

@netlify
Copy link

netlify bot commented Oct 27, 2023

Deploy Preview for jsonforms-examples ready!

Name Link
🔨 Latest commit 6e5cffe
🔍 Latest deploy log https://app.netlify.com/sites/jsonforms-examples/deploys/659d81d9f1d18b0008205ff4
😎 Deploy Preview https://deploy-preview-2200--jsonforms-examples.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@LukasBoll LukasBoll changed the title Fix/datepicker validation WIP: Fix/datepicker validation Oct 31, 2023
@coveralls
Copy link

coveralls commented Oct 31, 2023

Coverage Status

coverage: 84.82% (+0.03%) from 84.795%
when pulling 6e5cffe on LukasBoll:fix/datepicker_validation
into c8d3ecf on eclipsesource:master.

@sdirix
Copy link
Member

sdirix commented Oct 31, 2023

New behavior:

  • During editing, when value is a valid date/time, immediately write through
  • During editing, when value is not valid, don't trigger any change
  • On blur, if value is not valid, write undefined in data

@LukasBoll LukasBoll changed the title WIP: Fix/datepicker validation Fix/datepicker validation Nov 6, 2023
@LukasBoll LukasBoll changed the title Fix/datepicker validation WIP: Fix/datepicker validation Nov 7, 2023
@LukasBoll LukasBoll changed the title WIP: Fix/datepicker validation Fix/datepicker validation Nov 7, 2023
Copy link
Member

@sdirix sdirix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In principal looks good, however I found some issues in the code. Please also test the exceptional cases for which we require all that custom blur update handling.

Comment on lines 84 to 86
const updateChild = () => {
setKey(key + 1);
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whenever the new value of a state depends on the old value, the functional updater should be used, i.e. const updateChild = () => setKey((key) => key + 1)

Comment on lines 93 to 103
const onBlur = useMemo(
() =>
createOnBlurHandler(path, handleChange, format, saveFormat, updateChild),
[path, handleChange, format, saveFormat, updateChild]
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This useMemo will never work as updateChild is a new instance on every render call, therefore always breaking the memo.

@@ -62,6 +67,8 @@ export const MaterialDateControl = (props: ControlProps) => {
appliedUiSchemaOptions.showUnfocusedDescription
);

const [key, setKey] = useState<any>(0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid any at all cost and only use it when there is no better way. Here we can just type as number.

@@ -66,6 +71,8 @@ export const MaterialDateTimeControl = (props: ControlProps) => {
const format = appliedUiSchemaOptions.dateTimeFormat ?? 'YYYY-MM-DD HH:mm';
const saveFormat = appliedUiSchemaOptions.dateTimeSaveFormat ?? undefined;

const [key, setKey] = useState<any>(0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The key here is never used

@@ -56,6 +61,8 @@ export const MaterialTimeControl = (props: ControlProps) => {
const appliedUiSchemaOptions = merge({}, config, uischema.options);
const isValid = errors.length === 0;

const [key, setKey] = useState<any>(0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The key here is never used


export const MaterialDateControl = (props: ControlProps) => {
const [focused, onFocus, onBlur] = useFocus();
const [focused, onFocus] = useFocus();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We lose the focus handling of useFocus here, i.e. it expects that onBlur is called at some point to remove the focus. Shouldn't we call the onBlur here in our custom onBlur?

Copy link
Member

@sdirix sdirix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one minor change request regarding the naming. besides that, look's good!

format: string | undefined,
saveFormat: string | undefined,
rerenderChild: () => void,
resetFocus: () => void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method does not care why this callback is handed over. The parameter should be called onBlur or callback

@@ -75,16 +82,32 @@ export const MaterialTimeControl = (props: ControlProps) => {
: null;
const secondFormHelperText = showDescription && !isValid ? errors : null;

const updateChild = useCallback(() => setKey((key) => key + 1), [setKey]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically setKey is not required to be in the dependency list as it's guaranteed to be stable by React, however adding it doesn't break anything.

Copy link
Member

@sdirix sdirix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is still some error lurking. To reproduce:

  1. Open the React Material Ui example application (link)
  2. Into the birthDate field, enter the year 900. Observe that the data is not updated as intended because this year is invalid
  3. Blur the field, e.g. by clicking into another one
  4. Observe that the field is now empty, however the invalid date was saved into the data
  5. Refocus the field and blur it again
  6. Now the invalid date is actually removed from the data

Expected behavior:
After executing steps 1-3, the field and the actual data should be empty.

DateErrors

@sdirix sdirix force-pushed the master branch 2 times, most recently from 8bd14c2 to e9946ef Compare December 15, 2023 16:07
@LukasBoll LukasBoll force-pushed the fix/datepicker_validation branch 3 times, most recently from 67e6bdb to 81fece1 Compare December 20, 2023 11:24
@LukasBoll
Copy link
Contributor Author

Hi @sdirix ,
this commit will change the default format of datetime to "YYYY-MM-DDTHH:mm:ss.sssZ," making it coherent with convertDateToString wich is used for createDefaultValue in the core.
The previous default format was the default format from dayjs (current date in ISO8601, without fraction seconds, e.g. '2020-04-02T08:02:17-05:00')
Is this fine or should we keep the old default format?

@sdirix
Copy link
Member

sdirix commented Dec 20, 2023

Is this fine or should we keep the old default format?

This is fine as sss is also valid ISO8601

Comment on lines 74 to +75
const format = appliedUiSchemaOptions.timeFormat ?? 'HH:mm';
const saveFormat = appliedUiSchemaOptions.timeSaveFormat ?? 'HH:mm:ss';
const saveFormat = appliedUiSchemaOptions.timeSaveFormat ?? defaultTimeFormat;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a time is missing the seconds, the UI now doesn't show it anymore. See the dates example. Is there a way to still show it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous implementation didn’t support formats without seconds by default. So this wouldn't be an unexpected/new behavior.
Currently I adjusted the examples in our application to use the HH:mm:ss format.
But it is also possible to check if the time-value uses the HH:mm:ss or HH:mm format and set the saveFormat accordingly. Would you prefer this solution?

Comment on lines 45 to 46
// Workaround to address a bug in Dayjs (https://github.com/iamkun/dayjs/issues/1849)
if (date.year() < 1000 && date.year() > 100) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests for this. Also we should handle the range from `[0-100].

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dayjs currently doesn't support years < 100, but I adjusted the code (+ tests) so these cases are also handled, in case dayjs will support them in the future.

Previously, data wasn't cleared when the input field was emptied.
This commit will set the value to 'undefined' when the input is empty or
invalid upon blurring. During editing, the data is only updated when the
current input is valid.

Closes eclipsesource#2183
Copy link
Member

@sdirix sdirix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks

@sdirix sdirix merged commit 01b08f0 into eclipsesource:master Jan 22, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Date Picker Validation
3 participants