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;
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>
</>
)