Search code examples
reactjsdaterangepicker

How to set date range selection in react JS DateRangePicker?


I am using 'DateRangePicker' component in my react JS application. I am trying to restrict start date to last 6 month only and difference between start and end date should not be more than 1 month. I wrote following code

isOutsideRange = (day) => {
  if (day > moment()) return true;
  else if (this.state.startDate) {
    if (day > moment(this.state.endDate)) return true;
    if (day < moment().subtract(6, 'months')) return true;
    else return false;
  } else if (this.state.endDate) {
    if (day > moment(this.state.endDate)) return true;
    if ((moment(this.state.endDate) > (moment(this.state.startDate).subtract(1, 'month')))) return true;
    else return false;
  }
}

and here is the UI code

<DateRangePicker
  startDate={this.state.startDate}
  startDateId="validFromDate"
  endDate={this.state.endDate}
  endDateId="validToDate"
  onDatesChange={({ startDate, endDate }) =>
    this.handleValidDatesChange(startDate, endDate)
  }
  focusedInput={this.state.ofrFocusedInput}
  onFocusChange={(ofrFocusedInput) => this.setState({ ofrFocusedInput })}
  isOutsideRange={(e) => this.isOutsideRange(e)}
  showDefaultInputIcon={true}
  small={true}
  minimumNights={0}
  hideKeyboardShortcutsPanel={true}
  showClearDates={true}
  min={this.maxDate}
  shouldDisableDate={({ startDate }) => this.disablePrevDates(startDate)}
  // minDate={subDays(new Date(), 10)}
  displayFormat={() => "DD/MM/YYYY"}
/>;

I tried to debug but it is not working. Can someone suggest the solution ?


Solution

  • To check if a moment is between two other moments, optionally looking at unit scale (minutes, hours, days, etc), you should use:

    moment().isBetween(moment-like, moment-like, String, String);
    // where moment-like is Moment|String|Number|Date|Array
    

    For instance, if you need to check today - 6months <= someDate <= today, you would use something like:

    // returns TRUE if date is outside the range
    const isOutsideRange = date => {
        const now = moment();
        return !moment(date)
                 .isBetween(now.subtract(6, 'months'), now, undefined, '[]');
        // [] - match is inclusive
    }
    

    For more details, please check Is Between docs. This method is very flexible, for instance, you can have exclusive or inclusive match.

    Now, the second condition. If you would like to check if endDate - startDate <= 1 month, you can play with moments as well to achieve this.

    // so if you add 1 month to your startDate and then your end date
    // is still before the result or the same - you can say the duration
    // between them is 1 month
    const lessThanMonth = (startDate, endDate) => {
        return endDate.isSameOrBefore(moment(startDate).add(1, 'months'));
    }