react-date-range
react-date-range copied to clipboard
Maximum days restriction
Subject of the issue
Max days restriction
[BUG] Bug Reproduce Steps
How to add max. no. of days restriction. Ex. I should be able to select only max of one day.
[BUG] Expected behaviour
Environment
Package Version: React version: Node version: Browser:
I should be able to select only max of one day.
I am confused what you intend to do, is it:
- Maximum date user can select is is before a specific date lik 2023-04-01
- Range user can select can not include more than a numbers of days
- e.g. 14 days, so (2021-05-01, 2021-05-15) is acceptable ✅ but not (2021-05-01, 2021-05-30) is not ❌
I should be able to select only max of one day.
I am confused what you intend to do, is it:
Maximum date user can select is is before a specific date lik 2023-04-01
Range user can select can not include more than a numbers of days
- e.g. 14 days, so (2021-05-01, 2021-05-15) is acceptable ✅ but not (2021-05-01, 2021-05-30) is not ❌
@kamyar I think he has the same problem as me. We need to restrict the selected date range to 30 days. Min and max date are not applicable because you should be allowed to choose, for example, the last month, not only 30 days in the past. An option would be to update the min and max date dynamically, but I found no prop to detect a running selection.
@kamyar @lhimstedt I am also having the same problem. I want to restrict the number of days for the range starting from any date.
Exactly for the same please check my post with full code at https://stackoverflow.com/a/70403423/3574669
This will restrict to selection before and after from the range startDate by a maxDays.
However, reproducing the code below as well,
import React, {useState, useEffect} from "react"
import {makeStyles} from "@material-ui/core/styles";
import { DateRangePicker } from 'react-date-range';
import 'react-date-range/dist/styles.css'; // main style file
import 'react-date-range/dist/theme/default.css';
import { addDays, subDays } from "date-fns"; // theme css file
const useStyles = makeStyles(theme => ({
root:{
// padding: 16
}
}))
const selectionRange = {
startDate: new Date(),
endDate: new Date(),
key: 'dateRange',
}
const DateRange = (props) => {
const classes = useStyles();
const {
dateRange,
onSelectPeriod,
hides,
minDate,
maxDate,
maxDays
} = props
const [period, setPeriod] = useState(selectionRange)
const [miDate, setMiDate] = useState(new Date(1970, 1, 1))
const [maDate, setMaDate] = useState(new Date(2100, 1, 1))
useEffect(()=>{
if(dateRange) {
setPeriod(dateRange)
}
if(hides)
hides.map((num, index) => {
(document.getElementsByClassName('rdrStaticRanges')[0]).childNodes[num-index].remove();
})
if(minDate != null) setMiDate(minDate)
if(maxDate != null) setMaDate(maxDate)
},[])
useEffect(()=>{
onSelectPeriod(period)
},[period])
const handleSelect = (ranges) => {
if(ranges === undefined) return
// console.log("DateRangePicker: ", ranges)
setPeriod(ranges.dateRange)
// set to restrict only maxDays range selection; post selection it reset to as initial for further selection
if(maxDays != null) {
if(ranges.dateRange.startDate.getTime() === ranges.dateRange.endDate.getTime()){
// REstrict maxDays before or after for selection
setMiDate(subDays(ranges.dateRange.startDate, maxDays-1))
const mDate = addDays(ranges.dateRange.startDate, maxDays-1)
if(mDate.getTime() <= maxDate.getTime()) setMaDate(mDate)
} else {
// RESET as INITIAL
if(minDate != null) {
setMiDate(minDate)
} else {
setMiDate(new Date(1970, 1, 1))
}
if(maxDate != null) {
setMaDate(maxDate)
} else {
setMaDate(new Date(2100, 1, 1))
}
}
}
}
return (
<div className={classes.root}>
<DateRangePicker
ranges={[period]}
onChange={handleSelect}
minDate={miDate}
maxDate={maDate}
/>
</div>
)
}
export default DateRange
To achieve this, we can easily set minDate
and maxDate
when user select date. Just need to check if the startDate and endDate of the selected is the same. Example:
const [tempDateLimit, setTempDateLimit] = useState<
| {
minDate: Date;
maxDate: Date;
}
| undefined
>();
const handleOnChange = (keyDict: RangeKeyDict) => {
const selected = keyDict.selection;
const isSameDate =
selected.startDate?.getTime() === selected.endDate?.getTime();
setSelectedDate({ ...selected });
if (isSameDate && selected.startDate && selected.startDate) {
const tempMinDate = moment(selected.startDate)
.subtract(30, 'days')
.toDate();
const tempMaxDate = moment(selected.startDate)
.add(30, 'days')
.toDate();
setTempDateLimit({
minDate: tempMinDate,
maxDate: tempMaxDate,
});
} else {
setTempDateLimit(undefined);
}
};
return ( <DateRangePicker
{...props}
onChange={handleOnChange}
minDate={tempDateLimit?.minDate}
maxDate={tempDateLimit?.maxDate}
/>)