简体   繁体   中英

How to disable certain days and dates in MUI react datepicker based on a json array?

I have Laravel app that returns a json response of dates and days of the week that should be disabled in the datepicker

For example this is my datesOff constant when I console.log() it ['2022-05-08', '2022-05-11', '2022-05-19']

And This is daysOff constant when I console.log() it [3, 6]

So how do I disable both returned dates and days(wednesday and sunday in this case)

    useEffect(() => {
      axios.get(bookingUrl).then((response) => {
        setDaysOff(response.data.daysOff);
        setDatesOff(response.data.datesOff);
        setBooked(response.data.booked);
      })
    }, []);

<LocalizationProvider locale={hr} dateAdapter={AdapterDateFns}>
            <DatePicker
            label="Date"
            disablePast={true}
            minDate={minDate}
            maxDate={maxDate}
            value={date}
            shouldDisableDate={//What do i to here
            }
            onChange={(newDate) => {
            setDate(newDate);
            }}
            renderInput={(params) => <TextField {...params} />}

DatePicker has renderDay prop which we can use to customize the day cells of the calendar. It takes 3 arguments, the first one is the Date object, which we can use to compare with the array of dates that should be disabled:

  const dates = ["2022-05-08", "2022-05-11", "2022-05-19"];

  const customDayRenderer = (
    date: Date,
    selectedDates: Array<Date | null>,
    pickersDayProps: PickersDayProps<Date>
  ) => {
    const stringifiedDate = date.toISOString().slice(0, 10);
    if (dates.includes(stringifiedDate)) {
      return <PickersDay {...pickersDayProps} disabled />;
    }
    return <PickersDay {...pickersDayProps} />;
  };

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns}>
      <DatePicker
        label="Basic example"
        value={value}
        onChange={(newValue) => {
          setValue(newValue);
        }}
        renderInput={(params) => <TextField {...params} />}
        renderDay={customDayRenderer}
      />
    </LocalizationProvider>
  );

Demo

my answer is based on the answer of Dmitriif but it has been changed because it caused many renders thorugh the process of selecting a date.

const customDayRenderer = (
    date: Date,
    selectedDates: Array<Date | null>,
    pickersDayProps: PickersDayProps<Date>
) => {
    amountOfExercises.forEach(day => {
        selectedDates.push(new Date(day.exerciseDate))
    });

    return <PickersDay {...pickersDayProps}  sx={{
        [`&&.${pickersDayClasses.selected}`]: {
          backgroundColor: "#EBEBE4",
          cursor: 'not-allowed'
        }
      }} />;
};

<DatePicker
   disablePast={true}
   label="Exercise Date"
   **renderDay={customDayRenderer}**
   value={dateValue}
   onChange={(newDateValue) => {
   setNewDateValue(newDateValue);
   }}
   renderInput={(params) => <TextField {...params} />}
   />

"amountOfExercises" is a json array and inside the forEach i am extracting the date i want to disable and push it to the selectedDates array. after doing this you will notice that the background color of the dates you want disable had changed meaning the DatePicker "knows" what dates are supposed to be selected. in order to give the user a feeling that the selectedDates are not available for selection(disabled) i've added the sx attribute which gives a lightgray background color and a cursor which is not allowed.

the date variable inside customDayRender in my coed is never read but when trying to delete it i've got an error that the renderDay method can't find the day to render

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM