React-day-picker: How to properly hide the DayPickerInput overlay with onClick

Created on 26 Dec 2018  路  2Comments  路  Source: gpbl/react-day-picker

I'm trying to hide my calendar by clicking the react-day-picker-input element again (it will open when you click it by default). For that, I have a state that records true or false when you click the element. The problem is that when I click again to hide it, it gives me the error below:

TypeError: calendarNode.hideDayPicker is not a function

I tried using showOverlay and hideDayPicker. I saw a code that works with buttons, but fails to achieve the results when you apply onClick to the DayPickerInput component (see below). https://codesandbox.io/s/oqm3p4j9rz

Here's my code (summarized):

onKeyPress = (event) => {
event.preventDefault();
}

dateRestriction = () => {
const date = new Date();
const nutrition_offset = date.getTimezoneOffset() + 240;
date.setMinutes(date.getMinutes() + nutrition_offset);
const year = date.getFullYear();
const month = date.getMonth() + 1;
let day = date.getDate();
if ((date.getDay() === 4) || (date.getDay() === 5)) {
if (date.getDate() < 5) {
day = ('0' + (date.getDate() + 5));
} else {
day = date.getDate() + 5;
}
}
if (date.getDay() === 6) {
if (date.getDate() < 6) {
day = ('0' + (date.getDate() + 4));
} else {
day = date.getDate() + 4;
}
}
if ((date.getDay() === 0) || (date.getDay() === 1) || (date.getDay() === 2) || (date.getDay() === 3)) {
if (date.getDate() < 7) {
day = ('0' + (date.getDate() + 3));
} else {
day = date.getDate() + 3;
}
}
let dateRestricted = this.parseDate_(year + '-' + month + '-' + day);
this.setState({
noDay: dateRestricted,
showCalendar: true
});

this.handleDayPickerInputHide();
}

handleDayPickerInputHide = () => {
const calendarNode = document.getElementsByName("date");
if (this.state.showCalendar === false) {
return;
} else {
calendarNode.hideDayPicker();
this.setState = {
showCalendar: false
}
}
}

render () {
const { selectedDay } = this.state;
return (


inputProps={
{className: 'dib nav pl2 pointer br3 shadow-1 dropdownButtonDate removeCursor bg-transparent pv1 mt2 typefaceFont dropdownText',
onKeyDown: this.onKeyPress,
onClick: this.dateRestriction,
name: 'date',
required: "required"}
}
value={selectedDay}
onDayChange={this.handleDayChange}
dayPickerProps={{
selectedDays: selectedDay,
disabledDays:
[
new Date(2019, 0, 1),
new Date(2019, 11, 24),
new Date(2019, 11, 25),
new Date(2019, 11, 31),
{
daysOfWeek: [0, 6],
},
{
before: new Date(this.state.noDay)
}]
}}
/>

)
}
Expected: 1. Calendar is hidden initially (default behavior) 2. Click displays calendar (default behavior) 3. Click again to hide the calendar (NEEDED) 4. Click outside hides the calendar as well (default behavior) 5. Choose a date hides the calendar as well (default behavior)

Actual results: 1. Calendar is hidden initially (default behavior) 2. Click displays calendar (default behavior) 3. Click again to hide the calendar (ERROR) 4. Click outside hides the calendar as well (default behavior) 5. Choose a date hides the calendar as well (default behavior)

All 2 comments

Another thing that I've tried, but fails to render properly because of the "showOverlay" state, was modifying the node_module:
../node_modules/react-day-picker/lib/src/DayPickerInput.js
Line 342:
{
key: 'handleInputClick',
value: function handleInputClick(e) {
console.log(this.state.showOverlay);
if (this.props.inputProps.onClick) {
e.persist();
this.props.inputProps.onClick(e);
}
if (e.target.tagName === "INPUT") {
if (this.state.showOverlay === false) {
this.showDayPicker();
}
if (this.state.showOverlay === true) {
this.hideDayPicker();
}
}
}
}

This solution is incomplete, because the first click always shows/hide and if you click outside, it will do the same... Besides that, if you click it again, it will display the overlay, clicking again will hide it... I feel like I'm very close to get it, but I haven't found what keeps updating showOverlay that causes this issue.

If this gets fixed, it could be in the next version of react-day-picker?

FIGURED IT OUT!!!

There's no need to update the state, use DOM or attempt to run a public function from your react-app. All you need to do is update react-day-picker from your node_modules.

Man... This needs to go with their next version of react-day-picker...
Check it out!

{
    key: 'handleInputClick',
    value: function handleInputClick(e) {
      //this.showDayPicker();
      if (this.props.inputProps.onClick) {
        e.persist();
        this.props.inputProps.onClick(e);
        if (this.state.showOverlay === false) {
          this.showDayPicker();
        }
        if (this.state.showOverlay === true) {
          this.hideDayPicker();
        }
      }
    }
  }, {
    key: 'handleInputFocus',
    value: function handleInputFocus(e) {
      var _this5 = this;

      //this.showDayPicker();
      // Set `overlayHasFocus` after a timeout so the overlay can be hidden when
      // the input is blurred
      this.inputFocusTimeout = setTimeout(function () {
        _this5.overlayHasFocus = false;
      }, 2);
      if (this.props.inputProps.onFocus) {
        e.persist();
        this.props.inputProps.onFocus(e);
      }
    }
  1. Navigate to your node_modules directory and find DayPickerInput.js within ../node_modules/react-day-picker/lib/src/DayPickerInput.js
  2. Comment out (or remove) this.showDayPicker() under 'handleInputFocus' and 'handleInputClick'.
  3. Added the conditional below this.props.inputProps.onClick(e) (line 349)
    Note: There's no need to update showOverlay, as hideDayPicker() and showDayPicker() already do that.
Was this page helpful?
0 / 5 - 0 ratings

Related issues

thebuilder picture thebuilder  路  3Comments

kostiantyn-solianyk picture kostiantyn-solianyk  路  4Comments

jgatjens picture jgatjens  路  5Comments

laidinidis picture laidinidis  路  6Comments

michaelgriffithus picture michaelgriffithus  路  5Comments