UNPKG

11.9 kBJavaScriptView Raw
1/**
2 * Created by chief on 17/4/6.
3 */
4import React, { Component } from "react";
5import RangeCalendar from "./rc-calendar/RangeCalendar";
6import TimePickerPanel from "rc-time-picker/lib/Panel";
7import FormControl from "bee-form-control";
8import Picker from "./rc-calendar/Picker";
9import InputGroup from 'bee-input-group';
10import Icon from "bee-icon";
11import classNames from 'classnames';
12import { KeyCode } from 'tinper-bee-core';
13import { formatDate } from './rc-calendar/util';
14import zhCN from "./locale/zh_CN";
15import omit from 'omit.js';
16
17import moment from "moment";
18import "moment/locale/zh-cn";
19
20// function formatDate(value,format) {
21// if (!value) {
22// return '';
23// }
24
25// if (Array.isArray(format)) {
26// format = format[0];
27// }
28
29// return value.formatDate(format);
30// }
31
32const fullFormat = "YYYY-MM-DD";
33
34const cn = typeof window !== 'undefined' ? location.search.indexOf("cn") !== -1 : true;
35
36const now = moment();
37
38
39
40function isValidRange(v) {
41 return v && v[0] && v[1];
42}
43
44if (cn) {
45 now.locale("zh-cn").utcOffset(8);
46} else {
47 now.locale("en-gb").utcOffset(0);
48}
49
50
51class RangePicker extends Component {
52 constructor(props, context) {
53 super(props, context);
54 this.state = {
55 hoverValue: [],
56 value: this.initValue(props),
57 open: props.open||false
58 };
59 }
60 initValue=(props)=>{
61 let valueProp = props.value || props.defaultValue||[];
62 let values = [];
63 for(let i = 0;i<2;i++){
64 let value = valueProp[i]||'';
65 if(value){
66 if(typeof value == 'string'){
67 if(moment(value).isValid()){
68 values.push(moment(value));
69 }else{
70 console.error('value is not in the correct format');
71 values.push('');
72 }
73 }else if(value.format&&value.isValid()){
74 values.push(value);
75 }else{
76 console.error('value is not in the correct format');
77 values = []
78 }
79 }else{
80 values.push('')
81 }
82 }
83 return values;
84 }
85 componentWillReceiveProps(nextProps){
86 if ("value" in nextProps) {
87 this.setState({
88 value: this.initValue(nextProps)
89 });
90 }
91 if ("open" in nextProps) {
92 this.setState({
93 open: nextProps.open
94 });
95 }
96 this.setState({
97 renderIcon: nextProps.renderIcon
98 });
99 }
100
101 clearHoverValue = () => this.setState({ hoverValue: [] });
102
103 onChange = (value) => {
104 const props = this.props;
105 let formatStr = props.format || 'YYYY-MM-DD';
106 if(value.length < 2){ return }
107 this.setState({
108 value:value
109 });
110
111 //传入value和dateString
112 if(props.onChange&&isValidRange(value)||value.length==0){
113 if(value.length>0){
114 props.onChange(value,`["${formatDate(value[0],formatStr)}" , "${formatDate(value[1],formatStr)}"]`, [`${formatDate(value[0],formatStr)}` , `${formatDate(value[1],formatStr)}`]);
115 }
116 else {
117 props.onChange(null)
118 }
119
120 }else{
121 props.onPanelChange&&props.onPanelChange(value);
122 }
123 }
124
125 onHoverChange = (hoverValue) => {
126 this.setState({ hoverValue });
127 this.props.onHoverChange&&this.props.onHoverChange(hoverValue)
128 }
129
130 remove = (e) => {
131 this.setState({ value:''});
132 }
133 handleCalendarChange = (value) => {
134
135 }
136 onMouseLeave = (e) => {
137 this.setState({
138 showClose: false
139 })
140 }
141 onMouseEnter = (e) => {
142 if(!this.valueIsEmpty(this.state.value)){
143 this.setState({
144 showClose: true
145 })
146 }
147 }
148 //判断value是否为空
149 valueIsEmpty=(value)=>{
150 if(value){
151 if(value.length==0){
152 return true;
153 }else{//value.length>0
154 let flag = true;
155 if(value[0]||value[1])flag=false;
156 return flag;
157 }
158 }else{
159 return true
160 }
161
162 }
163 clear = (e) => {
164 e&&e.stopPropagation&&e.stopPropagation();
165 this.setState({
166 value: []
167 })
168 this.props.onChange && this.props.onChange([], []);
169 this.props.onFormControlClear&&this.props.onFormControlClear();
170 }
171 onOpenChange = open => {
172 const props = this.props;
173 const self = this;
174 // let {value} = this.state;
175 // if(!isValidRange(value)){
176 // debugger
177 // }
178 if (open === false) {
179 this.clearHoverValue();
180 }
181
182 this.setState({
183 open
184 },function(){
185 if(open){
186 setTimeout(() => {
187 self.inputFocus()
188 }, 0);
189 }
190 });
191 props.onOpenChange && props.onOpenChange(open);
192 if(open){
193 setTimeout(()=>{
194 self.inputFocus()
195 },200);
196 }
197 };
198
199 outInputFocus = (e)=>{
200 if(this.props.hasOwnProperty('open'))e.stopPropagation();
201 this.props.outInputFocus&&this.props.outInputFocus(e);
202 }
203
204 inputFocus=()=>{
205 let inputs = document.querySelectorAll('.rc-calendar-input');
206 if(!inputs){ return }
207 if(inputs[0].value){
208 inputs[0].select()
209 }else{
210 inputs[0].focus()
211 }
212 inputs[0].onkeydown=this.keydownLeft;
213 inputs[1].onkeydown=this.keydownRight;
214 }
215
216 keydownLeft=(e)=>{
217 let inputs = document.querySelectorAll('.rc-calendar-input');
218 if(e.keyCode == KeyCode.ESC){
219 this.setState({
220 open:false
221 });
222 this.props.onOpenChange(false,v, (v && this.getValue(v)) || '');
223 }
224 if(e.keyCode == KeyCode.RIGHT||e.keyCode == KeyCode.LEFT){
225 inputs[1].focus()
226 }
227 }
228 keydownRight=(e)=>{
229 let inputs = document.querySelectorAll('.rc-calendar-input');
230 if(e.keyCode == KeyCode.ESC){
231 this.setState({
232 open:false
233 });
234 this.props.onOpenChange(false,v, (v && this.getValue(v)) || '');
235 }
236 if(e.keyCode == KeyCode.LEFT||e.keyCode == KeyCode.RIGHT){
237 inputs[0].focus()
238 }
239 }
240 //日期面板中输入框的失焦事件
241 onStartInputBlur=(e)=>{
242 let inputs = document.querySelectorAll('.rc-calendar-input');
243 let startValue,endValue;
244 if(inputs) {
245 startValue = inputs[0].value ? inputs[0].value : '';
246 endValue = inputs[1].value ? inputs[1].value : '';
247 }
248 this.props.onStartInputBlur && this.props.onStartInputBlur(e, startValue, `["${startValue}" , "${endValue}"]`);
249 }
250 onEndInputBlur=(e)=>{
251 let inputs = document.querySelectorAll('.rc-calendar-input');
252 let startValue,endValue;
253 if(inputs) {
254 startValue = inputs[0].value ? inputs[0].value : '';
255 endValue = inputs[1].value ? inputs[1].value : '';
256 }
257 this.props.onEndInputBlur && this.props.onEndInputBlur(e, endValue, `["${startValue}" , "${endValue}"]`);
258 }
259 //阻止组件内部事件冒泡到组件外部容器
260 stopPropagation = (e) => {
261 e.stopPropagation();
262 }
263 onOk = (value) => {
264 this.props.onOk && this.props.onOk(value);
265 }
266 render() {
267 const props = this.props;
268 const { showClose ,onChange, showHour,showMinute,showSecond,tabIndex,...others } = props;
269 const {value,open} = this.state;
270 let formatStr = props.format || 'YYYY-MM-DD';
271 const timePickerElement = (
272 <TimePickerPanel
273 showHour={showHour} showMinute={showMinute} showSecond={showSecond}
274 defaultValue={moment(moment().format("HH:mm:ss"), "HH:mm:ss")} />
275 );
276 const calendar = (
277 <RangeCalendar
278 hoverValue={this.state.hoverValue}
279 onHoverChange={this.onHoverChange}
280 showWeekNumber={false}
281 format={formatStr}
282 dateInputPlaceholder={props.dateInputPlaceholder||['start', 'end']}
283 locale={props.locale || zhCN }
284 onChange={this.onChange}
285 disabledDate={props.disabledDate}
286 showClear={ props.showClear }
287 showOk={props.showOk}
288 showToday={props.showToday}
289 renderFooter={props.renderFooter}
290 timePicker={props.showTime ? timePickerElement : null}
291 renderError={props.renderError}
292 onStartInputBlur={this.onStartInputBlur}
293 onEndInputBlur={this.onEndInputBlur}
294 onClear={this.clear}
295 onOk={this.onOk}
296 validatorFunc={props.validatorFunc}
297 />
298 );
299 return (
300 <div
301 onClick={this.stopPropagation} onMouseOver={this.stopPropagation}
302 {...omit(others, [
303 'closeIcon',
304 'renderIcon',
305 'showClear',
306 'showToday',
307 'locale',
308 'placeholder',
309 'showOk',
310 'dateInputPlaceholder',
311 'onPanelChange',
312 'onStartInputBlur',
313 'onEndInputBlur',
314 'renderFooter',
315 'showTime',
316 'disabledDate',
317 'disabledTime'
318 ])}
319 >
320 <Picker
321 {...props}
322 value = {value}
323 animation={'animation' in props ? props.animation : "slide-up"}
324 calendar={calendar}
325 disabled={props.disabled}
326 dropdownClassName={props.dropdownClassName}
327 onOpenChange={this.onOpenChange}
328 open={open}
329 >
330 {
331 ({}) => {
332 return (
333 <div className={classNames('calendar-picker','u-input-group','simple',props.className)}
334 onMouseEnter={this.onMouseEnter}
335 onMouseLeave={this.onMouseLeave}
336 >
337 <FormControl
338 placeholder={this.props.placeholder?this.props.placeholder:'start ~ end'}
339 value={isValidRange(value) && (this.props.inputShowValue&&this.props.inputShowValue[0]&&this.props.inputShowValue[1]?`${this.props.inputShowValue[0]} ~ ${this.props.inputShowValue[1]}`:`${formatDate(value[0],formatStr)} ~ ${formatDate(value[1],formatStr)}`) || ''}
340 disabled={props.disabled}
341 onFocus={(v,e)=>{this.outInputFocus(e)}}
342 tabIndex={tabIndex}
343 />
344 {
345 showClose&&(!this.valueIsEmpty(value))&&this.state.showClose&&(!props.disabled)?(
346 <InputGroup.Button shape="border"
347 onClick={this.clear}>
348 { props.closeIcon() }
349 </InputGroup.Button>
350 ):<InputGroup.Button shape="border">
351 { props.renderIcon() }
352 </InputGroup.Button>
353 }
354 </div>
355 );
356 }
357 }
358 </Picker>
359 </div>);
360 }
361}
362
363RangePicker.defaultProps = {
364 closeIcon:()=><Icon type="uf-close-c"/>,
365 renderIcon: () => <Icon type="uf-calendar" />,
366 locale:zhCN,
367 showClear:true,
368 showToday:true,
369 showOk:true,
370 showClose:true,
371 showSecond:true,
372 showHour:true,
373 showMinute:true,
374 validatorFunc:()=>{
375 return true;
376 }
377}
378
379export default RangePicker;