UNPKG

7.39 kBJavaScriptView Raw
1/**
2 * Created by chief on 17/4/6.
3 */
4
5import MonthCalendar from "./rc-calendar/MonthCalendar";
6import { KeyCode } from 'tinper-bee-core';
7import React, { Component } from "react";
8import ReactDOM from 'react-dom';
9import Picker from "./rc-calendar/Picker";
10import FormControl from "bee-form-control";
11import Icon from "bee-icon";
12import InputGroup from 'bee-input-group';
13import classnames from 'classnames';
14import zhCN from "./locale/zh_CN";
15import omit from 'omit.js';
16import moment from "moment";
17import { formatDate } from './rc-calendar/util';
18
19class MonthPicker extends Component {
20 constructor(props, context) {
21 super(props, context);
22
23 this.state = {
24 type: "month",
25 value: props.value || props.defaultValue,
26 open: false,
27 showClose: false
28 };
29 }
30
31 componentDidMount(){
32 let value = this.props.value || this.props.defaultValue;
33 let format = this.props.format;
34 if(value){
35 if(typeof value == 'string'){
36 if(moment(value, format).isValid()){
37 value = moment(value, format);
38 }else{
39 console.error('value is not in the correct format');
40 value = ''
41 }
42 }else if(value.format&&value.isValid()){
43 value = value;
44 }else{
45 console.error('value is not in the correct format');
46 value = ''
47 }
48 }
49 this.setState({
50 value
51 })
52 }
53
54 componentWillReceiveProps(nextProps){
55 if('value' in nextProps){
56 let value = nextProps.value;
57 if(value){
58 if(value.format&&value.isValid()){
59
60 }else{
61 value = moment(value, this.props.format)
62 }
63 }else{
64 value='';
65 }
66 this.setState({
67 value
68 })
69 }
70}
71 handleCalendarChange = (value) => {
72 this.setState({
73 value: value && Object.assign(value, {_type:'month'}) || value
74 });
75 }
76 onChange = (value) => {
77 let { onChange,onClear,onSelect,format } = this.props;
78
79 this.setState({
80 value: value && Object.assign(value, {_type:'month'}) || value
81 });
82 onChange&&onChange(value,value?formatDate(value,format):'');
83 };
84 inputFocus=()=>{
85 const self = this;
86 const { format } = self.props;
87 let input = document.querySelector('.rc-calendar-input');
88 if(input){
89 if(input.value){
90 input.select()
91 }else{
92 input.focus()
93 }
94 input.onkeydown=(e)=>{
95 if(e.keyCode == KeyCode.DELETE){
96 input.value = '';
97 self.props.onChange&&self.props.onChange('','');
98 }else if(e.keyCode == KeyCode.ESC){
99 self.setState({
100 open:false
101 });
102 let v = self.state.value;
103 self.props.onOpenChange&&self.props.onOpenChange(false,v, (v && formatDate(v,self.props.format)) || '');
104 ReactDOM.findDOMNode(self.outInput).focus();// 按esc时候焦点回到input输入框
105 }else if(e.keyCode == KeyCode.ENTER){
106 let parsed = moment(input.value, format, true);
107 if(parsed.isValid()){
108 self.setState({
109 open:false
110 });
111 let v = self.state.value;
112 self.props.onOpenChange&&self.props.onOpenChange(false,v, (v && formatDate(v,format)) || '');
113 ReactDOM.findDOMNode(self.outInput).focus();
114 }
115 }
116 }
117 }
118 }
119 onOpenChange = open => {
120 const props = this.props;
121 const self = this;
122 this.setState({
123 open
124 },function(){
125 if(open){
126 setTimeout(() => {
127 self.inputFocus()
128 }, 0);
129 }
130 });
131 const value = self.state.value;
132 props.onOpenChange && props.onOpenChange(open,value, (value && formatDate(value,self.props.format)) || '');
133 if(open){
134 setTimeout(()=>{
135 self.inputFocus()
136 },200);
137 }
138 };
139
140 onTypeChange = type => {
141 this.setState({
142 type
143 });
144 };
145 onMouseLeave = (e) => {
146 this.setState({
147 showClose: false
148 })
149 }
150 onMouseEnter = (e) => {
151 this.setState({
152 showClose: true
153 })
154 }
155 clear = (e) => {
156 e.stopPropagation();
157 this.setState({
158 value: ''
159 })
160 this.props.onChange && this.props.onChange('', '');
161 }
162
163 render() {
164 let state = this.state;
165 let props = this.props;
166 const { showClose,value, ...others } = props;
167 const monthCalendar = <MonthCalendar {...props}
168 value = {state.value}
169 onChange={this.handleCalendarChange}
170 />;
171 let classes = classnames(props.className, "datepicker-container");
172 return (
173 <div className={classes}
174 {...omit(others, [
175 'closeIcon',
176 'renderIcon',
177 'format',
178 'showDateInput',
179 'showMonthInput',
180 'locale',
181 'placeholder',
182 'onClear',
183 'renderFooter',
184 'renderError',
185 'disabledDate',
186 'disabledTime',
187 ])}
188 >
189 <Picker
190 {...props}
191 onOpenChange={this.onOpenChange}
192 animation={'animation' in props ? props.animation : "slide-up"}
193 calendar={monthCalendar}
194 open={this.state.open}
195 value={state.value}
196 onChange={this.onChange}
197 dropdownClassName={props.dropdownClassName}
198 selectedValue={state.value}
199 renderError={props.renderError}
200 >
201 {({ value }) => {
202 let propsValStr;
203 if(value&&value.format&&value.isValid()){
204 value = (typeof value != 'string') ? formatDate(value,props.format) : value;
205 propsValStr = (typeof props.value != 'string') ? formatDate(props.value,props.format) : props.value;
206 // 为了避免在输入框内输入月份的过程中显示invalid date
207 if (value != propsValStr && propsValStr.length != 0){
208 value = props.value;
209 }
210 }else {
211 value = props.value;
212 }
213 return (
214 <InputGroup simple className="datepicker-input-group"
215 onMouseEnter={this.onMouseEnter}
216 onMouseLeave={this.onMouseLeave}
217 >
218 <FormControl
219 ref = { ref => this.outInput = ref }
220 placeholder={this.props.placeholder}
221 className={this.props.className}
222 value={value}
223 disabled={props.disabled}
224 />
225 {
226 showClose&&this.state.value&&this.state.showClose&&(!props.disabled)?(
227 <InputGroup.Button shape="border"
228 onClick={this.clear}>
229 { props.closeIcon() }
230 </InputGroup.Button>
231 ):<InputGroup.Button shape="border">
232 { props.renderIcon() }
233 </InputGroup.Button>
234 }
235 </InputGroup>
236 );
237 }}
238 </Picker>
239 </div>
240 );
241 }
242}
243
244
245MonthPicker.defaultProps = {
246 closeIcon:()=><Icon type="uf-close-c"/>,
247 renderIcon: () => <Icon type="uf-calendar" />,
248 format:'YYYY-MM',
249 renderError:()=>{},
250 showDateInput:true,
251 showMonthInput:true,
252 locale:zhCN,
253 showClose:true,
254 autoTriggerChange:true,
255 validatorFunc:()=>{
256 return true;
257 }
258}
259
260export default MonthPicker;