1

I am using react-datepicker for a booking system.

I am using filterDate to disable some dates.

<DatePicker
    selected={startDate}
    onChange={changeRangeHandler}
    startDate={startDate}
    endDate={endDate}
    selectsRange
    placeholderText={'Choisir vos dates'}
    minDate={new Date()}
    maxDate={addMonths(new Date(), bookingThreshold)}
    disabled={!regexNum.test(numPersons)}
    locale="fr"
    filterDate={isNotDisabled}
/>

The filtering function:

const isNotDisabled = (date) => {
    return !disabledDates.includes(moment(new Date(date)).format('YYYY-MM-DD'));
}   

disabledDates is a state array that is being updated dynamically.

Since this is for a booking system, once the user selects a check-in date, he should not be able to select a check-out that include disabled dates in between.

I have not seen anything about that particular issue in the documentation or on other posts on StackOverflow.

Jolan
  • 681
  • 12
  • 39

2 Answers2

0

You can use excludeDates prop. https://reactdatepicker.com/#example-exclude-dates

0

I had to do a similar calendar. You should create your own function to remove the disabled dates in a range, there's not a native prop to do this

I created two big functions, getCheckInDates and getCheckOutDates. When calendar is opened, getCheckInDates is triggered. I just enable check in dates. Then, when you select the first date, it triggers getCheckOutDates.

I have an array with all dates. First, i removed all previous dates to check in (in my case, i have an object and there's a property with the date in it, and that's why i'm doing two loops. Maybe isn't the best way, but works for me. Should be simpler for you)

 // Can't select previous days to Check-In
  const removeBeforeDates = availability?.total_availabilities?.filter(el => isAfter(new Date(el?.availability_date.replaceAll(/-/g, "/")), new Date(startDate)));
  const dates = [];

  removeBeforeDates.length > 0 && removeBeforeDates.map(el => {
    const date = new Date(el.availability_date.replaceAll(/-/g, "/"));
    dates.push(date);
  });

Now you have an array with all the enable dates starting from check in date. Now, find the first disabled date, and shrink the array one day before. i think that this is what you're looking for

  // if found an unavailable date in the range, shrink firts part of range
  const results = [];

  for (let i = 0; i < dates.length; i++) {
    const currentDate = new Date(dates[i]);
    const nextDate = new Date(dates[i + 1]);
    const diff = differenceBetweenDays(currentDate, nextDate);
    
    results.push(currentDate);
    
    if (diff !== 1) {
      break;
    }
  }

  setIncludeDates(results);

Note: I'm using isAfter function from date-fns and i've created a helper function to calculate difference between days

export const differenceBetweenDays = (a, b) => {
  const date_a = new Date(a);
  const date_b = new Date(b);

  const differenceStamp = date_b.getTime() - date_a.getTime();
  const difference = Math.ceil(differenceStamp / (1000 * 3600 * 24));
  return difference;
};

Excuse my english!

Agustin G.
  • 72
  • 3
  • 19