daterangepickerreact-daterange-picker

How Maximum days restriction in DateRangePicker for the React?


How Maximum days restriction in DateRangePicker for the React can be achieved?


Solution

  • I have tried to solve the requirement as below. Sharing if any finds this useful to use,

    This restricts selection before and after from the range startDate by a maxDays.

    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