@@ -5,6 +5,7 @@ var assign = require('object-assign'),
5
5
createClass = require ( 'create-react-class' ) ,
6
6
moment = require ( 'moment' ) ,
7
7
React = require ( 'react' ) ,
8
+ defaultMaskComponent = require ( 'react-bootstrap-maskedinput' ) . default ,
8
9
CalendarContainer = require ( './src/CalendarContainer' ) ,
9
10
onClickOutside = require ( 'react-onclickoutside' ) . default
10
11
;
@@ -33,18 +34,29 @@ var Datetime = createClass({
33
34
utc : TYPES . bool ,
34
35
displayTimeZone : TYPES . string ,
35
36
input : TYPES . bool ,
37
+ mask : TYPES . object ,
36
38
// dateFormat: TYPES.string | TYPES.bool,
37
39
// timeFormat: TYPES.string | TYPES.bool,
38
40
inputProps : TYPES . object ,
41
+ disableOnBlurInputOnOpen : TYPES . bool ,
39
42
timeConstraints : TYPES . object ,
40
43
viewMode : TYPES . oneOf ( [ viewModes . YEARS , viewModes . MONTHS , viewModes . DAYS , viewModes . TIME ] ) ,
41
44
isValidDate : TYPES . func ,
45
+ isValidUnix : TYPES . func ,
42
46
open : TYPES . bool ,
43
47
strictParsing : TYPES . bool ,
44
48
closeOnSelect : TYPES . bool ,
45
49
closeOnTab : TYPES . bool
46
50
} ,
47
51
52
+ isUnfilled : function ( value ) {
53
+ return typeof value === 'string' && value . split ( '' ) . find ( function ( char ) {
54
+ return char === '_' ;
55
+ } ) ;
56
+ } ,
57
+ isWithMask : function ( ) {
58
+ return this . props . mask && this . props . mask . maskedProps ;
59
+ } ,
48
60
getInitialState : function ( ) {
49
61
this . checkTZ ( this . props ) ;
50
62
@@ -59,6 +71,39 @@ var Datetime = createClass({
59
71
return state ;
60
72
} ,
61
73
74
+ renderPagination : function ( props ) {
75
+ var type = props . type , renderRange = props . renderRange ,
76
+ params = props . params || { } ;
77
+
78
+ var isValidUnix = this . props . isValidUnix ;
79
+ var viewDate = params . viewDate || this . state . viewDate ;
80
+ var validatePagination = this . props . validatePagination ;
81
+ var addValue = { } , subtractValue = { } ;
82
+
83
+ Object . defineProperty ( addValue , type , {
84
+ value : viewDate [ type ] ( ) ,
85
+ enumerable : true ,
86
+ } ) ;
87
+ Object . defineProperty ( subtractValue , type , {
88
+ value : viewDate [ type ] ( ) ,
89
+ enumerable : true ,
90
+ } ) ;
91
+
92
+ var nextDatesTab = viewDate . clone ( ) . startOf ( type ) . add ( params . add || renderRange , type ) ;
93
+ var prevDatesTab = viewDate . clone ( ) . endOf ( type ) . startOf ( 'days' ) . subtract ( params . subtract || renderRange , type ) ;
94
+ var nextDate = true ;
95
+ var prevDate = true ;
96
+
97
+ if ( ( typeof isValidUnix === 'function' ) && validatePagination ) {
98
+ nextDate = isValidUnix ( nextDatesTab ) ;
99
+ prevDate = isValidUnix ( prevDatesTab ) ;
100
+ }
101
+ return [
102
+ React . createElement ( 'th' , { key : 'prev' , className : 'rdtPrev' + ( prevDate ? '' : ' disabled' ) , onClick : prevDate ? this . subtractTime ( renderRange , type ) : null } , React . createElement ( 'span' , { } , '‹' ) ) ,
103
+ React . createElement ( 'th' , { key : 'next' , className : 'rdtNext' + ( nextDate ? '' : ' disabled' ) , onClick : nextDate ? this . addTime ( renderRange , type ) : null } , React . createElement ( 'span' , { } , '›' ) )
104
+ ] ;
105
+ } ,
106
+
62
107
parseDate : function ( date , formats ) {
63
108
var parsedDate ;
64
109
@@ -76,11 +121,19 @@ var Datetime = createClass({
76
121
getStateFromProps : function ( props ) {
77
122
var formats = this . getFormats ( props ) ,
78
123
date = props . value || props . defaultValue ,
124
+ isValidUnix = props . isValidUnix ,
125
+ validatePagination = props . validatePagination ,
79
126
selectedDate , viewDate , updateOn , inputValue
80
127
;
81
128
82
129
selectedDate = this . parseDate ( date , formats ) ;
83
130
131
+ if ( ( typeof isValidUnix === 'function' ) && validatePagination ) {
132
+ if ( selectedDate && ! isValidUnix ( selectedDate ) ) {
133
+ selectedDate = null ;
134
+ }
135
+ }
136
+
84
137
viewDate = this . parseDate ( props . viewDate , formats ) ;
85
138
86
139
viewDate = selectedDate ?
@@ -152,7 +205,13 @@ var Datetime = createClass({
152
205
153
206
if ( nextProps . value !== this . props . value ||
154
207
formats . datetime !== this . getFormats ( this . props ) . datetime ) {
155
- updatedState = this . getStateFromProps ( nextProps ) ;
208
+ if ( this . isWithMask ( ) ) {
209
+ if ( ! this . isUnfilled ( ) ) {
210
+ updatedState = this . getStateFromProps ( nextProps ) ;
211
+ }
212
+ } else {
213
+ updatedState = this . getStateFromProps ( nextProps ) ;
214
+ }
156
215
}
157
216
158
217
if ( updatedState . open === undefined ) {
@@ -216,20 +275,32 @@ var Datetime = createClass({
216
275
} ,
217
276
218
277
onInputChange : function ( e ) {
219
- var value = e . target === null ? e : e . target . value ,
220
- localMoment = this . localMoment ( value , this . state . inputFormat ) ,
221
- update = { inputValue : value }
222
- ;
278
+ var value = e . target === null ? e : e . target . value ;
279
+ var withMask = this . isWithMask ( ) ;
280
+
281
+ if ( withMask ) {
282
+ // to be determined if it needed or not
283
+ // if (!value) {
284
+ // return;
285
+ // }
286
+ if ( this . isUnfilled ( value ) ) {
287
+ return this . props . onChange ( value ) ;
288
+ }
289
+ }
223
290
224
- if ( localMoment . isValid ( ) && ! this . props . value ) {
291
+ var localMoment = this . localMoment ( value , this . state . inputFormat ) ,
292
+ update = { inputValue : value } ;
293
+
294
+ if ( localMoment . isValid ( ) && ! this . props . value ) {
225
295
update . selectedDate = localMoment ;
226
296
update . viewDate = localMoment . clone ( ) . startOf ( 'month' ) ;
227
297
} else {
228
298
update . selectedDate = null ;
229
299
}
230
300
231
301
return this . setState ( update , function ( ) {
232
- return this . props . onChange ( localMoment . isValid ( ) ? localMoment : this . state . inputValue ) ;
302
+ var editedValue = withMask ? value : this . state . inputValue ;
303
+ return this . props . onChange ( localMoment . isValid ( ) ? localMoment : editedValue ) ;
233
304
} ) ;
234
305
} ,
235
306
@@ -239,6 +310,16 @@ var Datetime = createClass({
239
310
}
240
311
} ,
241
312
313
+ onInputBlur : function ( ) {
314
+ var me = this ;
315
+ return function ( e ) {
316
+ if ( me . props . disableInputOnBlurOnOpen && me . state . open ) {
317
+ return ;
318
+ }
319
+ return typeof me . props . inputProps . onBlur === 'function' && me . props . inputProps . onBlur ( e ) ;
320
+ } ;
321
+ } ,
322
+
242
323
showView : function ( view ) {
243
324
var me = this ;
244
325
return function ( ) {
@@ -369,6 +450,7 @@ var Datetime = createClass({
369
450
370
451
openCalendar : function ( e ) {
371
452
if ( ! this . state . open ) {
453
+ e . persist ( ) ;
372
454
this . setState ( { open : true } , function ( ) {
373
455
this . props . onFocus ( e ) ;
374
456
} ) ;
@@ -416,9 +498,9 @@ var Datetime = createClass({
416
498
} ,
417
499
418
500
componentProps : {
419
- fromProps : [ 'value' , 'isValidDate' , 'renderDay' , 'renderMonth' , 'renderYear' , 'timeConstraints' ] ,
501
+ fromProps : [ 'value' , 'isValidDate' , 'isValidUnix' , ' renderDay', 'renderMonth' , 'renderYear' , 'timeConstraints' , 'validatePagination '] ,
420
502
fromState : [ 'viewDate' , 'selectedDate' , 'updateOn' ] ,
421
- fromThis : [ 'setDate' , 'setTime' , 'showView' , 'addTime' , 'subtractTime' , 'updateSelectedDate' , 'localMoment' , 'handleClickOutside' ]
503
+ fromThis : [ 'setDate' , 'setTime' , 'showView' , 'addTime' , 'subtractTime' , 'updateSelectedDate' , 'localMoment' , 'handleClickOutside' , 'renderPagination' ]
422
504
} ,
423
505
424
506
getComponentProps : function ( ) {
@@ -483,6 +565,14 @@ var Datetime = createClass({
483
565
484
566
if ( this . props . renderInput ) {
485
567
children = [ React . createElement ( 'div' , { key : 'i' } , this . props . renderInput ( finalInputProps , this . openCalendar , this . closeCalendar ) ) ] ;
568
+ } else if ( this . isWithMask ( ) ) {
569
+ children = [
570
+ React . createElement ( this . props . mask . maskComponent || defaultMaskComponent , assign (
571
+ this . props . mask . maskedProps ,
572
+ finalInputProps ,
573
+ { key : 'i' , onBlur : this . onInputBlur ( ) }
574
+ )
575
+ ) ] ;
486
576
} else {
487
577
children = [ React . createElement ( 'input' , assign ( { key : 'i' } , finalInputProps ) ) ] ;
488
578
}
0 commit comments