3

I have array of days.

const availableDates = ["2019-02-01", "2019-02-04", "2019-02-05", "2019-02-06", "2019-02-07", "2019-02-11", "2019-02-12", "2019-02-13", "2019-02-14", "2019-02-15", "2019-02-19", "2019-02-20", "2019-02-21", "2019-02-22", "2019-02-23", "2019-02-25", "2019-02-26", "2019-02-27", "2019-02-28", "2019-03-01", "2019-03-04", "2019-03-05", "2019-03-06", "2019-03-07", "2019-03-08", "2019-03-09", "2019-03-11", "2019-03-12"]

I only want to show the above selected days in the airbnb datepicker and disable the other ones.

<SingleDatePicker
    date={moment()}
    onDateChange={date => this.setState({ date })} 
    focused={this.state.focused} 
    onFocusChange={({ focused }) => this.setState({ focused })}
    id="your_unique_id"
    numberOfMonths={1}
    renderCalendarDay={() => availableDates.map(d => moment(d).format(d))}
    className="select-btn selectbtn-picker"
/>

How can I do that? Thank you

Treycos
  • 7,373
  • 3
  • 24
  • 47
Profer
  • 553
  • 8
  • 40
  • 81

2 Answers2

3

You will have to use the isDayBlocked prop of the date picker. The following function will find if a day is contained inside your array, and return true if it does not find any :

isBlocked = day => {
    const availableDates = ["2019-02-01", "2019-02-04", "2019-02-05", "2019-02-06", "2019-02-07", "2019-02-11", "2019-02-12", "2019-02-13", "2019-02-14", "2019-02-15", "2019-02-19", "2019-02-20", "2019-02-21", "2019-02-22", "2019-02-23", "2019-02-25", "2019-02-26", "2019-02-27", "2019-02-28", "2019-03-01", "2019-03-04", "2019-03-05", "2019-03-06", "2019-03-07", "2019-03-08", "2019-03-09", "2019-03-11", "2019-03-12"]
    return !availableDates.some(date => day.isSame(date), 'day')
}

It uses the isSame function of moment.js : https://momentjs.com/docs/#/query/is-same/

Then bind your function :

<SingleDatePicker
    date={moment()}
    onDateChange={date => this.setState({ date })} 
    focused={this.state.focused} 
    onFocusChange={({ focused }) => this.setState({ focused })}
    id="your_unique_id"
    numberOfMonths={1}
    renderCalendarDay={() => availableDates.map(d => moment(d).format(d))}
    className="select-btn selectbtn-picker"
    isDayBlocked={this.isBlocked}
/>
Treycos
  • 7,373
  • 3
  • 24
  • 47
  • What is `day` in `isBlocked = day => {}` ? – Profer Jan 30 '19 at 09:33
  • `day` is a moment.js date given by `react-dates`, the function is called for every single day that is going to be rendered in the calendar, this function expects you to return a boolean indicating if the day should be disabled. – Treycos Jan 30 '19 at 09:35
  • You can see an example of it being used here, as there is no documentation for every single functions : http://airbnb.io/react-dates/?selectedKind=SDP%20-%20Day%20Props&selectedStory=with%20some%20blocked%20dates&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybook%2Factions%2Factions-panel – Treycos Jan 30 '19 at 09:36
  • It is blocking all the upcoming days. :-(... I need to show only the days which are avaiblable in the `availableDates` array. Rest of them need to block – Profer Jan 30 '19 at 09:37
  • Weird... Just edited my answer by putting the raw date instead of converting it into a moment object. – Treycos Jan 30 '19 at 09:41
  • No it is still blocking all the upcoming days. – Profer Jan 30 '19 at 09:47
  • Suppose I have to block the days which are inside the array `availableDates`. Then What do I do? – Profer Jan 30 '19 at 09:48
  • Oh, then just do the opposite by removing the `!` right next to the `return` – Treycos Jan 30 '19 at 09:49
  • No it doesn't block the dates which is inside the array. We are missing something else. And also `isBlocked` returning a function – Profer Jan 30 '19 at 09:52
  • `isBlocked` is returning the result of `some`, winch gives out a boolean : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some – Treycos Jan 30 '19 at 09:58
  • just a small question it works when I save inside the code. But when I click on next previous buttons it doesn't work – Profer Jan 30 '19 at 10:15
2

The function mentioned above needs correction, but as the edit is less than 6 chars, the site is not allowing me to. So here is the correct version.

day is supposed to be supplied as the second parameter to moment's isSame function

isBlocked = day => {
    const availableDates = ["2019-02-01", "2019-02-04", "2019-02-05", "2019-02-06", "2019-02-07", "2019-02-11", "2019-02-12", "2019-02-13", "2019-02-14", "2019-02-15", "2019-02-19", "2019-02-20", "2019-02-21", "2019-02-22", "2019-02-23", "2019-02-25", "2019-02-26", "2019-02-27", "2019-02-28", "2019-03-01", "2019-03-04", "2019-03-05", "2019-03-06", "2019-03-07", "2019-03-08", "2019-03-09", "2019-03-11", "2019-03-12"];
    return !availableDates.some(date => day.isSame(date, 'day'));
}
Daya
  • 121
  • 1
  • 6