David Jay
David Jay

Reputation: 353

How can I disable a selected date on the Material UI calendar once the value is submited (booking system)

I integrated a simple calendar using Material UI Date & Time picker, which I would like to use inside my react app form to allow users to select a date and time (like a booking system) and submit it with their name and email. My idea was that once the user booked a date/time in the calendar. I Will be saved in an array. Then I'll check if the user selects the same date/time then I'll disable it in the calendar, so it will not be booked again. I tried to use ShouldDisableDate and I've done a lot of research, but I got stuck...

This is the documentation https://material-ui-pickers.dev/demo/datetime-picker

Ps: The booking component is separated from the form component. And the click button is only for debugging

What do you think?

import React, {useState } from "react";

import DateFnsUtils from '@date-io/date-fns';
import { DateTimePicker, MuiPickersUtilsProvider} from "@material-ui/pickers";

function Booking() {

  const [selectedDate, handleDateChange] = useState(new Date());
  const [calendarData, setCalendardata] = useState([]);
  console.log(calendarData);
  console.log(selectedDate);

  let stringfySelectedDate = JSON.stringify(selectedDate);

  const onSubmitDate = (e) => {
    e.preventdefault();
    
    // If the the array length is === to zero then add the first element
    if(calendarData.length === 0) {
      setCalendardata([...calendarData, stringfySelectedDate]);
      console.log("empty array");
    }

    if(calendarData.includes(stringfySelectedDate)) {
      console.log("already exist");
      return calendarData;
    } else {
      setCalendardata([...calendarData, JSON.stringify(selectedDate)]);
    }
  
  }

  
  return (
    <>
    <MuiPickersUtilsProvider utils={DateFnsUtils}>
      <DateTimePicker
        label="Book"
        inputVariant="outlined"
        value={selectedDate}
        onChange={handleDateChange}
        shouldDisableDate={}
        disablePast
        showTodayButton
        clearable
        id="calendar"
      />
    </MuiPickersUtilsProvider>
    <div className="col-12">
                          <div className="text-center">
                            <button
                              onClick={onSubmitDate}
                              className="nb butn light mt-30 full-width"
                            >
                              <span className="ls3 text-u">click</span>
                            </button>
                          </div>
                        </div>
    </>
  );
}

export default Booking;

Upvotes: 0

Views: 849

Answers (1)

Okan Karadag
Okan Karadag

Reputation: 3055

You should use shouldDisableDate props. shouldDisableDate type is (date) => boolean.

const [calendarData, setCalendardata] = useState([]);

const onSubmitDate = (e) => {
   ///other actions
   setCalendardata([...calendarData, selectedDate.toDateString()]);
}
const checkDisableDate = (date) => {
   return calendarData.includes(date.toDateString());
};
return(
   <>
     //....
      <DateTimePicker
        ...otherProps
        shouldDisableDate={checkDisableDate}
      />
  </>
)

Update: Above Solution is only date. if for time, should use dropdown.

const [selectedTime, setSelectedTime] = useState("0:00")

const onSubmitDate = (e) => {
   ///other actions
    const date = selectedDate.toLocaleDateString();
    const dateTime = date + "*TZ" + selectedTime;
    setCalendardata([...calendarData, dateTime ]);
    setSelectedTime("");
}
const checkDisableDateTime = (time) => {
    var arr = calendarData.filter(x => x.split("*TZ")[0] === 
                                   selectedDate.toLocaleDateString());
    return arr.some(x => x.split("*TZ")[1] === time);
} 
return (
   <>
   //Other components    
        <Select
          value={selectedTime}
          onChange={(e) => setSelectedTime(e.target.value || "")}
          label="Time"             
        >
          <MenuItem value="">
          Select
          </MenuItem>
          {
            times.map((item,index) => {
              return <MenuItem 
                       key={index} 
                       disabled={checkDisableDateTime(item)}  
                       value={item}>
              {item}
            </MenuItem>
            })
          }
      </Select>
  </>

)

Edit Material demo (forked)

Upvotes: 1

Related Questions