Search code examples
reactjsreact-dates

Block a day of the week during a particular month using DateRangePicker


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.


Solution

  • 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')