Reputation: 4483
I am implementing this Calendar component from Material UI and would like to be able to select multiple dates. When another date is selected it should remain highlighted. Below is what I have so far.
import React from 'react';
import Calendar from 'material-ui/DatePicker/Calendar';
class MultiCalendar extends React.Component {
constructor(props) {
super(props);
this.state = {
controlledDate: null,
};
}
handleChange = (event, date) => {
console.log('HERE');
this.setState({
controlledDate: date,
});
console.log(date);
console.log(this.state.controlledDate);
};
render() {
return (
<Calendar
onChange={this.handleChange}
value={this.state.controlledDate}
className='calendar-test' id='calendar'
firstDayOfWeek={0} style={{ width: '500px' }}>
</Calendar>
);
}
}
export default MultiCalendar
(1) I can see here that the issue has been closed but I am not sure where to find the solution.
(2) The onChange event is not firing because those statements never appear in the console.
Any help with these issues would be wonderful. Thanks
Upvotes: 6
Views: 16866
Reputation: 266
You can use StaticDatePicker and the property renderDay to allow many dates. The dates selected will be saved in values.
import * as React from "react";
import { styled } from "@mui/material/styles";
import TextField from "@mui/material/TextField";
import AdapterDateFns from "@mui/lab/AdapterDateFns";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import StaticDatePicker from "@mui/lab/StaticDatePicker";
import PickersDay from "@mui/lab/PickersDay";
import startOfDay from "date-fns/startOfDay";
const CustomPickersDay = styled(PickersDay, {
shouldForwardProp: (prop) => prop !== "selected"
})(({ theme, selected }) => ({
...(selected && {
backgroundColor: theme.palette.primary.main,
color: theme.palette.common.white,
"&:hover, &:focus": {
backgroundColor: theme.palette.primary.dark
},
borderTopLeftRadius: "50%",
borderBottomLeftRadius: "50%",
borderTopRightRadius: "50%",
borderBottomRightRadius: "50%"
})
}));
export default function MultiDatePicker() {
const [values, setValues] = React.useState([startOfDay(new Date())]);
const findDate = (dates, date) => {
const dateTime = date.getTime();
return dates.find((item) => item.getTime() === dateTime);
};
const findIndexDate = (dates, date) => {
const dateTime = date.getTime();
return dates.findIndex((item) => item.getTime() === dateTime);
};
const renderPickerDay = (date, selectedDates, pickersDayProps) => {
if (!values) {
return <PickersDay {...pickersDayProps} />;
}
const selected = findDate(values, date);
return (
<CustomPickersDay
{...pickersDayProps}
disableMargin
selected={selected}
/>
);
};
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<StaticDatePicker
displayStaticWrapperAs="desktop"
label="Week picker"
value={values}
onChange={(newValue) => {
//copying the values array
const array = [...values];
const date = startOfDay(newValue);
const index = findIndexDate(array, date);
if (index >= 0) {
array.splice(index, 1);
} else {
array.push(date);
}
setValues(array);
}}
renderDay={renderPickerDay}
renderInput={(params) => <TextField {...params} />}
inputFormat="'Week of' MMM d"
/>
</LocalizationProvider>
);
}
The dependencies used in the example are:
The view is.
Upvotes: 10