2

Using the DateRangePicker from react-dates, I wish to disable Mondays, but only during the months of July and August. React is new to me and I don't know how to start solving this problem.

The documentation has a blockedDays prop, but it is not clear to me how I should use it for my particular case.

How can I access the currently displayed month and how can I subsequently block Mondays?

For those who wish to see my code, I have made a gist.

Helenesh
  • 3,999
  • 2
  • 21
  • 36

1 Answers1

2

You can achieve this by using the isDayBlocked prop.

This prop is a function callback that will send you a moment date, and require you to send a boolean back, true meaning that the day is blocked and false meaning the opposite.

According to the moment documentation, here is how you will know if your day should be blocked or not :

isDayBlocked = momentDate => {
    if (momentDate.format('ddd') === 'Mon' && ['Jul', 'Aug'].includes(momentDate.format('MMM')) return true

    return false
}

The following condition would work as well (refer to the doc link above) :

momentDate.format('d') === 0 && [6, 7].includes(momentDate.format('M')

Short syntax :

isDayBlocked = momentDate => momentDate.format('d') === 0 && [6, 7].includes(momentDate.format('M')

And here is the picker :

<DateRangePicker
    isDayBlocked={this.isDayBlocked}
    // ... your other props
/>

I think I found it. In the code you gave me, you declare the isDayBlocked prop twice :

            isDayBlocked={day1 => this.state.disabledDates.some(day2 => isSameDay(day1, day2))} //First time
            startDateId="datePickerStart"
            endDateId="datePickerEnd"
            onDatesChange={this.onDatesChange}
            onFocusChange={this.onFocusChange}
            focusedInput={focusedInput}
            startDate={startDate}
            endDate={endDate}
            minimumNights={minimumNights}
            isOutsideRange={condition}
            isDayBlocked = {momentDate => momentDate.format('d') === 0 } // Second one

You can merge them in a single function as shown in my first bit of code and put both conditions inside :

isDayBlocked = momentDate => {
    if (momentDate.format('ddd') === 'Mon' && ['Jul', 'Aug'].includes(momentDate.format('MMM')) return true

    if(this.state.disabledDates.some(day2 => isSameDay(day1, day2))) return true

    return false
}

Following your comment, you have 2 solutions.

Converting the values you want to test to strings :

momentDate => momentDate.format('d') === '0' && ['6','7'].includes(momentDate.format('M')

Or using the non-strict operator :

momentDate => momentDate.format('d') == 0 && ['6', '7'].includes(momentDate.format('M')
Treycos
  • 7,373
  • 3
  • 24
  • 47
  • Thank you. To test your approach, I simplified it like this (directly in the picker): `isDayBlocked = {momentDate => momentDate.format('d') === 0 }`, which doesn't disable any dates at all. It should return true (and thus disable) every Monday. Any ideas? – Helenesh Jan 10 '19 at 21:13
  • Umm, weird, is there a reason for the function you pasted to be surrounded by brackets or is it a typo ? Also, can you console.log out the result of the formatted date ? – Treycos Jan 10 '19 at 21:22
  • The console.log logs integers between 0 and 6, so that seems to be correct. The brackets are required here ( https://gist.github.com/heleneshaikh/0f959d2bd66e97b1b3ef7a4ec2e63083#file-app-js-L125 ) – Helenesh Jan 10 '19 at 21:29
  • I think I figured it out – Treycos Jan 10 '19 at 21:38
  • `momentDate.format('d)` returns a `string` representation of the week index, so a strict comparison with an `int` would not work as used in your example. – Helenesh Jan 11 '19 at 09:28