diff options
Diffstat (limited to 'src/module')
-rw-r--r-- | src/module/Combobox.jsx | 24 | ||||
-rw-r--r-- | src/module/Header.jsx | 44 | ||||
-rw-r--r-- | src/module/Panel.jsx | 49 | ||||
-rw-r--r-- | src/module/Select.jsx | 19 |
4 files changed, 80 insertions, 56 deletions
diff --git a/src/module/Combobox.jsx b/src/module/Combobox.jsx index afce675..3dfd321 100644 --- a/src/module/Combobox.jsx +++ b/src/module/Combobox.jsx | |||
@@ -1,5 +1,6 @@ | |||
1 | import React, {PropTypes} from 'react'; | 1 | import React, {PropTypes} from 'react'; |
2 | import Select from './Select'; | 2 | import Select from './Select'; |
3 | import GregorianCalendar from 'gregorian-calendar'; | ||
3 | 4 | ||
4 | const formatOption = (option) => { | 5 | const formatOption = (option) => { |
5 | if (option < 10) { | 6 | if (option < 10) { |
@@ -15,6 +16,7 @@ const Combobox = React.createClass({ | |||
15 | value: PropTypes.object, | 16 | value: PropTypes.object, |
16 | onChange: PropTypes.func, | 17 | onChange: PropTypes.func, |
17 | showHour: PropTypes.bool, | 18 | showHour: PropTypes.bool, |
19 | gregorianCalendarLocale: PropTypes.object, | ||
18 | showSecond: PropTypes.bool, | 20 | showSecond: PropTypes.bool, |
19 | hourOptions: PropTypes.array, | 21 | hourOptions: PropTypes.array, |
20 | minuteOptions: PropTypes.array, | 22 | minuteOptions: PropTypes.array, |
@@ -22,7 +24,13 @@ const Combobox = React.createClass({ | |||
22 | }, | 24 | }, |
23 | 25 | ||
24 | onItemChange(type, itemValue) { | 26 | onItemChange(type, itemValue) { |
25 | const { value, onChange } = this.props; | 27 | const { onChange } = this.props; |
28 | let value = this.props.value; | ||
29 | if (value) { | ||
30 | value = value.clone(); | ||
31 | } else { | ||
32 | value = this.getNow().clone(); | ||
33 | } | ||
26 | if (type === 'hour') { | 34 | if (type === 'hour') { |
27 | value.setHourOfDay(itemValue); | 35 | value.setHourOfDay(itemValue); |
28 | } else if (type === 'minute') { | 36 | } else if (type === 'minute') { |
@@ -78,9 +86,19 @@ const Combobox = React.createClass({ | |||
78 | ); | 86 | ); |
79 | }, | 87 | }, |
80 | 88 | ||
81 | render() { | 89 | getNow() { |
82 | const { prefixCls, value } = this.props; | 90 | if (this.showNow) { |
91 | return this.showNow; | ||
92 | } | ||
93 | const value = new GregorianCalendar(this.props.gregorianCalendarLocale); | ||
94 | value.setTime(Date.now()); | ||
95 | this.showNow = value; | ||
96 | return value; | ||
97 | }, | ||
83 | 98 | ||
99 | render() { | ||
100 | const { prefixCls } = this.props; | ||
101 | const value = this.props.value || this.getNow(); | ||
84 | return ( | 102 | return ( |
85 | <div className={`${prefixCls}-combobox`}> | 103 | <div className={`${prefixCls}-combobox`}> |
86 | {this.getHourSelect(value.getHourOfDay())} | 104 | {this.getHourSelect(value.getHourOfDay())} |
diff --git a/src/module/Header.jsx b/src/module/Header.jsx index b65fd25..962328c 100644 --- a/src/module/Header.jsx +++ b/src/module/Header.jsx | |||
@@ -4,7 +4,7 @@ const Header = React.createClass({ | |||
4 | propTypes: { | 4 | propTypes: { |
5 | formatter: PropTypes.object, | 5 | formatter: PropTypes.object, |
6 | prefixCls: PropTypes.string, | 6 | prefixCls: PropTypes.string, |
7 | gregorianTimePickerLocale: PropTypes.object, | 7 | gregorianCalendarLocale: PropTypes.object, |
8 | locale: PropTypes.object, | 8 | locale: PropTypes.object, |
9 | disabledDate: PropTypes.func, | 9 | disabledDate: PropTypes.func, |
10 | placeholder: PropTypes.string, | 10 | placeholder: PropTypes.string, |
@@ -14,7 +14,8 @@ const Header = React.createClass({ | |||
14 | secondOptions: PropTypes.array, | 14 | secondOptions: PropTypes.array, |
15 | onChange: PropTypes.func, | 15 | onChange: PropTypes.func, |
16 | onClear: PropTypes.func, | 16 | onClear: PropTypes.func, |
17 | showClear: PropTypes.bool, | 17 | onEsc: PropTypes.func, |
18 | allowEmpty: PropTypes.bool, | ||
18 | }, | 19 | }, |
19 | 20 | ||
20 | getInitialState() { | 21 | getInitialState() { |
@@ -25,6 +26,12 @@ const Header = React.createClass({ | |||
25 | }; | 26 | }; |
26 | }, | 27 | }, |
27 | 28 | ||
29 | componentDidMount() { | ||
30 | this.timer = setTimeout(() => { | ||
31 | this.refs.input.focus(); | ||
32 | }, 0); | ||
33 | }, | ||
34 | |||
28 | componentWillReceiveProps(nextProps) { | 35 | componentWillReceiveProps(nextProps) { |
29 | const value = nextProps.value; | 36 | const value = nextProps.value; |
30 | this.setState({ | 37 | this.setState({ |
@@ -33,19 +40,23 @@ const Header = React.createClass({ | |||
33 | }); | 40 | }); |
34 | }, | 41 | }, |
35 | 42 | ||
43 | componentWillUnmount() { | ||
44 | clearTimeout(this.timer); | ||
45 | }, | ||
46 | |||
36 | onInputChange(event) { | 47 | onInputChange(event) { |
37 | const str = event.target.value; | 48 | const str = event.target.value; |
38 | this.setState({ | 49 | this.setState({ |
39 | str, | 50 | str, |
40 | }); | 51 | }); |
41 | let value = null; | 52 | let value = null; |
42 | const {formatter, gregorianTimePickerLocale, hourOptions, minuteOptions, secondOptions, onChange} = this.props; | 53 | const {formatter, gregorianCalendarLocale, hourOptions, minuteOptions, secondOptions, onChange, allowEmpty} = this.props; |
43 | 54 | ||
44 | if (str) { | 55 | if (str) { |
45 | const originalValue = this.props.value; | 56 | const originalValue = this.props.value; |
46 | try { | 57 | try { |
47 | value = formatter.parse(str, { | 58 | value = formatter.parse(str, { |
48 | locale: gregorianTimePickerLocale, | 59 | locale: gregorianCalendarLocale, |
49 | obeyCount: true, | 60 | obeyCount: true, |
50 | }); | 61 | }); |
51 | } catch (ex) { | 62 | } catch (ex) { |
@@ -84,8 +95,13 @@ const Header = React.createClass({ | |||
84 | }); | 95 | }); |
85 | return; | 96 | return; |
86 | } | 97 | } |
87 | } else { | 98 | } else if (allowEmpty) { |
88 | onChange(null); | 99 | onChange(null); |
100 | } else { | ||
101 | this.setState({ | ||
102 | invalid: true, | ||
103 | }); | ||
104 | return; | ||
89 | } | 105 | } |
90 | 106 | ||
91 | this.setState({ | 107 | this.setState({ |
@@ -93,24 +109,34 @@ const Header = React.createClass({ | |||
93 | }); | 109 | }); |
94 | }, | 110 | }, |
95 | 111 | ||
112 | onKeyDown(e) { | ||
113 | if (e.keyCode === 27) { | ||
114 | this.props.onEsc(); | ||
115 | } | ||
116 | }, | ||
117 | |||
96 | onClear() { | 118 | onClear() { |
97 | this.setState({str: ''}); | 119 | this.setState({str: ''}); |
98 | this.props.onClear(); | 120 | this.props.onClear(); |
99 | }, | 121 | }, |
100 | 122 | ||
101 | getClearButton() { | 123 | getClearButton() { |
102 | const { locale, prefixCls, showClear } = this.props; | 124 | const { locale, prefixCls, allowEmpty } = this.props; |
103 | if (!showClear) { | 125 | if (!allowEmpty) { |
104 | return null; | 126 | return null; |
105 | } | 127 | } |
106 | return <a className={`${prefixCls}-clear-btn`} role="button" title={locale.clear} onMouseDown={this.onClear} />; | 128 | return <a className={`${prefixCls}-clear-btn`} role="button" title={locale.clear} onMouseDown={this.onClear}/>; |
107 | }, | 129 | }, |
108 | 130 | ||
109 | getInput() { | 131 | getInput() { |
110 | const { prefixCls, placeholder } = this.props; | 132 | const { prefixCls, placeholder } = this.props; |
111 | const { invalid, str } = this.state; | 133 | const { invalid, str } = this.state; |
112 | const invalidClass = invalid ? `${prefixCls}-input-invalid` : ''; | 134 | const invalidClass = invalid ? `${prefixCls}-input-invalid` : ''; |
113 | return <input className={`${prefixCls}-input ${invalidClass}`} value={str} placeholder={placeholder} onChange={this.onInputChange} />; | 135 | return (<input className={`${prefixCls}-input ${invalidClass}`} |
136 | ref="input" | ||
137 | onKeyDown={this.onKeyDown} | ||
138 | value={str} | ||
139 | placeholder={placeholder} onChange={this.onInputChange}/>); | ||
114 | }, | 140 | }, |
115 | 141 | ||
116 | render() { | 142 | render() { |
diff --git a/src/module/Panel.jsx b/src/module/Panel.jsx index e372774..b91c6fe 100644 --- a/src/module/Panel.jsx +++ b/src/module/Panel.jsx | |||
@@ -1,8 +1,4 @@ | |||
1 | import React, {PropTypes} from 'react'; | 1 | import React, {PropTypes} from 'react'; |
2 | import classnames from 'classnames'; | ||
3 | import GregorianCalendar from 'gregorian-calendar'; | ||
4 | import zhCn from 'gregorian-calendar/lib/locale/zh_CN'; | ||
5 | |||
6 | import CommonMixin from '../mixin/CommonMixin'; | 2 | import CommonMixin from '../mixin/CommonMixin'; |
7 | import Header from './Header'; | 3 | import Header from './Header'; |
8 | import Combobox from './Combobox'; | 4 | import Combobox from './Combobox'; |
@@ -22,11 +18,16 @@ const Panel = React.createClass({ | |||
22 | value: PropTypes.object, | 18 | value: PropTypes.object, |
23 | locale: PropTypes.object, | 19 | locale: PropTypes.object, |
24 | placeholder: PropTypes.string, | 20 | placeholder: PropTypes.string, |
21 | gregorianCalendarLocale: PropTypes.object, | ||
25 | formatter: PropTypes.object, | 22 | formatter: PropTypes.object, |
26 | hourOptions: PropTypes.array, | 23 | hourOptions: PropTypes.array, |
27 | minuteOptions: PropTypes.array, | 24 | minuteOptions: PropTypes.array, |
28 | secondOptions: PropTypes.array, | 25 | secondOptions: PropTypes.array, |
29 | onChange: PropTypes.func, | 26 | onChange: PropTypes.func, |
27 | onEsc: PropTypes.func, | ||
28 | allowEmpty: PropTypes.bool, | ||
29 | showHour: PropTypes.bool, | ||
30 | showSecond: PropTypes.bool, | ||
30 | onClear: PropTypes.func, | 31 | onClear: PropTypes.func, |
31 | }, | 32 | }, |
32 | 33 | ||
@@ -43,26 +44,11 @@ const Panel = React.createClass({ | |||
43 | }, | 44 | }, |
44 | 45 | ||
45 | getInitialState() { | 46 | getInitialState() { |
46 | let value = this.props.value; | ||
47 | if (!value) { | ||
48 | value = new GregorianCalendar(zhCn); | ||
49 | value.setTime(Date.now()); | ||
50 | } | ||
51 | return { | 47 | return { |
52 | value, | 48 | value: this.props.value, |
53 | }; | 49 | }; |
54 | }, | 50 | }, |
55 | 51 | ||
56 | componentWillMount() { | ||
57 | const formatter = this.props.formatter; | ||
58 | const pattern = formatter.originalPattern; | ||
59 | if (pattern === 'HH:mm') { | ||
60 | this.showSecond = false; | ||
61 | } else if (pattern === 'mm:ss') { | ||
62 | this.showHour = false; | ||
63 | } | ||
64 | }, | ||
65 | |||
66 | componentWillReceiveProps(nextProps) { | 52 | componentWillReceiveProps(nextProps) { |
67 | const value = nextProps.value; | 53 | const value = nextProps.value; |
68 | if (value) { | 54 | if (value) { |
@@ -81,37 +67,34 @@ const Panel = React.createClass({ | |||
81 | this.props.onClear(); | 67 | this.props.onClear(); |
82 | }, | 68 | }, |
83 | 69 | ||
84 | showHour: true, | ||
85 | showSecond: true, | ||
86 | |||
87 | render() { | 70 | render() { |
88 | const { locale, prefixCls, placeholder, hourOptions, minuteOptions, secondOptions } = this.props; | 71 | const { locale, prefixCls, placeholder, hourOptions, minuteOptions, secondOptions, allowEmpty, showHour, showSecond, formatter, gregorianCalendarLocale } = this.props; |
89 | const value = this.state.value; | 72 | const value = this.state.value; |
90 | const cls = classnames({ 'narrow': !this.showHour || !this.showSecond }); | ||
91 | |||
92 | return ( | 73 | return ( |
93 | <div className={`${prefixCls}-panel-inner ${cls}`}> | 74 | <div className={`${prefixCls}-inner`}> |
94 | <Header | 75 | <Header |
95 | prefixCls={prefixCls} | 76 | prefixCls={prefixCls} |
96 | gregorianTimePickerLocale={value.locale} | 77 | gregorianCalendarLocale={gregorianCalendarLocale} |
97 | locale={locale} | 78 | locale={locale} |
98 | value={value} | 79 | value={value} |
99 | formatter={this.getFormatter()} | 80 | onEsc={this.props.onEsc} |
81 | formatter={formatter} | ||
100 | placeholder={placeholder} | 82 | placeholder={placeholder} |
101 | hourOptions={hourOptions} | 83 | hourOptions={hourOptions} |
102 | minuteOptions={minuteOptions} | 84 | minuteOptions={minuteOptions} |
103 | secondOptions={secondOptions} | 85 | secondOptions={secondOptions} |
104 | onChange={this.onChange} | 86 | onChange={this.onChange} |
105 | onClear={this.onClear} | 87 | onClear={this.onClear} |
106 | showClear | 88 | allowEmpty={allowEmpty} |
107 | /> | 89 | /> |
108 | <Combobox | 90 | <Combobox |
109 | prefixCls={prefixCls} | 91 | prefixCls={prefixCls} |
110 | value={value} | 92 | value={value} |
111 | formatter={this.getFormatter()} | 93 | gregorianCalendarLocale={gregorianCalendarLocale} |
94 | formatter={formatter} | ||
112 | onChange={this.onChange} | 95 | onChange={this.onChange} |
113 | showHour={this.showHour} | 96 | showHour={showHour} |
114 | showSecond={this.showSecond} | 97 | showSecond={showSecond} |
115 | hourOptions={hourOptions} | 98 | hourOptions={hourOptions} |
116 | minuteOptions={minuteOptions} | 99 | minuteOptions={minuteOptions} |
117 | secondOptions={secondOptions} | 100 | secondOptions={secondOptions} |
diff --git a/src/module/Select.jsx b/src/module/Select.jsx index 2b69623..be4c025 100644 --- a/src/module/Select.jsx +++ b/src/module/Select.jsx | |||
@@ -22,6 +22,7 @@ const Select = React.createClass({ | |||
22 | propTypes: { | 22 | propTypes: { |
23 | prefixCls: PropTypes.string, | 23 | prefixCls: PropTypes.string, |
24 | options: PropTypes.array, | 24 | options: PropTypes.array, |
25 | gregorianCalendarLocale: PropTypes.object, | ||
25 | selectedIndex: PropTypes.number, | 26 | selectedIndex: PropTypes.number, |
26 | type: PropTypes.string, | 27 | type: PropTypes.string, |
27 | onSelect: PropTypes.func, | 28 | onSelect: PropTypes.func, |
@@ -37,23 +38,19 @@ const Select = React.createClass({ | |||
37 | this.scrollToSelected(200); | 38 | this.scrollToSelected(200); |
38 | }, | 39 | }, |
39 | 40 | ||
40 | onSelect(event) { | 41 | onSelect(value) { |
41 | // do nothing when select selected option | ||
42 | if (event.target.getAttribute('class') === 'selected') { | ||
43 | return; | ||
44 | } | ||
45 | // change combobox selection | ||
46 | const { onSelect, type } = this.props; | 42 | const { onSelect, type } = this.props; |
47 | const value = parseInt(event.target.innerHTML, 10); | ||
48 | onSelect(type, value); | 43 | onSelect(type, value); |
49 | }, | 44 | }, |
50 | 45 | ||
51 | getOptions() { | 46 | getOptions() { |
52 | const { options, selectedIndex } = this.props; | 47 | const { options, selectedIndex, prefixCls } = this.props; |
53 | return options.map((item, index) => { | 48 | return options.map((item, index) => { |
54 | const cls = classnames({ selected: selectedIndex === index}); | 49 | const selected = selectedIndex === index; |
55 | const ref = selectedIndex === index ? 'selected' : null; | 50 | const cls = classnames({ |
56 | return <li ref={ref} className={cls} key={index} onClick={this.onSelect}>{item}</li>; | 51 | [`${prefixCls}-select-option-selected`]: selected, |
52 | }); | ||
53 | return <li className={cls} key={index} onClick={this.onSelect.bind(this, +item)}>{item}</li>; | ||
57 | }); | 54 | }); |
58 | }, | 55 | }, |
59 | 56 | ||