UNPKG

8.23 kBJavaScriptView Raw
1/**
2 * Created by chief on 17/4/6.
3 */
4
5import Calendar from "./rc-calendar";
6import React, { Component } from "react";
7import ReactDOM from 'react-dom';
8import classnames from 'classnames';
9import Picker from "./rc-calendar/Picker";
10import FormControl from "bee-form-control";
11import zhCN from "./locale/zh_CN";
12import enUS from "./locale/en_US";
13import Icon from "bee-icon";
14import InputGroup from 'bee-input-group';
15import moment from "moment";
16import "moment/locale/zh-cn";
17import "moment/locale/en-gb";
18import omit from 'omit.js';
19
20const cn = typeof window !== 'undefined' ? location.search.indexOf("cn") === -1 : true;
21
22const now = moment();
23if (cn) {
24 now.locale("zh-cn").utcOffset(8);
25} else {
26 now.locale("en-gb").utcOffset(0);
27}
28
29const format = "YYYY-Wo";
30
31const style = `
32.week-calendar .rc-calendar-tbody > tr:hover
33.rc-calendar-date {
34 background: #ebfaff;
35}
36
37.week-calendar .rc-calendar-tbody > tr:hover
38.rc-calendar-selected-day .rc-calendar-date {
39 background: #3fc7fa;
40}
41.week-calendar .week-calendar-footer {
42 position:absolute;
43 top:0;
44 left:0;
45 bottom:0;
46 width:100%;
47 border-right: 1px solid #ccc;
48}
49`;
50
51class WeekPicker extends Component {
52 constructor(props, context) {
53 super(props, context);
54
55 this.state = {
56 value: this.initValue(props),
57 open: false,
58 showClose: false
59 };
60 }
61
62 initValue=(props)=>{
63 let value = props.value || props.defaultValue||'';
64 let format = props.format;
65 if(value){
66 if(typeof value == 'string'){
67 if(moment(value,format).isValid()){
68 value = moment(value,format);
69 }else{
70 console.error('value is not in the correct format');
71 value = ''
72 }
73 }else if(value.format&&value.isValid()){
74 value = value;
75 }else{
76 console.error('value is not in the correct format');
77 value = ''
78 }
79 }
80
81 return value;
82 }
83 componentWillReceiveProps(nextProps) {
84 if ("value" in nextProps) {
85 this.setState({
86 value: this.initValue(nextProps)
87 });
88 }
89 }
90
91 onChange = value => {
92 this.setState({
93 value
94 });
95 };
96
97 onOpenChange = open => {
98 this.setState({
99 open
100 });
101 };
102
103 dateRender = current => {
104 const selectedValue = this.state.value;
105
106 let monday = moment(selectedValue).isoWeekday(1);//周一
107 let sunday = moment(selectedValue).isoWeekday(7);//周日
108 const startYear = monday.format("YYYY");
109 const endYear = sunday.format("YYYY");
110
111 let sundayStr = sunday.format("DD");
112 if ((selectedValue &&
113 current.year() === selectedValue.year() &&
114 current.week() === selectedValue.week())
115 || (startYear !== endYear
116 && ((parseInt(sundayStr) <= 3 && current.week() == monday.week() && sunday.day() < monday.day())
117 ||(parseInt(sundayStr) > 3 && current.week() == sunday.week() && sunday.day()<monday.day())))
118 // 区分跨年的情况 如果周日小于等于3 就是前一年几十周
119 ) {
120 return (
121 <div className="rc-calendar-selected-day">
122 <div className="rc-calendar-date">{current.date()}</div>
123 </div>
124 );
125 }
126 return <div className="rc-calendar-date">{current.date()}</div>;
127 };
128
129 lastWeek = () => {
130 const value = this.props.value || now;
131 value.add(-1, "weeks");
132 this.setState({
133 value,
134 open: false
135 });
136 };
137 nextWeek = () => {
138 const value = this.props.value || now;
139 value.add(+1, "weeks");
140 this.setState({
141 value,
142 open: false
143 });
144 };
145 nowWeek = () => {
146 const value = now;
147 this.setState({
148 value,
149 open: false
150 });
151 };
152
153 renderFooter = () => {
154 return (
155 <div className="week-calendar-footer" key="footer">
156 <span
157 className="week-calendar-footer-button"
158 onClick={this.lastWeek.bind(this)}
159 style={{'float':'left'}}
160 >
161 {this.props.locale.lastWeek}
162 </span>
163 <span
164 className="week-calendar-footer-button"
165 onClick={this.nowWeek.bind(this)}
166 >
167 {this.props.locale.nowWeek}
168 </span>
169 <span
170 className="week-calendar-footer-button"
171 onClick={this.nextWeek.bind(this)}
172 style={{'float':'right'}}
173 >
174 {this.props.locale.nextWeek}
175 </span>
176 </div>
177 );
178 };
179
180 onTypeChange = type => {
181 this.setState({
182 type
183 });
184 };
185
186 handleCalendarChange = (value) => {
187 this.setState({
188 value: value && Object.assign(value, {_type:'week'}) || value
189 });
190 }
191 onMouseLeave = (e) => {
192 this.setState({
193 showClose: false
194 })
195 }
196 onMouseEnter = (e) => {
197 this.setState({
198 showClose: true
199 })
200 }
201 onClear = (e) => {
202 e&&e.stopPropagation&&e.stopPropagation();
203 this.setState({
204 value: ''
205 })
206 this.props.onChange && this.props.onChange('', '');
207 }
208
209 // 跨年周显示的转换
210 getShowValue = () => {
211 let {value} = this.state;
212
213 let monday = moment(value).isoWeekday(1);//周一
214 let sunday = moment(value).isoWeekday(7);//周日
215
216 const startYear = monday.format("YYYY");
217 const endYear = sunday.format("YYYY");
218
219 let showValue;
220 if (startYear !== endYear) { // 是跨年周
221 let sundayStr = sunday.format("DD");
222 if (parseInt(sundayStr) <= 3) {
223 // 周一出现在周五之后,取周一的 年-周
224 showValue = monday;
225 } else {
226 showValue = sunday
227 }
228 }else {
229 showValue = value
230 }
231 return showValue;
232 }
233
234 render() {
235 const state = this.state;
236 const props = this.props;
237 const { showClose, ...others } = props;
238 const value = state.value;
239 const calendar = (
240 <Calendar
241 className="week-calendar"
242 showWeekNumber
243 showMonthInput={false}
244 renderFooter={this.renderFooter}
245 dateRender={this.dateRender}
246 locale={cn ? zhCN : enUS}
247 format={format}
248 dateInputPlaceholder={this.props.placeholder}
249 defaultValue={now}
250 showDateInput
251 onChange={this.handleCalendarChange}
252 showToday={false}
253 onClear={this.onClear}
254 />
255 );
256 let classes = classnames(props.className, "datepicker-container");
257 let showValue = this.getShowValue();
258 return (
259 <div className={classes}
260 {...omit(others, [
261 'closeIcon',
262 'renderIcon',
263 'format',
264 'locale',
265 'placeholder'
266 ])}
267 >
268 {/* <style dangerouslySetInnerHTML={{ __html: style }} /> */}
269 <Picker
270 animation="slide-up"
271 {...props}
272 onOpenChange={this.onOpenChange}
273 open={this.state.open}
274 calendar={calendar}
275 value={showValue}
276 >
277 {({ }) => {
278 return (
279 <InputGroup simple className="datepicker-input-group"
280 onMouseEnter={this.onMouseEnter}
281 onMouseLeave={this.onMouseLeave}
282 >
283 <FormControl
284 placeholder={this.props.placeholder}
285 disabled={props.disabled}
286 readOnly
287 tabIndex="-1"
288 className={this.props.className}
289 value={(showValue && showValue.format(format)) || ""}
290 />
291 {
292 showClose&&this.state.value&&this.state.showClose&&(!props.disabled)?(
293 <InputGroup.Button shape="border"
294 onClick={this.onClear}>
295 { props.closeIcon() }
296 </InputGroup.Button>
297 ):<InputGroup.Button shape="border">
298 { props.renderIcon() }
299 </InputGroup.Button>
300 }
301 </InputGroup>
302 );
303 }}
304 </Picker>
305 </div>
306 );
307 }
308}
309
310WeekPicker.defaultProps = {
311 closeIcon:()=><Icon type="uf-close-c"/>,
312 renderIcon: () => <Icon type="uf-calendar" />,
313 locale:zhCN,
314 showClose:true,
315 format : "YYYY-Wo"
316}
317
318export default WeekPicker;