Material-UI pickers trigger validation on blur not on change?

Viewed 8101

As soon as you start typing inside the DatePicker component, the validation is triggered.

How does one trigger validation on blur instead of onInputChange when using

@material-ui/pickers meant for material-ui v4

Passing the value to the blur function should work and omitting on change, but as soon as you remove the onChange event the code breaks.

Example

export default function MaterialUIPickers() {
  const [selectedDate, setSelectedDate] = React.useState();

  const handleDateChange = (date) => {
    setSelectedDate(date);
  };

  const handleBlur = (e) => {
    setSelectedDate(e.target.value);
  };

  return (
    <MuiPickersUtilsProvider utils={DateFnsUtils}>
      <KeyboardDatePicker
        id="date-picker-dialog"
        format="MM/dd/yyyy"
        value={selectedDate}
        onChange={handleDateChange}
        onBlur={handleBlur}
      />
    </MuiPickersUtilsProvider>
  );
}

Muiv4 documentation

Stackblitz example

2 Answers

Since onChange is mandatory returning undefined in the callback solves the issue but breaks the datePicker select option (does not apply the selected date to the input field).

Because of the above, onAccept should be used thereby internal state logic can be omitted which is crucial.

Code

export default function MaterialUIPickers() {
  const [selectedDate, setSelectedDate] = React.useState();

  const handleBlur = (e) => {
    setSelectedDate(e.target.value);
  };

  return (
    <MuiPickersUtilsProvider utils={DateFnsUtils}>
      <KeyboardDatePicker
        id="date-picker-dialog"
        format="MM/dd/yyyy"
        value={selectedDate}
        onChange={()=>undefined}
        onAccept{setSelectedDate}
        onBlur={handleBlur}
      />
    </MuiPickersUtilsProvider>
  );
}

Stackblitz

The onChange is required, per the documentation. However, you don't need to set the value in onChange. If you omit the setSelectedDate in that function and instead only do it in onBlur, the date setting and validation will only occur with the blur event.

export default function MaterialUIPickers() {
  const [selectedDate, setSelectedDate] = React.useState();
  const [wasOpened, setWasOpened] = React.useState();

  const handleDateChange = (date) => {
    if (wasOpened)
    {
      setSelectedDate(date);
    }
  };

  const handleBlur = (e) => {
    setSelectedDate(e.target.value);
  };

  const handleOnOpen = () => {
    setWasOpened(true);
  };

  const handleOnClose = () => {
    setWasOpened(false);
  };

  return (
    <MuiPickersUtilsProvider utils={DateFnsUtils}>
      <KeyboardDatePicker
        id="date-picker-dialog"
        variant="inline"
        format="MM/dd/yyyy"
        value={selectedDate}
        onChange={handleDateChange}
        onBlur={handleBlur}
        autoOk={true}
        onOpen={handleOnOpen}
        onClose={handleOnClose}
      />
    </MuiPickersUtilsProvider>
  );
}

Related