UNPKG

react-datepicker2-elhampour

Version:

react datepicker component. (include persian jalaali calendar)

259 lines (218 loc) 7.27 kB
import React, { Component, PropTypes } from 'react'; import moment from 'moment-jalaali'; import TetherComponent from 'react-tether'; import Calendar from './Calendar'; import classnames from 'classnames'; import MyTimePicker from './CustomTimePicker' export const outsideClickIgnoreClass = 'ignore--click--outside' moment.loadPersian(); export default class DatePicker extends Component { static propTypes = { value: PropTypes.object, defaultValue: PropTypes.object, onChange: PropTypes.func, onFocus: PropTypes.func, onBlur: PropTypes.func, children: PropTypes.node, min: PropTypes.object, max: PropTypes.object, defaultMonth: PropTypes.object, inputFormat: PropTypes.string, removable: PropTypes.bool, styles: PropTypes.object, calendarStyles: PropTypes.object, calendarContainerProps: PropTypes.object, isGregorian: PropTypes.bool,// jalaali or gregorian timePicker: PropTypes.bool, justCalender: PropTypes.bool }; static defaultProps = { styles: undefined, calendarContainerProps: {}, isGregorian: true, timePicker: true }; state = { isOpen: false, momentValue: this.props.defaultValue || null, inputValue: this.getValue(this.props.defaultValue, this.props.isGregorian, this.props.timePicker), inputFormat: this.props.inputFormat || this.getInputFormat(this.props.isGregorian, this.props.timePicker), isGregorian: this.props.isGregorian, timePicker: this.props.timePicker, timePickerComponent: this.props.timePicker ? MyTimePicker : undefined, justCalender: this.props.justCalender != undefined && this.props.justCalender ? true : false }; getInputFormat(isGregorian, timePicker) { if (timePicker) return isGregorian ? 'YYYY/M/D hh:mm A' : 'jYYYY/jM/jD hh:mm A'; return isGregorian ? 'YYYY/M/D' : 'jYYYY/jM/jD'; } getValue(inputValue, isGregorian, timePicker) { if (!inputValue) return ''; const inputFormat = this.getInputFormat(isGregorian, timePicker); return isGregorian ? inputValue.locale('es').format(inputFormat) : inputValue.locale('fa').format(inputFormat); } setOpen(isOpen) { const { momentValue } = this.state; if (momentValue && this.props.onChange) { this.props.onChange(momentValue); } this.setState({ isOpen }); } componentWillMount() { if (this.props.value) { this.setMomentValue(this.props.value); } } componentWillReceiveProps(nextProps) { if ('value' in nextProps && nextProps.value !== this.props.value) { this.setMomentValue(nextProps.value); } if ('isGregorian' in nextProps && nextProps.isGregorian !== this.props.isGregorian) { const inputFormat = nextProps.isGregorian ? 'YYYY/M/D hh:mm A' : 'jYYYY/jM/jD hh:mm A'; this.setState({ isGregorian: nextProps.isGregorian, inputValue: this.getValue(nextProps.value, nextProps.isGregorian, nextProps.timePicker), inputFormat: inputFormat }); } if ('timePicker' in nextProps && nextProps.timePicker !== this.props.timePicker) { this.setState({ timePicker: nextProps.timePicker, timePickerComponent: this.props.timePicker ? MyTimePicker : undefined }); } } setMomentValue(momentValue) { const { inputFormat, isGregorian, timePicker } = this.state; if (this.props.onChange) { this.props.onChange(momentValue); } // const inputValue = momentValue.format(inputFormat); const inputValue = this.getValue(momentValue, isGregorian, timePicker); this.setState({ momentValue, inputValue }); } handleFocus() { this.setOpen(true); } handleBlur(event) { const { onBlur } = this.props; const { isOpen, momentValue, inputFormat } = this.state; if (isOpen) { this.refs.input.focus(); } else if (onBlur) { onBlur(event); } if (momentValue) { const inputValue = momentValue.format(inputFormat); this.setState({ inputValue }); } } handleClickOutsideCalendar() { this.setOpen(false); } handleSelectDay(selectedDay) { const { momentValue: oldValue } = this.state; let momentValue = selectedDay.clone(); if (oldValue) { momentValue = momentValue .set({ hour: oldValue.hours(), minute: oldValue.minutes(), second: oldValue.seconds() }); } this.setMomentValue(momentValue); } handleInputChange(event) { const { inputFormat } = this.state; const inputValue = event.target.value; const momentValue = moment(inputValue, inputFormat); if (momentValue.isValid()) { this.setState({ momentValue }); } this.setState({ inputValue }); } handleInputClick() { if (!this.props.disabled) { this.setOpen(true) } } renderInput() { const { isOpen, inputValue } = this.state; const className = classnames(this.props.className, { [outsideClickIgnoreClass]: isOpen }); return ( <div> <input className={`datepicker-input ${className}`} type="text" ref="input" onFocus={this.handleFocus.bind(this)} onBlur={this.handleBlur.bind(this)} onChange={this.handleInputChange.bind(this)} onClick={this.handleInputClick.bind(this)} value={inputValue} /> </div> ); } renderCalendar() { const { momentValue, isGregorian, timePickerComponent: TimePicker } = this.state; const { onChange, min, max, defaultMonth, styles, calendarContainerProps } = this.props; return ( <div> <Calendar min={min} max={max} selectedDay={momentValue} defaultMonth={defaultMonth} onSelect={this.handleSelectDay.bind(this)} onClickOutside={this.handleClickOutsideCalendar.bind(this)} outsideClickIgnoreClass={outsideClickIgnoreClass} styles={styles} containerProps={calendarContainerProps} isGregorian={isGregorian} > { TimePicker ? ( <TimePicker isGregorian={isGregorian} min={min} max={max} momentValue={momentValue} setMomentValue={this.setMomentValue.bind(this)} /> ) : null } </Calendar> </div> ); } removeDate() { const { onChange } = this.props; if (onChange) { onChange(''); } this.setState({ input: '', inputValue: '' }); } render() { const { isOpen } = this.state; return ( <TetherComponent attachment="top center"> {!this.state.justCalender ? ( <div> <div>{this.renderInput()}</div> <div>{isOpen ? this.renderCalendar() : null}</div> </div> ) : null} {this.state.justCalender ? this.renderCalendar() : null} </TetherComponent> ); } }