'React DatePicker how to open datepicker on click of icon

Trying to open datepicker on click of icon of react-datepicker component, I have gone through their docs and issues links but found that its not much useful.

<DatePicker
        {...startDateOpts}
        id='abc'
        maxDate={moment()}
        onChange={this.handleStartChange}
        placeholderText='Start Date'
        popoverAttachment={smallScreen ? 'bottom center' : undefined}
        popoverTargetAttachment={smallScreen ? 'top center' : undefined}
        popoverTargetOffset={smallScreen ? '0px 0px' : undefined}
      />

enter image description here

I tried from React-datepicker docs link but no luck.



Solution 1:[1]

Just wrap DatePicker with label. All click inside label call focus on input, that open calendar.

<label>
    <DatePicker/>
</label>

Solution 2:[2]

If you want to programmatically open the datepicker or if you just don't want to use a <label> wrapper you can set a ref to the datepicker component and use setOpen(bool) to open it. Notice that since we're using refs, the component should be stateful.

Example:

openDatepicker = () => this._calendar.setOpen(true);


render() {
    <Datepicker
        {...datepickerProps}
        ref={(c) => this._calendar = c} />

    <img src={iconImg} onClick={this.openDatepicker} />
}

There is currently an open issue on the datepicker's Github stating that this is missing from the docs.

Solution 3:[3]

I have just finished that by that way,

svg icon has been imported by webpack

    import IconCalendar from 'IconCalendar';

the render function in main component

    render() {
        const {reportSettings: {
                dateTo
            }} = this.props;
        return (
            <div id="date-picker">
                <Label for="date-picker-1">Select Results date</Label>
                <DatePicker todayButton={"Today"} dateFormat={Constants.DATE_FORMAT} customInput={(<ExampleCustomInput/>)} selected={dateTo} onChange={this.handleChange}/>
            </div>
        );
    }

Secondary component that renders input field and icon

class ExampleCustomInput extends Component {
    static propTypes = {
        onClick: PropTypes.func,
        value: PropTypes.string
    }
    render() {
        const {value, onClick} = this.props;

        return (
            <div className="form-group">
                <input type="text" className="form-control" value={value} onClick={onClick}/>
                <IconCalendar className="date-picker-icon" onClick={onClick}></IconCalendar>
            </div>
        );
    }
}

finally css helped me to display icon on input field

.date-picker-icon {
            float: right;
            margin-right: 6px;
            margin-top: -30px;
            position: relative;
            z-index: 2;
        }

Solution 4:[4]

After adding newer version of react-datepicker i.e. 0.30.0 i got props autofocus but, again I got problem that only worked for first time then i tried using ref like below

refs='startDate'

in datepicker then in this object i got

this.refs.startDate.deferFocusInput();

So i called it and I got date-picker open on click of icon

Solution 5:[5]

This can be achieved using ref as below:

const datepickerRef = useRef(null); // OR React.createRef();  if you are not using hooks

// OPENS UP THE DATEPICKER WHEN THE CALENDAR ICON IS CLICKED FOR THE INPUT FIELD
function handleClickDatepickerIcon() {
  const datepickerElement = datepickerRef.current;
  // console.log("datepickerElement = ", datepickerElement);
  datepickerElement.setFocus(true);
}

<DatePicker
  {...startDateOpts}
  id="abc"
  maxDate={moment()}
  onChange={this.handleStartChange}
  placeholderText="Start Date"
  popoverAttachment={smallScreen ? "bottom center" : undefined}
  popoverTargetAttachment={smallScreen ? "top center" : undefined}
  popoverTargetOffset={smallScreen ? "0px 0px" : undefined}
  ref={datepickerRef} // attach the ref
/>;

{/* CALENDAR ICON */}
<span className="calender-placment" onClick={() => handleClickDatepickerIcon()}>
  <i className="fal fa-calendar-alt" />
</span>

Solution 6:[6]

Added in version 0.30.0, I think the customInput prop would allow you to do this. That way you could create your own input component and attach the onClick handler to the icon inside it.

Solution 7:[7]

@Jayant Patil I have achieved the functionality of opening react-datepicker on click of an icon.

This is how I did it.

  1. I have created a wrapper component around the date picker and passed an id as props to it.
class DateRangePicker extends React.Component {
    constructor(props, context) {
        super(props, context);
        // DatePicker is a controlled component.
        // This means that you need to provide an input value
        // and an onChange handler that updates this value.
    }
    render() {
        return <DatePicker
            id={this.props.id}
            selected={this.props.selected}
            onChange={this.props.onChange}
            onChangeRaw={this.props.onChangeRaw}
            onBlur={this.props.onBlur}
            peekNextMonth={true}
            showMonthDropdown={true}
            showYearDropdown={true}
            dropdownMode="select"
            placeholderText="MM/DD/YYYY"
            dateFormat="MM/DD/YYYY"
            shouldCloseOnSelect={true}
            defaultValue={null}
            />
    }

}
export default DateRangePicker;
  1. Then enclose your icon using a label and then pass the id.
        <DateRangePicker
            ref={'calendar1'}
            id={'fromdate'}
            dateFormat={gridAttributes.DEFAULT_DATE_FORMAT}
            selected={this.state.fromDate}
            onChange={this.handleDateChange.bind(this, 'fromDate')}
            onChangeRaw={(e) => this.handleRawFromDateChange(e)}
            onBlur={this.handleFromBlur.bind(this)}
            peekNextMonth={true}
            placeholderText={gridAttributes.DEFAULT_DATE_FORMAT}
            showMonthDropdown={true}
            showYearDropdown={true}
            defaultValue={null}
            className="calendar1"
        />
 <label className="icon iconCalendar calendar" style={{ fontSize: '20px' }} htmlFor='fromdate' />

This works without affecting any functionality unlike when only enclosing the icon with label as said by @tre

<label>
<DatePicker/> </label>

causes the calendar to be in open and can be closed only when we click outside the calendar.

Solution 8:[8]

I don't know but none of these solutions worked for me. So made the following one:

openDatepicker = (e) => {

    // find date picker input element
    const inputElement = e.target.closest('.my-wrapper-class')?.querySelector('input')

    return inputElement?.click();

  }

Solution 9:[9]

The accepted answer is having some issues in that, like -> When user select the date, the calender is not closing on date select, as the <label> trying to setOpen = true again so even after selecting the date, the claendar still open.

How to overcome this issue? see below the simple answer ->

this.state = {
openCalendar : false,
date : new Date()
}

handleChange = date => this.setState({ setDate : date });

      render(){
           return(
               <label>
                   <DatePicker
                      selected={this.state.date}
                      onFocus={() => this.setState({ openCalendar: true })}
                      onChange={this.handleDateChange}
                      open={this.state.openCalendar}
                  />
                 //you can add any icon here and on click that, the date will work as expected.
               <svg/>  //add any icon you want
               </label>
    )
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 tre
Solution 2 fabio.sang
Solution 3
Solution 4 Jayant Patil
Solution 5 Rahul Gupta
Solution 6 BatFace
Solution 7 Sridhar Sundaravadivelu
Solution 8 Shivam Jha
Solution 9 rajat sharma