'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}
/>
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.
- 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;
- 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