react-jam-ui
Version:
React JAM UI components
212 lines (188 loc) • 7.07 kB
JavaScript
import React from 'react'
import classNames from 'classnames'
import moment from 'moment'
import Input from '../Input'
import DatePicker from '../DatePicker'
import { Toast } from '../Toast'
import IconCalendar from '../Icons/feather/IconCalendar'
import './styles.styl'
/* type Props = {
format: ?string,
tz: ?string,
onChange: ?any,
activeDates: ?moment[]
} */
export default class InputCalendar extends React.Component {
constructor(props) {
super();
const format = props.format || 'DD.MM.YYYY';
const viewMonth = props.minDate || props.date || moment()
this.state = {
format,
date: props.date ? props.date : null,
viewValue: props.date ? props.date.format(format) : '',
viewMonth: viewMonth.clone(),
show: false,
valid: true,
tz: props.tz ? props.tz : moment().utcOffset()
};
}
componentWillReceiveProps(nextProps) {
if (nextProps.minDate && ((this.props.minDate && !this.props.minDate.isSame(nextProps.minDate, 'day')) || !this.props.minDate )) {
this.setState({
viewMonth: nextProps.minDate.clone()
})
}
}
onToggleCalendar = e => {
this.setState({
show: !this.state.show
});
}
onShowCalendar = e => {
this.setState({
show: true
});
}
onHideCalendar = e => {
this.setState({
show: false
});
}
onChangeInput = e => {
const value = e.target.value;
this.setState({
viewValue: value
})
if (/^\d{2}.\d{2}.\d{4}$/.test(value)) {
const tz = this.state.tz;
const date = moment(value, 'DD.MM.YYYY', true).utcOffset(tz, true).hours(12)
const isDisabled = this.props.activeDates && !this.props.activeDates.find( el => date.isSame(el, 'day'));
if (date.isValid() && ( !this.props.minDate || this.props.minDate && date.isSameOrAfter(this.props.minDate.utcOffset(tz), 'day') ) && isDisabled) {
this.setState({
date,
viewMonth: date.clone(),
valid: true
})
if (this.props.onChange) this.props.onChange(date);
this.onHideCalendar()
} else {
this.setState({
valid: false
})
Toast.error('Проверьте дату')
}
}
}
validateInputDate = value => {
const valueArray = value.split('.');
if (parseInt(valueArray[0].replace('-','')) > 31 || parseInt(valueArray[1].replace('-','')) > 12) {
return false
}
return value
}
onClickInput = e => {
const input = e.target;
if (input.value == '--.--.----') {
if (input.setSelectionRange) {
input.setSelectionRange(0, 0);
} else if (input.createTextRange) {
var range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', 0);
range.moveStart('character', 0);
range.select();
}
}
}
onPrevMonthClick = e => {
const month = 'prev';
if (this.props.onMonthChange) this.props.onMonthChange(month)
if (this.props.onPrevMonthClick) this.props.onPrevMonthClick()
}
onNextMonthClick = e => {
const month = 'next';
if (this.props.onMonthChange) this.props.onMonthChange(month)
if (this.props.onNextMonthClick) this.props.onPrevMonthClick()
}
renderCalendarDay = day => {
const tz = this.state.tz;
const date = day.clone().utcOffset(tz, true);
const minDate = this.props.minDate && this.props.minDate.utcOffset(tz) || moment().utcOffset(tz);
const isDisabled = this.props.activeDates && !this.props.activeDates.find( el => date.isSame(el, 'day'));
const classes = classNames({
'disable': date.isBefore(minDate, 'day') || isDisabled,
'active': date.isSame(this.state.date, 'day')
});
/* const dates = this.state.dates.filter( d => day.isSame(moment(d).utcOffset(tz), 'day'))
const filledClass = dates.length > 0 ? 'filled' : ''; */
return <div className={ classes }>
{/*
dates.length > 0 &&
<div className='day-dates'>{ dates.length }</div>
*/}
{ date.format('D') }
</div>
}
selectCalendarDay = day => {
const tz = this.props.tz;
const date = day.clone();
date.utcOffset(tz, true)
const minDate = this.props.minDate && this.props.minDate.utcOffset(tz) || moment().utcOffset(tz);
const isDisabled = this.props.activeDates && !this.props.activeDates.find( el => date.isSame(el, 'day'));
if (!date.isBefore(minDate, 'day') && !isDisabled) {
this.setState({
date,
viewValue: date.format(this.state.format),
viewMonth: date.clone()
})
this.onHideCalendar()
if (this.props.onChange) this.props.onChange(date)
}
}
render() {
const classes = classNames(
'input-calendar',
this.props.className,
{
'show': this.state.show,
'no-valid': !this.state.valid
}
);
return <div
className={ classes }
onFocus={ this.onShowCalendar }
id={ this.props.id || '' }
>{
this.state.show &&
<div className='input-calendar-backface' onClick={ this.onHideCalendar }></div>
}
<Input
value={ this.state.viewValue }
onChange={ this.onChangeInput }
onClick={ this.onClickInput }
mask={{
pattern: [/[0-3]/, /[0-9]/, '.', /[0-1]/, /[0-9]/,'.', /[1-3]/, /[0-9]/, /[0-9]/, /[0-9]/],
keepCharPositions: true,
showMask: true,
placeholderChar: '-',
pipe: this.validateInputDate
}}
/>
<IconCalendar size='20'/>
{
this.state.show &&
<DatePicker
type='inline'
numberOfMonths={1}
initialVisibleMonth={ () => this.state.viewMonth }
onDayClick={ this.selectCalendarDay }
renderDayContents={ this.renderCalendarDay }
onPrevMonthClick={ this.onPrevMonthClick }
onNextMonthClick={ this.onNextMonthClick }
hideKeyboardShortcutsPanel
/>
}
</div>
}
}