Loris Guignard
2016-07-08 bc8e0f8721fe1e059c4e721dd2f0de82a51bedc9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
'use strict';
 
var React = require('react'),
    assign = require('object-assign');
 
var DOM = React.DOM;
var DateTimePickerTime = React.createClass({
    getInitialState: function(){
        return this.calculateState( this.props );
    },
    calculateState: function( props ){
        var date = props.selectedDate || props.viewDate,
            format = props.timeFormat,
            counters = []
        ;
 
        if( format.indexOf('H') != -1 || format.indexOf('h') != -1 ){
            counters.push('hours');
            if( format.indexOf('m') != -1 ){
                counters.push('minutes');
                if( format.indexOf('s') != -1 ){
                    counters.push('seconds');
                }
            }
        }
 
        var daypart = false;
        if( this.props.timeFormat.indexOf(' A') != -1  && this.state != null ){
            daypart = ( this.state.hours > 12 ) ? 'PM' : 'AM';
        }
 
        return {
            hours: date.format('H'),
            minutes: date.format('mm'),
            seconds: date.format('ss'),
            milliseconds: date.format('SSS'),
            daypart: daypart,
            counters: counters
        };
    },
    renderCounter: function( type ){
        if (type !== 'daypart') {
            var value = this.state[ type ];
            if (type === 'hours' && this.props.timeFormat.indexOf(' A') != -1 && value > 12) {
                value = value - 12;
            }
            return DOM.div({ key: type, className: 'rdtCounter'}, [
                DOM.span({ key:'up', className: 'rdtBtn', onMouseDown: this.onStartClicking( 'increase', type ) }, '▲' ),
                DOM.div({ key:'c', className: 'rdtCount' }, value ),
                DOM.span({ key:'do', className: 'rdtBtn', onMouseDown: this.onStartClicking( 'decrease', type ) }, '▼' )
            ]);
        }
        return '';
    },
    render: function() {
        var me = this,
            counters = []
        ;
 
        this.state.counters.forEach( function(c){
            if( counters.length )
                counters.push( DOM.div( {key: 'sep' + counters.length, className: 'rdtCounterSeparator' }, ':' ));
            counters.push( me.renderCounter( c ) );
        });
 
 
        if (this.state.daypart !== false) {
            counters.push(DOM.div({ key: this.state.daypart, className: 'rdtDayPart'}, this.state.daypart ));
        }
 
        if( this.state.counters.length == 3 && this.props.timeFormat.indexOf('S') != -1 ){
            counters.push( DOM.div( {className: 'rdtCounterSeparator', key: 'sep5' }, ':' ));
            counters.push(
                DOM.div( {className: 'rdtCounter rdtMilli', key:'m'},
                    DOM.input({ value: this.state.milliseconds, type: 'text', onChange: this.updateMilli })
                    )
                );
        }
 
        return DOM.div( {className: 'rdtTime'},
            DOM.table( {}, [
                this.renderHeader(),
                DOM.tbody({key: 'b'}, DOM.tr({}, DOM.td({},
                    DOM.div({ className: 'rdtCounters' }, counters )
                )))
            ])
        );
    },
    componentWillMount: function() {
        var me = this;
        ['hours', 'minutes', 'seconds', 'milliseconds'].forEach(function(type) {
            assign(me.settings[type], me.props[type]);
        });
    },
    componentWillReceiveProps: function( nextProps, nextState ){
        this.setState( this.calculateState( nextProps ) );
    },
    updateMilli: function( e ){
        var milli = parseInt( e.target.value );
        if( milli == e.target.value && milli >= 0 && milli < 1000 ){
            this.props.setTime( 'milliseconds', milli );
            this.setState({ milliseconds: milli });
        }
    },
    renderHeader: function(){
        if( !this.props.dateFormat )
            return null;
 
        var date = this.props.selectedDate || this.props.viewDate;
        return DOM.thead({ key: 'h'}, DOM.tr({},
            DOM.th( {className: 'rdtSwitch', colSpan: 4, onClick: this.props.showView('days')}, date.format( this.props.dateFormat ) )
        ));
    },
    onStartClicking: function( action, type ){
        var me = this,
            update = {},
            value = this.state[ type ]
        ;
 
 
        return function(){
            var update = {};
            update[ type ] = me[ action ]( type );
            me.setState( update );
 
            me.timer = setTimeout( function(){
                me.increaseTimer = setInterval( function(){
                    update[ type ] = me[ action ]( type );
                    me.setState( update );
                },70);
            }, 500);
 
            me.mouseUpListener = function(){
                clearTimeout( me.timer );
                clearInterval( me.increaseTimer );
                me.props.setTime( type, me.state[ type ] );
                document.body.removeEventListener('mouseup', me.mouseUpListener);
            };
 
            document.body.addEventListener('mouseup', me.mouseUpListener);
        };
    },
    settings: {
        hours: {
            min: 0,
            max: 23,
            pad: 1,
            step: 1,
        },
        minutes: {
            min: 0,
            max: 59,
            pad: 2,
            step: 1,
        },
        seconds: {
            min: 0,
            max: 59,
            pad: 2,
            step: 1,
        },
        milliseconds: {
            min: 0,
            max: 999,
            pad: 3,
            step: 1,
        },
    },
    increase: function( type ){
        var value = parseInt(this.state[ type ]) + this.settings[ type ].step;
        if( value > this.settings[ type ].max )
            value = this.settings[ type ].min;
        return this.pad( type, value );
    },
    decrease: function( type ){
        var value = parseInt(this.state[ type ]) - this.settings[ type ].step;
        if( value < this.settings[ type ].min )
            value = this.settings[ type ].max;
        return this.pad( type, value );
    },
    pad: function( type, value ){
        var str = value + '';
        while( str.length < this.settings[ type ].pad )
            str = '0' + str;
        return str;
    }
});
 
module.exports = DateTimePickerTime;