1

I am trying to create react-datepicker component with custom styled input:

<DatePicker
        selected={startDate}
        customInput={<CustomInput inputRef={inputRef} />}
        onChangeRaw={(e) => handleChangeRaw(e)}
        onChange={(date: Date | null) => {
          setStartDate(date);
        }}
      />

const CustomInput = forwardRef((props: any, ref) => {
  return <Input {...props} ref={ref} />;
});

I wanted to introduce validation (just simple validation that whatever user inputs will be formatted to the date so user cannot just type whatever he wants).

I created a function that would be formatting the input using onChangeRaw attribute in react-datepicker:

  const handleChangeRaw = (date) => {
    date.currentTarget.value = format(startDate, "dd/MM/yyyy");
  };

However after using this I cannot type anymore. Anyone has idea how to use manual typing with custom input in react-datepicker with simple validation function?

Here is recreated issue in the sandbox: https://codesandbox.io/s/react-datepicker-custominput-sample-forked-elx310?file=/src/App.tsx

Alex T
  • 3,529
  • 12
  • 56
  • 105

2 Answers2

1
selected={startDate}

Here react-datepicker expects a Date object.

However, when you trigger handleChangeRaw, you get an change event, with some value (date.currentTarget.value), but thats not in the Date notation that datepicker expects.

So my take on this would be;

  • onChangeRaw, convert the input value to a new Date.
  • If the date isn't valid, just ignore the change
  • Otherwise, create a new Date, and use setStartDate to change to that new date
const handleChangeRaw = (date) => {
      const newRaw = new Date(date.currentTarget.value);
      if (newRaw instanceof Date && !isNaN(newRaw)) {
        setStartDate(newRaw);
      }
  };

Try it online

0stone0
  • 34,288
  • 4
  • 39
  • 64
  • I added one more validation condition to your function and even tough validation should be failing it allows for the change: https://codesandbox.io/s/react-datepicker-custominput-sample-forked-z8qeoy?file=/src/App.tsx:601-833, do you know why? – Alex T Sep 05 '22 at 15:41
  • How do you mean 'allows for the change'? If I enter `09/05/2022abc` it fails and resets the value on focus loss. – 0stone0 Sep 05 '22 at 15:43
  • I added one more condition where I calculate age based on the date picked from the calendar. If age is less than 1 the validation should fail and it also should reset. But in fact it will allow to select and write future dates which result in age less than 0. See my sandbox. – Alex T Sep 05 '22 at 16:00
  • Yea thats because that change was handled by `onChange`, so it didn;t trigger our function. See [this updated sandbox](https://codesandbox.io/s/react-datepicker-custominput-sample-forked-49c46d?file=/src/App.tsx) where I made a single function for both handles, with the age check – 0stone0 Sep 05 '22 at 16:09
0

If I understand your issue correctly, you can add the following type to fix the typing.

const handleChangeRaw = (date: React.FocusEvent<HTMLInputElement>) => {
    if (!startDate){
      return
    }
    date.currentTarget.value = format(startDate, "dd/MM/yyyy");
};

date should have the type React.FocusEvent<HTMLInputElement>. Since startDate can be null, we have to check before using it. In this case I just return from the function. But you could also assign a default value here or something else.

Tobias S.
  • 21,159
  • 4
  • 27
  • 45