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

Ds 447 build ds date field component input not updating correctly during on change validation #547

Conversation

LimeWub
Copy link
Contributor

@LimeWub LimeWub commented Jul 19, 2023

Edit: There was an additional problem with this field not updating in Forms correctly which Michal brought up (JIRA 2 link). I've reworked this PR to fix this problem and remove the original remounting hack introduced.

JIRA: https://atomlearningltd.atlassian.net/browse/DS-447
JIRA 2: https://atomlearningltd.atlassian.net/browse/DS-469

Basically the bug is that when the DateField is used in combination with validation, once we submit the form and we get to a state of validating onChange - typing in the Input field glitches out and eats the letters we are typing as well as backspaces etc.
From a day's worth of research/work it looks to me like this might be a bug within react-hook-form's validation logic - I have not exactly pinpointed where it is in their code though.

All I can tell is our onChange does not run when validation happens onChange (post submit) and the message is about to change. I did not find any github issues reporting on this - the closest I got was this stackoverflow ticket.

This is an attempt to fix the reported bug. It is an unorthodox method and kind of a hack - but I could not figure out the proper way to solve this. I'm assuming this is a bug or even expected functionality from react-hook-form. This sort of bug I'm also assuming affects any other field which relies on controlled value but is used with validation - perhaps particularly with a validation function.

Comments and alternative solutions are welcome.

Edit:
I changed the solution to trigger onChange on the input instead. Which solves the issue with the component not marking as dirty when observed via a Form's dirtyFields

Tested with sanbox

import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { reset } from 'stitches-reset'

import { Form, DateField, globalCss, InputField } from '../src'
import { DEFAULT_DATE_FORMAT } from '../src/components/date-input/constants'
import { TooltipProvider } from '@radix-ui/react-tooltip'

import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'
dayjs.extend(customParseFormat)

const formatDateToString = (date?: Date, dateFormat = DEFAULT_DATE_FORMAT) => date ? dayjs(date).format(dateFormat) : ''

globalCss({ ...reset, '*': { boxSizing: 'border-box' } })()

const App = () => {

  return (
    <TooltipProvider>
      <Form
        onSubmit={(data) => { console.log({ data }) }}
        validationMode={undefined}
        defaultValues={{
          'name': '',
          'exam-date': formatDateToString(new Date()),
        }}
        render={({ watch, formState }) => {
          console.log('dirtyFields', formState.dirtyFields)

          return (
            <>
              <InputField
                name={'name'}
                defaultValue=""
                validation={{
                  validate: (value) => {
                    if (value.length >= 2) {
                      return 'too long';
                    }
                    return true
                  }
                }}
              />
              <DateField name="exam-date" label="Exam date" validation={{
                validate: (value) => {
                  var now = new Date;
                  const d = value.slice(0, 2),
                    m = value.slice(3, 5),
                    y = value.slice(6, 10);
                  var target = new Date(y, m - 1, d);
                  console.log({ now, target })

                  if (target >= now) {
                    console.log('Date in the future!')
                    return 'in future';
                  }
                  return true
                }
              }} initialDate={new Date()} />
            </>
          )
        }}
      />
    </TooltipProvider >
  )
}

ReactDOM.render(<App />, document.getElementById('root'))

Videos

before

Screen.Recording.2023-07-19.at.12.12.01.mov

after

Screen.Recording.2023-08-23.at.16.09.03.mov

@LimeWub LimeWub added bug Something isn't working help wanted Extra attention is needed labels Jul 19, 2023
@LimeWub LimeWub marked this pull request as ready for review July 19, 2023 11:13
@LimeWub LimeWub self-assigned this Jul 25, 2023
@LimeWub LimeWub force-pushed the DS-447-build-ds-date-field-component-input-not-updating-correctly-during-on-change-validation branch from b42fcca to 9770fd1 Compare July 28, 2023 09:59
Copy link
Contributor

@michalrozenek michalrozenek left a comment

Choose a reason for hiding this comment

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

Honestly I am not 💯 to go this way because it looks hacky, but I am ok if you tested it properly if that works.

So, on the one hand - if it solves the problem, its' better than now. On the other hand it's hacky 🙂
Maybe we can merge it now and do more research + refactor working on isDirty issue.
Maybe it's more than small changes here, maybe complex refactor from scratch, dunno

@LimeWub LimeWub force-pushed the DS-447-build-ds-date-field-component-input-not-updating-correctly-during-on-change-validation branch from 9770fd1 to 3639f43 Compare August 23, 2023 15:12
@LimeWub
Copy link
Contributor Author

LimeWub commented Aug 23, 2023

I updated the solution for this (latest commit - the rest is a rebase). It's now both less hacky and fixes the issue with dirtyFields in Form not updating. Have a look. @michalrozenek @D7Torres

@LimeWub LimeWub force-pushed the DS-447-build-ds-date-field-component-input-not-updating-correctly-during-on-change-validation branch from 3639f43 to 87aa1ec Compare September 14, 2023 09:29
@LimeWub LimeWub merged commit 380c652 into main Sep 14, 2023
1 check passed
@LimeWub LimeWub deleted the DS-447-build-ds-date-field-component-input-not-updating-correctly-during-on-change-validation branch September 14, 2023 11:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants