Rahul Yadav
Rahul Yadav

Reputation: 3197

How to prevent date display on click in mui x-date-pickers

I am using the controlled form of DatePicker. In the onChange handler I need a way to prevent date selection on certain condition.

To do that I am setting the value to null. Still, the field displays the clicked value. I need the field to be in the initial state even after clicking the date. How do I achieve this?

I am using version ^6.0.0 of @mui/x-date-pickers/DatePicker

import * as React from 'react';
import dayjs, { Dayjs } from 'dayjs';
import { DemoContainer } from '@mui/x-date-pickers/internals/demo';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';

export default function DatePickerValue() {
  const [value, setValue] = React.useState<Dayjs | null>(null);

  return (
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <DemoContainer components={['DatePicker', 'DatePicker']}>
        
        <DatePicker
          label="Controlled picker"
          value={value}
          onChange={(newValue) => setValue(null)}
        />
      </DemoContainer>
    </LocalizationProvider>
  );
}

https://codesandbox.io/p/sandbox/goofy-worker-glfpfr

Upvotes: 0

Views: 156

Answers (1)

Calix
Calix

Reputation: 356

It's strange. If i think about it simply, when the state is changed to a null value, the value of the DatePicker should not be updated. However, it is being selected again when clicked again.

I updated the key and approached it by making it re-render.

import * as React from "react";
import dayjs, { Dayjs } from "dayjs";
import { DemoContainer } from "@mui/x-date-pickers/internals/demo";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";

export default function DatePickerValue() {
  const [value, setValue] = React.useState<Dayjs | null>(dayjs("2022-04-17"));
  const [key, setKey] = React.useState(0);

  const handleDateChange = (newValue: Dayjs | null) => {
    const condition = true; // Check the conditions here
    if (condition) {
      setValue(null);
      setKey((prevKey) => prevKey + 1); //Force re-rendering by updating the key
    } else {
      setValue(newValue);
    }
  };
  return (
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <DemoContainer components={["DatePicker", "DatePicker"]}>
        <DatePicker
          label="Uncontrolled picker"
          defaultValue={dayjs("2022-04-17")}
        />
        <DatePicker
          key={key} //add key
          label="Controlled picker"
          value={value}
          onChange={handleDateChange}
        />
      </DemoContainer>
    </LocalizationProvider>
  );
}

I looked at the documentation for the library and found that there is a shouldDisableDate props. You can also use this to disable certain dates.

 const disableDates = (date: Dayjs) => {
    const isMonday = date.day() === 1; // disabled monday
    return isMonday;
  };
  return (
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <DemoContainer components={["DatePicker", "DatePicker"]}>
        <DatePicker
          label="Uncontrolled picker"
          defaultValue={dayjs("2022-04-17")}
        />
        <DatePicker
          label="Controlled picker"
          value={value}
          onChange={(value) => setValue(value)}
          shouldDisableDate={disableDates}
        />
      </DemoContainer>
    </LocalizationProvider>
  );

Upvotes: 0

Related Questions