Hello,
I have a very specific requirement for selecting date range in my application. I'm trying out this library and I was able to customize date range with the help of following issue #1137
Requirement:
This is what my code looks like inside of my component that is using the DateRangePicker.
render() {
const isOutsideRange = (day => {
let dayIsBlocked = false;
//Block future dates
if(Moment().diff(day, 'days') < 0) {
dayIsBlocked = true;
}
//Block days from 1 year ago
if(Moment().diff(day, 'years') > 0) {
dayIsBlocked = true;
}
return dayIsBlocked;
})
return (
<div>TBI: Calendar for selecting date range</div>
<DateRangePicker
startDate={this.state.startDate} // momentPropTypes.momentObj or null,
startDateId="your_unique_start_date_id" // PropTypes.string.isRequired,
endDate={this.state.endDate} // momentPropTypes.momentObj or null,
endDateId="your_unique_end_date_id" // PropTypes.string.isRequired,
onDatesChange={({ startDate, endDate }) => this.setState({ startDate, endDate })} // PropTypes.func.isRequired,
focusedInput={this.state.focusedInput} // PropTypes.oneOf([START_DATE, END_DATE]) or null,
onFocusChange={focusedInput => this.setState({ focusedInput })} // PropTypes.func.isRequired,
showDefaultInputIcon
isOutsideRange={isOutsideRange}
autoFocus
/>
}
Problem:
The date range appears to be working. Future dates are blocked; Current day is enabled; and dates from 1 year ago is also blocked. Problem is, whenever I start selecting a date range, 1 extra date in future gets enabled in the Calendar. Good thing is that I'm not able to select that future date as my "End Date".
For example: Today is June 25, 2018. In the Calendar, I don't see any dates after June 25, 2018 as enabled. I select a "Start Date" (i.e. June 20, 2018) and right away, June 26, 2018 becomes enabled in the Calendar. I can only select up to June 25, 2018 as my "End Date". Once the range is selected and the calendar disappears, if I click on the calendar icon or input fields to see the range, June 26, 2018 is disabled again. But, it will become visually enabled again if I start to select a new date.
What did I do wrong in the sample code above? Could this be a bug?
...and suddenly that 1 future date is now always enabled and allows me to select it. I made some minor changes (even tried undoing all the changes) but for some reason it's working differently now. I'm now able to select that 1 future date as part of the date range. This what my current code looks like. If you compare with my snippet in the description above, you'll see very minor changes.
render() {
const isOutsideRange = (day => {
let dayIsBlocked = false;
//Block future dates
if(Moment().diff(day, 'days') < 0) {
dayIsBlocked = true;
}
//Block days from 1 year ago
if(Moment().diff(day, 'years') > 0) {
dayIsBlocked = true;
}
return dayIsBlocked;
})
return (
<div>TBI: Calendar for selecting date range</div>
<DateRangePicker
startDate={this.state.startDate} // momentPropTypes.momentObj or null,
startDateId="reportCalendar-startDate" // PropTypes.string.isRequired,
endDate={this.state.endDate} // momentPropTypes.momentObj or null,
endDateId="reportCalendar-endDate" // PropTypes.string.isRequired,
onDatesChange={({ startDate, endDate }) => this.setState({ startDate, endDate })} // PropTypes.func.isRequired,
focusedInput={this.state.focusedInput} // PropTypes.oneOf([START_DATE, END_DATE]) or null,
onFocusChange={focusedInput => this.setState({ focusedInput })} // PropTypes.func.isRequired,
showDefaultInputIcon
isOutsideRange={isOutsideRange}
/>
}
very confused at this point...
hmm, the initial bug you filed seems like it could be some faulty minimum nights logic. Could there be some time zone trickery happening as well?
Instead of:
if(Moment().diff(day, 'days') < 0) {
dayIsBlocked = true;
}
does using the react-dates isAfterDay helper change anything?
import isAfterDay from 'react-dates/lib/utils/isAfterDay';
...
if (isAfterDay(day, Moment())) {
dayIsBlocked = true;
}
interesting... it does fix the issue, although I'm not really sure why the timezone would play a role here. It's all on the client side, right?
With your suggestion of using isAfterDay() method, I don't see that 1 extra future date enabled/selectable anymore. Now I just need to figure out how to allow selecting 1 day to be selected as the entire range (both start date and end date). The way I had it before I could select 1 day as the range.
Never mind about the 1 day selection comment above. I needed to add minimumNights={0} to the DateRangePicker component's configuration. With this and your suggestion about isAfterDay method, now everything looks good. Thanks a lot for your help.
Glad to see it worked out!
Most helpful comment
Never mind about the 1 day selection comment above. I needed to add
minimumNights={0}to theDateRangePickercomponent's configuration. With this and your suggestion aboutisAfterDaymethod, now everything looks good. Thanks a lot for your help.