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