1 |
|
2 |
|
3 |
|
4 |
|
5 | import Calendar from "./rc-calendar";
|
6 | import React, { Component } from "react";
|
7 | import ReactDOM from 'react-dom';
|
8 | import classnames from 'classnames';
|
9 | import Picker from "./rc-calendar/Picker";
|
10 | import FormControl from "bee-form-control";
|
11 | import zhCN from "./locale/zh_CN";
|
12 | import enUS from "./locale/en_US";
|
13 | import Icon from "bee-icon";
|
14 | import InputGroup from 'bee-input-group';
|
15 | import moment from "moment";
|
16 | import "moment/locale/zh-cn";
|
17 | import "moment/locale/en-gb";
|
18 | import omit from 'omit.js';
|
19 |
|
20 | const cn = typeof window !== 'undefined' ? location.search.indexOf("cn") === -1 : true;
|
21 |
|
22 | const now = moment();
|
23 | if (cn) {
|
24 | now.locale("zh-cn").utcOffset(8);
|
25 | } else {
|
26 | now.locale("en-gb").utcOffset(0);
|
27 | }
|
28 |
|
29 | const format = "YYYY-Wo";
|
30 |
|
31 | const 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 |
|
51 | class 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 |
|
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 | {}
|
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 |
|
310 | WeekPicker.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 |
|
318 | export default WeekPicker;
|