commit | author | age
|
d76f7b
|
1 |
'use strict'; |
M |
2 |
|
bc8e0f
|
3 |
var React = require('react'), |
84755c
|
4 |
createClass = require('create-react-class'), |
11612b
|
5 |
assign = require('object-assign'), |
JM |
6 |
onClickOutside = require('react-onclickoutside') |
f0ec5a
|
7 |
; |
d76f7b
|
8 |
|
M |
9 |
var DOM = React.DOM; |
84755c
|
10 |
var DateTimePickerTime = onClickOutside( createClass({ |
cf1e72
|
11 |
getInitialState: function() { |
c658ad
|
12 |
return this.calculateState( this.props ); |
M |
13 |
}, |
f0ec5a
|
14 |
|
cf1e72
|
15 |
calculateState: function( props ) { |
62fd2f
|
16 |
var date = props.selectedDate || props.viewDate, |
c658ad
|
17 |
format = props.timeFormat, |
d76f7b
|
18 |
counters = [] |
M |
19 |
; |
|
20 |
|
cf1e72
|
21 |
if ( format.toLowerCase().indexOf('h') !== -1 ) { |
d76f7b
|
22 |
counters.push('hours'); |
cf1e72
|
23 |
if ( format.indexOf('m') !== -1 ) { |
d76f7b
|
24 |
counters.push('minutes'); |
cf1e72
|
25 |
if ( format.indexOf('s') !== -1 ) { |
d76f7b
|
26 |
counters.push('seconds'); |
M |
27 |
} |
|
28 |
} |
|
29 |
} |
|
30 |
|
fa70cd
|
31 |
var daypart = false; |
f0ec5a
|
32 |
if ( this.state !== null && this.props.timeFormat.toLowerCase().indexOf( ' a' ) !== -1 ) { |
SE |
33 |
if ( this.props.timeFormat.indexOf( ' A' ) !== -1 ) { |
cf1e72
|
34 |
daypart = ( this.state.hours >= 12 ) ? 'PM' : 'AM'; |
SE |
35 |
} else { |
|
36 |
daypart = ( this.state.hours >= 12 ) ? 'pm' : 'am'; |
|
37 |
} |
a17593
|
38 |
} |
MK |
39 |
|
d76f7b
|
40 |
return { |
f0ec5a
|
41 |
hours: date.format( 'H' ), |
SE |
42 |
minutes: date.format( 'mm' ), |
|
43 |
seconds: date.format( 'ss' ), |
|
44 |
milliseconds: date.format( 'SSS' ), |
a17593
|
45 |
daypart: daypart, |
d76f7b
|
46 |
counters: counters |
M |
47 |
}; |
|
48 |
}, |
1a0429
|
49 |
|
f0ec5a
|
50 |
renderCounter: function( type ) { |
SE |
51 |
if ( type !== 'daypart' ) { |
|
52 |
var value = this.state[ type ]; |
|
53 |
if ( type === 'hours' && this.props.timeFormat.toLowerCase().indexOf( ' a' ) !== -1 ) { |
|
54 |
value = ( value - 1 ) % 12 + 1; |
|
55 |
|
|
56 |
if ( value === 0 ) { |
7c7053
|
57 |
value = 12; |
ER |
58 |
} |
a17593
|
59 |
} |
f0ec5a
|
60 |
return DOM.div({ key: type, className: 'rdtCounter' }, [ |
SE |
61 |
DOM.span({ key: 'up', className: 'rdtBtn', onMouseDown: this.onStartClicking( 'increase', type ) }, '▲' ), |
|
62 |
DOM.div({ key: 'c', className: 'rdtCount' }, value ), |
|
63 |
DOM.span({ key: 'do', className: 'rdtBtn', onMouseDown: this.onStartClicking( 'decrease', type ) }, '▼' ) |
a17593
|
64 |
]); |
MK |
65 |
} |
|
66 |
return ''; |
d76f7b
|
67 |
}, |
f0ec5a
|
68 |
|
3bf154
|
69 |
renderDayPart: function() { |
f0ec5a
|
70 |
return DOM.div({ key: 'dayPart', className: 'rdtCounter' }, [ |
SE |
71 |
DOM.span({ key: 'up', className: 'rdtBtn', onMouseDown: this.onStartClicking( 'toggleDayPart', 'hours') }, '▲' ), |
|
72 |
DOM.div({ key: this.state.daypart, className: 'rdtCount' }, this.state.daypart ), |
|
73 |
DOM.span({ key: 'do', className: 'rdtBtn', onMouseDown: this.onStartClicking( 'toggleDayPart', 'hours') }, '▼' ) |
3bf154
|
74 |
]); |
DF |
75 |
}, |
f0ec5a
|
76 |
|
d76f7b
|
77 |
render: function() { |
M |
78 |
var me = this, |
|
79 |
counters = [] |
|
80 |
; |
|
81 |
|
f0ec5a
|
82 |
this.state.counters.forEach( function( c ) { |
462115
|
83 |
if ( counters.length ) |
f0ec5a
|
84 |
counters.push( DOM.div({ key: 'sep' + counters.length, className: 'rdtCounterSeparator' }, ':' ) ); |
d76f7b
|
85 |
counters.push( me.renderCounter( c ) ); |
M |
86 |
}); |
a17593
|
87 |
|
f0ec5a
|
88 |
if ( this.state.daypart !== false ) { |
3bf154
|
89 |
counters.push( me.renderDayPart() ); |
a17593
|
90 |
} |
MK |
91 |
|
f0ec5a
|
92 |
if ( this.state.counters.length === 3 && this.props.timeFormat.indexOf( 'S' ) !== -1 ) { |
SE |
93 |
counters.push( DOM.div({ className: 'rdtCounterSeparator', key: 'sep5' }, ':' ) ); |
d76f7b
|
94 |
counters.push( |
f0ec5a
|
95 |
DOM.div({ className: 'rdtCounter rdtMilli', key: 'm' }, |
SE |
96 |
DOM.input({ value: this.state.milliseconds, type: 'text', onChange: this.updateMilli } ) |
d76f7b
|
97 |
) |
M |
98 |
); |
|
99 |
} |
|
100 |
|
f0ec5a
|
101 |
return DOM.div({ className: 'rdtTime' }, |
SE |
102 |
DOM.table({}, [ |
a3a33b
|
103 |
this.renderHeader(), |
f0ec5a
|
104 |
DOM.tbody({ key: 'b'}, DOM.tr({}, DOM.td({}, |
SE |
105 |
DOM.div({ className: 'rdtCounters' }, counters ) |
a3a33b
|
106 |
))) |
M |
107 |
]) |
d76f7b
|
108 |
); |
c658ad
|
109 |
}, |
f0ec5a
|
110 |
|
bc8e0f
|
111 |
componentWillMount: function() { |
LG |
112 |
var me = this; |
9c55be
|
113 |
me.timeConstraints = { |
AG |
114 |
hours: { |
|
115 |
min: 0, |
|
116 |
max: 23, |
|
117 |
step: 1 |
|
118 |
}, |
|
119 |
minutes: { |
|
120 |
min: 0, |
|
121 |
max: 59, |
|
122 |
step: 1 |
|
123 |
}, |
|
124 |
seconds: { |
|
125 |
min: 0, |
|
126 |
max: 59, |
cf1e72
|
127 |
step: 1 |
9c55be
|
128 |
}, |
AG |
129 |
milliseconds: { |
|
130 |
min: 0, |
|
131 |
max: 999, |
|
132 |
step: 1 |
|
133 |
} |
|
134 |
}; |
f0ec5a
|
135 |
['hours', 'minutes', 'seconds', 'milliseconds'].forEach( function( type ) { |
cf1e72
|
136 |
assign(me.timeConstraints[ type ], me.props.timeConstraints[ type ]); |
bc8e0f
|
137 |
}); |
79e319
|
138 |
this.setState( this.calculateState( this.props ) ); |
bc8e0f
|
139 |
}, |
f0ec5a
|
140 |
|
cf1e72
|
141 |
componentWillReceiveProps: function( nextProps ) { |
c658ad
|
142 |
this.setState( this.calculateState( nextProps ) ); |
d76f7b
|
143 |
}, |
f0ec5a
|
144 |
|
cf1e72
|
145 |
updateMilli: function( e ) { |
462115
|
146 |
var milli = parseInt( e.target.value, 10 ); |
cf1e72
|
147 |
if ( milli === e.target.value && milli >= 0 && milli < 1000 ) { |
d76f7b
|
148 |
this.props.setTime( 'milliseconds', milli ); |
cf1e72
|
149 |
this.setState( { milliseconds: milli } ); |
d76f7b
|
150 |
} |
M |
151 |
}, |
f0ec5a
|
152 |
|
cf1e72
|
153 |
renderHeader: function() { |
462115
|
154 |
if ( !this.props.dateFormat ) |
49a27b
|
155 |
return null; |
d76f7b
|
156 |
|
62fd2f
|
157 |
var date = this.props.selectedDate || this.props.viewDate; |
f0ec5a
|
158 |
return DOM.thead({ key: 'h' }, DOM.tr({}, |
SE |
159 |
DOM.th({ className: 'rdtSwitch', colSpan: 4, onClick: this.props.showView( 'days' ) }, date.format( this.props.dateFormat ) ) |
d76f7b
|
160 |
)); |
M |
161 |
}, |
f0ec5a
|
162 |
|
cf1e72
|
163 |
onStartClicking: function( action, type ) { |
462115
|
164 |
var me = this; |
59314a
|
165 |
|
cf1e72
|
166 |
return function() { |
d76f7b
|
167 |
var update = {}; |
M |
168 |
update[ type ] = me[ action ]( type ); |
|
169 |
me.setState( update ); |
|
170 |
|
cf1e72
|
171 |
me.timer = setTimeout( function() { |
SE |
172 |
me.increaseTimer = setInterval( function() { |
d76f7b
|
173 |
update[ type ] = me[ action ]( type ); |
M |
174 |
me.setState( update ); |
462115
|
175 |
}, 70); |
d76f7b
|
176 |
}, 500); |
M |
177 |
|
cf1e72
|
178 |
me.mouseUpListener = function() { |
d76f7b
|
179 |
clearTimeout( me.timer ); |
M |
180 |
clearInterval( me.increaseTimer ); |
|
181 |
me.props.setTime( type, me.state[ type ] ); |
f0ec5a
|
182 |
document.body.removeEventListener( 'mouseup', me.mouseUpListener ); |
4e9d38
|
183 |
}; |
M |
184 |
|
f0ec5a
|
185 |
document.body.addEventListener( 'mouseup', me.mouseUpListener ); |
d76f7b
|
186 |
}; |
0b3475
|
187 |
}, |
f0ec5a
|
188 |
|
0b3475
|
189 |
padValues: { |
LG |
190 |
hours: 1, |
|
191 |
minutes: 2, |
|
192 |
seconds: 2, |
|
193 |
milliseconds: 3 |
d76f7b
|
194 |
}, |
f0ec5a
|
195 |
|
cf1e72
|
196 |
toggleDayPart: function( type ) { // type is always 'hours' |
f0ec5a
|
197 |
var value = parseInt( this.state[ type ], 10) + 12; |
0b3475
|
198 |
if ( value > this.timeConstraints[ type ].max ) |
cf1e72
|
199 |
value = this.timeConstraints[ type ].min + ( value - ( this.timeConstraints[ type ].max + 1 ) ); |
d76f7b
|
200 |
return this.pad( type, value ); |
M |
201 |
}, |
f0ec5a
|
202 |
|
SE |
203 |
increase: function( type ) { |
|
204 |
var value = parseInt( this.state[ type ], 10) + this.timeConstraints[ type ].step; |
|
205 |
if ( value > this.timeConstraints[ type ].max ) |
|
206 |
value = this.timeConstraints[ type ].min + ( value - ( this.timeConstraints[ type ].max + 1 ) ); |
|
207 |
return this.pad( type, value ); |
|
208 |
}, |
|
209 |
|
cf1e72
|
210 |
decrease: function( type ) { |
f0ec5a
|
211 |
var value = parseInt( this.state[ type ], 10) - this.timeConstraints[ type ].step; |
0b3475
|
212 |
if ( value < this.timeConstraints[ type ].min ) |
4ed404
|
213 |
value = this.timeConstraints[ type ].max + 1 - ( this.timeConstraints[ type ].min - value ); |
d76f7b
|
214 |
return this.pad( type, value ); |
M |
215 |
}, |
f0ec5a
|
216 |
|
cf1e72
|
217 |
pad: function( type, value ) { |
d76f7b
|
218 |
var str = value + ''; |
462115
|
219 |
while ( str.length < this.padValues[ type ] ) |
d76f7b
|
220 |
str = '0' + str; |
M |
221 |
return str; |
11612b
|
222 |
}, |
JM |
223 |
|
|
224 |
handleClickOutside: function() { |
|
225 |
this.props.handleClickOutside(); |
|
226 |
} |
|
227 |
})); |
d76f7b
|
228 |
|
M |
229 |
module.exports = DateTimePickerTime; |