React DatePicker how to open datepicker on click of icon
Asked Answered
A

11

18

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.

Ashbey answered 18/10, 2016 at 8:42 Comment(1)
Have you solved your problem? If not, we can discuss it further. Otherwise, if my answer helped you, please consider accepting it as the correct answer.Signboard
M
42

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

<label>
    <DatePicker/>
</label>
Maggard answered 17/2, 2017 at 8:37 Comment(5)
Best solution! Insert the Icon after <DatePicker/> but within the <label>Boggle
also see fabio's answer if your click listener needs to be in a different area of the pageDry
Just what I was looking for. +1Fourteen
Problem is the calendar wont close after selecting dateOstentation
This is simple, thanksTrefoil
S
26

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.

Signboard answered 28/10, 2018 at 10:57 Comment(1)
perfect solution - this should have been marked as the correct answerDry
W
4

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;
        }
Whitt answered 15/11, 2016 at 7:37 Comment(1)
When used in this way, didn't the icon render (updates were visible) everytime you selected a date?Horvath
R
3

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>
Ranita answered 8/4, 2021 at 11:52 Comment(1)
finally an answer which works and uses hooks, thanks a ton!Dashed
P
3

If you want to do it in functional component:

const startRef = useRef<DatePicker<never, undefined>>(null);

<DatePicker
  ref={startRef}
/>
<button onClick={() => startRef.current?.setOpen(true)}></button>

You want to do it (native JS version)

openDatepicker = (e) => {

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

    return inputElement?.click();

  }
Purifoy answered 22/4, 2022 at 6:38 Comment(0)
A
2

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

Ashbey answered 18/10, 2016 at 10:33 Comment(0)
F
1

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.

Furuncle answered 26/10, 2016 at 6:39 Comment(0)
S
0

@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.

Subtlety answered 21/9, 2018 at 15:18 Comment(0)
F
0
      const datePickerRef = useRef<ReactDatePicker<never, undefined> | null>();


  <div className="relative">
        <ReactDatePicker
          ref={(pickerRef) => {
            datePickerRef.current = pickerRef;
          }}
          id={id}
          className={datePickerClass({ intent })}
          placeholderText={placeholder}
          selected={value}
          dateFormat={dateFormate}
          showTimeInput={showTimeInput}
          onChange={(date) => {
            if (onChange && date) {
              onChange(date);
            }
          }}
          onBlur={onBlur}
        />
        <CalendarIcon
          className="absolute right-2 top-2.5 z-0 h-5 w-5 text-gray-400"
          onClick={() => {
            if (datePickerRef.current) {
              datePickerRef.current.setOpen(true);
            }
          }}
        />
      </div>
Fussell answered 22/5, 2023 at 11:20 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Deluxe
M
0

We can use the prop toggleCalendarOnIconClick to open date picker on click of icon refer the link below [1]: https://reactdatepicker.com/#example-toggle-calendar-open-status-on-click-of-the-calendar-icon

Merited answered 14/5 at 12:1 Comment(0)
C
-1

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>
    )
  }
Cattish answered 10/11, 2020 at 14:1 Comment(1)
Not working for meDashed

© 2022 - 2024 — McMap. All rights reserved.