У меня есть эта простая редукционная форма v6 с вводом, который отображает настраиваемый компонент, который заполняет его значение с помощью средства выбора response-day.
https://github.com/gpbl/react-day-picker
Я предпочел response-day-picker другим, потому что он не зависит от moment.js и работает с моими текущими настройками.
Когда я фокусирую поле, я хочу, чтобы всплывала кнопка выбора даты, но если я нажимаю где-нибудь, кроме нее, я хочу, чтобы она исчезла.
По сути, я хочу, чтобы мой DatePicker React работал как jQueryUI:
https://jqueryui.com/datepicker/
Я получаю три сценария:
Я щелкаю поле, всплывает указатель даты, но он не исчезнет, если я не выберу дату или не щелкну поле еще раз (это слишком жестко для наших нужд).
Я щелкаю поле, всплывает указатель даты, но он исчезает СЛИШКОМ быстро, если я щелкну в любом месте, поскольку поле ввода onBlur вызывается до того, как он обработает событие щелчка для средства выбора даты, чтобы заполнить поле выбранной датой.
Я щелкаю поле, всплывает указатель даты, автоматически фокусируется, размывается должным образом, за исключением случаев, когда я щелкаю что-либо, кроме
или указателя даты.
Сначала я попытался использовать пустой div-брат-брат, который обертывает всю страницу, поэтому, когда я щелкаю пустой div, он правильно переключает datepicker. Это работало нормально с z-индексами и position: fixed, пока я не изменил месяц datepicker, который, кажется, повторно отображает datepicker и испортил порядок щелчка, что снова привело к ситуации 2).
Моя самая последняя попытка - автоматически сфокусировать div datepicker, когда он появляется, поэтому, когда я размываю что-либо, кроме datepicker, он будет переключать datepicker. Теоретически это работало, за исключением того, что datepicker - это компонент со множеством вложенных ‹div> внутри него для управления днем, неделей, месяцем, отключенными днями ... поэтому, когда я нажимаю 'день', он регистрирует размытие, потому что я ' m щелкнув по «day» <div>
, а не по корневому «datepicker» <div>
, на котором изначально был сделан упор.
Решением вышеизложенного было настроить onBlur 'datepicker' <div>
так, чтобы он переключал datepicker только тогда, когда document.activeElement имеет ‹body>, но это работает, только если я не нажимаю другое поле формы.
WizardFormPageOne.js:
function WizardFormPageOne({ handleSubmit }) {
return (
<form onSubmit={handleSubmit} className="col-xs-6">
<h1>WizardFormPageOne</h1>
<div className="card">
<div className="card-block">
<div className="form-group">
<label htmlFor="first">Label 1</label>
<Field type="text" name="first" component={DateInput} className="form-control" />
</div>
...
export default reduxForm({
form: 'wizardForm',
destroyOnUnmount: false,
})(WizardFormPageOne);
DateInput.js:
import React from 'react';
import styles from './styles.css';
import DatePicker from '../DatePicker';
class DateInput extends React.Component { // eslint-disable-line react/prefer-stateless-function
constructor(props) {
super(props);
this.state = {
dateValue: new Date(),
activeDateWidget: false,
};
}
changeDate = (date) => {
this.setState({
dateValue: date,
});
}
changeActiveDateWidget = (e) => {
e.stopPropagation();
this.setState({
activeDateWidget: !this.state.activeDateWidget,
});
}
render() {
const { input, meta } = this.props;
const { dateValue, activeDateWidget } = this.state;
return (
<div className={styles.dateInput}>
<input
{...input}
className="form-control"
type="text"
value={dateValue}
onClick={this.changeActiveDateWidget}
// onBlur={this.changeActiveDateWidget}
/>
{activeDateWidget ? (
<div>
<DatePicker
changeActiveDateWidget={this.changeActiveDateWidget}
changeDate={this.changeDate}
dateValue={dateValue}
/>
</div>
) : (
<div></div>
)}
</div>
);
}
}
export default DateInput;
DatePicker.js:
import React from 'react';
import 'react-day-picker/lib/style.css';
import DayPicker, { DateUtils } from 'react-day-picker';
import styles from './styles.css';
import disabledDays from './disabledDays';
class DatePicker extends React.Component { // eslint-disable-line react/prefer-stateless-function
constructor(props) {
super(props);
this.state = {
selectedDay: new Date(),
};
}
componentDidMount() {
if (this._input) {
this._input.focus();
}
}
handleDayClick = (e, day, { disabled }) => {
e.stopPropagation();
if (disabled) {
return;
}
this.setState({ selectedDay: day }, () => {
this.props.changeDate(day);
this.props.changeActiveDateWidget();
});
}
focusThisComponent = (e) => {
if (e) {
this._input = e;
}
}
focusIt = () => {
console.log('focusing');
}
blurIt = () => {
console.log('blurring');
setTimeout(() => {
if (document.activeElement == document.body) {
this.props.changeActiveDateWidget();
}
}, 1);
}
render() {
const { changeActiveDateWidget } = this.props;
const { selectedDay } = this.state;
return (
<div
className={styles.datePicker}
ref={this.focusThisComponent}
tabIndex="1"
onFocus={this.focusIt}
onBlur={this.blurIt}
>
<DayPicker
id="THISTHING"
initialMonth={selectedDay}
disabledDays={disabledDays}
selectedDays={(day) => DateUtils.isSameDay(selectedDay, day)}
onDayClick={this.handleDayClick}
/>
</div>
);
}
}
export default DatePicker;
Вот скринкаст проблемы, с которой я столкнулся сейчас:
http://screencast.com/t/kZuIwUzl
Средство выбора даты переключается правильно, за исключением случаев, когда щелчок по другому полю прекращает правильное размытие / переключение. Все мои попытки привели меня к одному из трех сценариев, перечисленных выше.