How to open it manually? Is there any API exposed or I have to trigger click event on input?
This is pretty simple:
<DatePicker
ref={(c) => this._calendar = c}
locale='ru'
...
customInput={<InputField {...this.props} calendar={this._calendar}/>}
/>
And then somewhere
this._calendar.setOpen(bool)
@alex-shamshurin It is but setOpen is not documented in API so i treat it like a workaround or hack rather than a public API method.
No matter, it works! This is exaxtly is used inside.
@alex-shamshurin It's generally considered bad practice to use the _ prefixed methods as they're meant to be private and are subject to change between releases.
That _calendar variable is in my code, not inside DatePicker. It's just a ref to calendar object, not related to DatePicker library at all.
@alex-shamshurin oops I see that now. Sorry.
I wonder why setOpen isn't documented. Perhaps a separate issue should be opened to wrote docs for it.
I think so.
Improvements to the docs are welcome! Thanks!
So setOpen is normal public method, as @martijnrusschen has just confirmed, we only need add this to the docs.
@alex-shamshurin in my case i don't have the possibility to use it as a public method, since i can't use the "ref" property of the component to assign it to a variable and the use the setOpen. Can you add it as a property or is there any other way to express directly in the render of an outer component that the DatePicker should start opened by default?
I really do not understand why you cannot get a reference to a component and use its methods and state. if you want it always be opened you can use withPortal or inline options. If you want it just to start opened you should get a reference and open it.
@alex-shamshurin it's a little bit complicated to explain but basically, i'm using riek library for inline editing (values in a visual table). I'm extending that library to support inline datepicker editing. My extension class is:
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
import { RIEInput } from 'riek'
import moment from 'moment'
import DatePicker from 'react-datepicker'
import { I18n } from 'react-redux-i18n'
import 'react-datepicker/dist/react-datepicker.css'
const debug = require('debug')('RIEDate')
export default class RIEDate extends RIEInput {
constructor(props) {
super(props)
}
static propTypes = {
format: PropTypes.func
}
// ... More code here omited for simplicity...
renderNormalComponent = () => {
debug(`renderNormalComponent()`)
return <span
tabIndex = "0"
className = { this.makeClassString() }
onFocus = { this.startEditing }
onClick = { this.elementClick } {...this.props.defaultProps } >
{ this.props.format ? this.props.format(this.state.newValue || this.props.value) : (moment(this.state.newValue).format(I18n.t("time.formats.calendar_date_js")) || moment(this.props.value).format(I18n.t("time.formats.calendar_date_js"))) }
</span>
}
renderEditingComponent = () => {
debug(`renderEditingComponent()`)
return <DatePicker
disabled={ this.props.shouldBlockWhileLoading && this.state.loading }
placeholderText={ this.props.placeholder }
className={ this.makeClassString() }
selected={ moment(this.props.value) }
onChange={ this.elementBlur }
locale="es"
**ref="input"**
{...this.props.editProps }
/>
}
}
This works by calling _renderEditingComponent()_ when clicking a date value on a table column, which makes an input appears on top of it. That would be the
Why you cannot wrap this ReactDatePicker component into custom your DatePicker or Calendar component and use ref="input" on its props whereas save real reference on DatePicker inside your internal component and pass it back via callback function?
@tommyalvarez And besides, you need a reference only for input, not for a DatePicker
This really needs to be documented, I shouldn't have to go to the third page of issues in order to find this...
At the very least, a reference to this issue in the main .md
That aside, this is awesome!
@serkolch, PRs for improvements to the docs are welcome
the workaround doesn't work for me with v0.53.0.
The customInput line gives me a
expected a string (for built-in components) or a class/function (for composite components) but got: undefined.
and setOpen gives
Cannot read property 'setOpen' of undefined
Any ideas are appreciated...
EDIT:
Seems I was confused as to what the this keyword was referring to in this case. It worked with a helper method outside the return method.
The customInput part is still borked, though.
I'm a react/redux newb - so didn't immediately understand how the setOpen method might be exploited to wire up to redux.
Here's how I got the React parts to work for anyone else with same issue:
Create a ref to the calendar in your components constructor:
this.calendarRef = React.createRef();
Attach the ref to your calendar:
<DatePicker ref={this.calendarRef} />
Then you can use the ref to trigger the setOpen method:
<button onClick={() => {this.calendarRef.current.setOpen(true)}}>
Open sesame
</button>
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
calendar.setOpen(true) works for me, but I still have to force typescript to ignore it other wise I get the error Property setOpen does not exist on type MutableRefObject<any> ?
@cherner How did you get typescript to ignore it? I keep getting the error that setOpen is not an option. Thanks.
@amemmes not recommended, but just place //@ts-ignore above the code
Understood but it was the only way to get it to actually build and execute the setOpen function. Thanks for that.
There are no setOpen in ReactDatePickerProps.
To avoid ts warning:
const inputRef = useRef<ReactDatePickerProps & { setOpen:(open: boolean) => void }>(null);
Most helpful comment
I'm a react/redux newb - so didn't immediately understand how the
setOpenmethod might be exploited to wire up to redux.Here's how I got the React parts to work for anyone else with same issue:
Create a ref to the calendar in your components constructor:
Attach the ref to your calendar:
Then you can use the ref to trigger the
setOpenmethod: