aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Header.jsx
diff options
context:
space:
mode:
authoryiminghe <yiminghe@gmail.com>2016-08-04 19:53:55 +0800
committeryiminghe <yiminghe@gmail.com>2016-08-04 19:53:55 +0800
commit4984ed85e54f442998a335db70618d6184fa397e (patch)
tree6ae348b2cac5f48f3afb6f7b8dd0c2fd02f044fc /src/Header.jsx
parentdeaa6062ea2e274d50d58c70251c1237c0c03c67 (diff)
downloadtime-picker-4984ed85e54f442998a335db70618d6184fa397e.tar.gz
time-picker-4984ed85e54f442998a335db70618d6184fa397e.tar.zst
time-picker-4984ed85e54f442998a335db70618d6184fa397e.zip
2.x :boom:2.0.0
Diffstat (limited to 'src/Header.jsx')
-rw-r--r--src/Header.jsx175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/Header.jsx b/src/Header.jsx
new file mode 100644
index 0000000..4196ea9
--- /dev/null
+++ b/src/Header.jsx
@@ -0,0 +1,175 @@
1import React, { PropTypes } from 'react';
2import moment from 'moment';
3
4const Header = React.createClass({
5 propTypes: {
6 format: PropTypes.string,
7 prefixCls: PropTypes.string,
8 disabledDate: PropTypes.func,
9 placeholder: PropTypes.string,
10 clearText: PropTypes.string,
11 value: PropTypes.object,
12 hourOptions: PropTypes.array,
13 minuteOptions: PropTypes.array,
14 secondOptions: PropTypes.array,
15 disabledHours: PropTypes.func,
16 disabledMinutes: PropTypes.func,
17 disabledSeconds: PropTypes.func,
18 onChange: PropTypes.func,
19 onClear: PropTypes.func,
20 onEsc: PropTypes.func,
21 allowEmpty: PropTypes.bool,
22 defaultOpenValue: PropTypes.object,
23 currentSelectPanel: PropTypes.string,
24 },
25
26 getInitialState() {
27 const { value, format } = this.props;
28 return {
29 str: value && value.format(format) || '',
30 invalid: false,
31 };
32 },
33
34 componentWillReceiveProps(nextProps) {
35 const { value, format } = nextProps;
36 this.setState({
37 str: value && value.format(format) || '',
38 invalid: false,
39 });
40 },
41
42 onInputChange(event) {
43 const str = event.target.value;
44 this.setState({
45 str,
46 });
47 const {
48 format, hourOptions, minuteOptions, secondOptions,
49 disabledHours, disabledMinutes,
50 disabledSeconds, onChange, allowEmpty,
51 } = this.props;
52
53 if (str) {
54 const originalValue = this.props.value;
55 const value = this.getProtoValue().clone();
56 const parsed = moment(str, format, true);
57 if (!parsed.isValid()) {
58 this.setState({
59 invalid: true,
60 });
61 return;
62 }
63 value.hour(parsed.hour()).minute(parsed.minute()).second(parsed.second());
64
65 // if time value not allowed, response warning.
66 if (
67 hourOptions.indexOf(value.hour()) < 0 ||
68 minuteOptions.indexOf(value.minute()) < 0 ||
69 secondOptions.indexOf(value.second()) < 0
70 ) {
71 this.setState({
72 invalid: true,
73 });
74 return;
75 }
76
77 // if time value is disabled, response warning.
78 const disabledHourOptions = disabledHours();
79 const disabledMinuteOptions = disabledMinutes(value.hour());
80 const disabledSecondOptions = disabledSeconds(value.hour(), value.minute());
81 if (
82 (disabledHourOptions && disabledHourOptions.indexOf(value.hour()) >= 0) ||
83 (disabledMinuteOptions && disabledMinuteOptions.indexOf(value.minute()) >= 0) ||
84 (disabledSecondOptions && disabledSecondOptions.indexOf(value.second()) >= 0)
85 ) {
86 this.setState({
87 invalid: true,
88 });
89 return;
90 }
91
92 if (originalValue) {
93 if (
94 originalValue.hour() !== value.hour() ||
95 originalValue.minute() !== value.minute() ||
96 originalValue.second() !== value.second()
97 ) {
98 // keep other fields for rc-calendar
99 const changedValue = originalValue.clone();
100 changedValue.hour(value.hour());
101 changedValue.minute(value.minute());
102 changedValue.second(value.second());
103 onChange(changedValue);
104 }
105 } else if (originalValue !== value) {
106 onChange(value);
107 }
108 } else if (allowEmpty) {
109 onChange(null);
110 } else {
111 this.setState({
112 invalid: true,
113 });
114 return;
115 }
116
117 this.setState({
118 invalid: false,
119 });
120 },
121
122 onKeyDown(e) {
123 if (e.keyCode === 27) {
124 this.props.onEsc();
125 }
126 },
127
128 onClear() {
129 this.setState({ str: '' });
130 this.props.onClear();
131 },
132
133 getClearButton() {
134 const { prefixCls, allowEmpty } = this.props;
135 if (!allowEmpty) {
136 return null;
137 }
138 return (<a
139 className={`${prefixCls}-clear-btn`}
140 role="button"
141 title={this.props.clearText}
142 onMouseDown={this.onClear}
143 />);
144 },
145
146 getProtoValue() {
147 return this.props.value || this.props.defaultOpenValue;
148 },
149
150 getInput() {
151 const { prefixCls, placeholder } = this.props;
152 const { invalid, str } = this.state;
153 const invalidClass = invalid ? `${prefixCls}-input-invalid` : '';
154 return (<input
155 className={`${prefixCls}-input ${invalidClass}`}
156 ref="input"
157 onKeyDown={this.onKeyDown}
158 value={str}
159 placeholder={placeholder}
160 onChange={this.onInputChange}
161 />);
162 },
163
164 render() {
165 const { prefixCls } = this.props;
166 return (
167 <div className={`${prefixCls}-input-wrap`}>
168 {this.getInput()}
169 {this.getClearButton()}
170 </div>
171 );
172 },
173});
174
175export default Header;