3
3
Input , OnChanges , OnInit , Optional , Output ,
4
4
SimpleChanges , SkipSelf , ViewContainerRef
5
5
} from '@angular/core' ;
6
- import { AbstractControl , ControlContainer , FormGroup , FormGroupDirective } from '@angular/forms' ;
7
- import { NguiDatetimePickerComponent } from './datetime-picker.component' ;
8
- import { NguiDatetime } from './datetime' ;
6
+ import { AbstractControl , ControlContainer , FormGroup , FormGroupDirective } from '@angular/forms' ;
7
+ import { NguiDatetimePickerComponent } from './datetime-picker.component' ;
8
+ import { NguiDatetime } from './datetime' ;
9
9
10
10
declare var moment : any ;
11
11
@@ -29,36 +29,36 @@ function isNaN(value) {
29
29
* If the given string is not a valid date, it defaults back to today
30
30
*/
31
31
@Directive ( {
32
- selector : '[ngui-datetime-picker]' ,
32
+ selector : '[ngui-datetime-picker]' ,
33
33
providers : [ NguiDatetime ]
34
34
} )
35
35
export class NguiDatetimePickerDirective implements OnInit , OnChanges {
36
- @Input ( 'date-format' ) dateFormat : string ;
37
- @Input ( 'parse-format' ) parseFormat : string ;
38
- @Input ( 'date-only' ) dateOnly : boolean ;
39
- @Input ( 'time-only' ) timeOnly : boolean ;
40
- @Input ( 'close-on-select' ) closeOnSelect : boolean = true ;
41
- @Input ( 'default-value' ) defaultValue : Date | string ;
42
- @Input ( 'minute-step' ) minuteStep : number ;
43
- @Input ( 'min-date' ) minDate : Date | string ;
44
- @Input ( 'max-date' ) maxDate : Date | string ;
45
- @Input ( 'min-hour' ) minHour : Date | number ;
46
- @Input ( 'max-hour' ) maxHour : Date | number ;
47
- @Input ( 'disabled-dates' ) disabledDates : Date [ ] ;
48
- @Input ( 'show-close-layer' ) showCloseLayer : boolean ;
36
+ @Input ( 'date-format' ) dateFormat : string ;
37
+ @Input ( 'parse-format' ) parseFormat : string ;
38
+ @Input ( 'date-only' ) dateOnly : boolean ;
39
+ @Input ( 'time-only' ) timeOnly : boolean ;
40
+ @Input ( 'close-on-select' ) closeOnSelect : boolean = true ;
41
+ @Input ( 'default-value' ) defaultValue : Date | string ;
42
+ @Input ( 'minute-step' ) minuteStep : number ;
43
+ @Input ( 'min-date' ) minDate : Date | string ;
44
+ @Input ( 'max-date' ) maxDate : Date | string ;
45
+ @Input ( 'min-hour' ) minHour : Date | number ;
46
+ @Input ( 'max-hour' ) maxHour : Date | number ;
47
+ @Input ( 'disabled-dates' ) disabledDates : Date [ ] ;
48
+ @Input ( 'show-close-layer' ) showCloseLayer : boolean ;
49
49
@Input ( 'show-today-shortcut' ) showTodayShortcut : boolean = false ;
50
50
@Input ( 'show-week-numbers' ) showWeekNumbers : boolean ;
51
51
@Input ( ) formControlName : string ;
52
- @Input ( 'is-draggable' ) isDraggable : boolean = true ;
52
+ @Input ( 'is-draggable' ) isDraggable : boolean = true ;
53
53
54
- @Input ( 'ngModel' ) ngModel : any ;
54
+ @Input ( 'ngModel' ) ngModel : any ;
55
55
@Output ( 'ngModelChange' ) ngModelChange = new EventEmitter ( ) ;
56
- @Output ( 'valueChanged' ) valueChanged$ = new EventEmitter ( ) ;
57
- @Output ( 'popupClosed' ) popupClosed$ = new EventEmitter ( ) ;
56
+ @Output ( 'valueChanged' ) valueChanged$ = new EventEmitter ( ) ;
57
+ @Output ( 'popupClosed' ) popupClosed$ = new EventEmitter ( ) ;
58
58
59
59
private el : HTMLInputElement ; /* input element */
60
60
private nguiDatetimePickerEl : HTMLElement ; /* dropdown element */
61
- private componentRef :ComponentRef < NguiDatetimePickerComponent > ; /* dropdown component reference */
61
+ private componentRef : ComponentRef < NguiDatetimePickerComponent > ; /* dropdown component reference */
62
62
private ctrl : AbstractControl ;
63
63
private sub : any ;
64
64
// private justShown: boolean;
@@ -67,9 +67,9 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
67
67
clickedDatetimePicker : boolean ;
68
68
userModifyingValue : boolean = false ;
69
69
70
- constructor (
71
- private resolver :ComponentFactoryResolver ,
72
- private viewContainerRef :ViewContainerRef ,
70
+ constructor (
71
+ private resolver : ComponentFactoryResolver ,
72
+ private viewContainerRef : ViewContainerRef ,
73
73
@Optional ( ) @Host ( ) @SkipSelf ( ) private parent : ControlContainer
74
74
) {
75
75
this . el = this . viewContainerRef . element . nativeElement ;
@@ -117,8 +117,8 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
117
117
}
118
118
}
119
119
120
- ngOnInit ( ) :void {
121
- if ( this . parent && this . formControlName ) {
120
+ ngOnInit ( ) : void {
121
+ if ( this . parent && this . formControlName ) {
122
122
if ( this . parent [ "form" ] ) {
123
123
this . ctrl = ( < FormGroup > this . parent [ "form" ] ) . get ( this . formControlName ) ;
124
124
} else if ( this . parent [ "path" ] ) {
@@ -138,19 +138,19 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
138
138
this . normalizeInput ( ) ;
139
139
140
140
//wrap this element with a <div> tag, so that we can position dynamic element correctly
141
- let wrapper = document . createElement ( "div" ) ;
142
- wrapper . className = 'ngui-datetime-picker-wrapper' ;
141
+ let wrapper = document . createElement ( "div" ) ;
142
+ wrapper . className = 'ngui-datetime-picker-wrapper' ;
143
143
this . el . parentElement . insertBefore ( wrapper , this . el . nextSibling ) ;
144
144
wrapper . appendChild ( this . el ) ;
145
145
146
146
if ( this . ngModel && this . ngModel . getTime ) { // if it is a Date object given, set dateValue and toString method
147
147
this . ngModel . toString = ( ) => NguiDatetime . formatDate ( this . ngModel , this . dateFormat , this . dateOnly ) ;
148
148
}
149
- setTimeout ( ( ) => { // after [(ngModel)] is applied
149
+ setTimeout ( ( ) => { // after [(ngModel)] is applied
150
150
if ( this . el . tagName === 'INPUT' ) {
151
151
this . inputElValueChanged ( this . el . value ) ; //set this.el.dateValue and reformat this.el.value
152
152
}
153
- if ( this . ctrl ) {
153
+ if ( this . ctrl ) {
154
154
this . ctrl . markAsPristine ( ) ;
155
155
}
156
156
} ) ;
@@ -160,7 +160,7 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
160
160
// if this element is not an input tag, move dropdown after input tag
161
161
// so that it displays correctly
162
162
this . inputEl = this . el . tagName === "INPUT" ?
163
- < HTMLInputElement > this . el : < HTMLInputElement > this . el . querySelector ( "input" ) ;
163
+ < HTMLInputElement > this . el : < HTMLInputElement > this . el . querySelector ( "input" ) ;
164
164
165
165
if ( this . inputEl ) {
166
166
this . inputEl . addEventListener ( 'focus' , this . showDatetimePicker ) ;
@@ -176,7 +176,7 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
176
176
177
177
ngOnChanges ( changes : SimpleChanges ) {
178
178
let date ;
179
- if ( changes && changes [ 'ngModel' ] ) {
179
+ if ( changes && changes [ 'ngModel' ] ) {
180
180
date = changes [ 'ngModel' ] . currentValue ;
181
181
182
182
if ( date && typeof date !== 'string' ) {
@@ -186,22 +186,28 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
186
186
} else if ( date && typeof date === 'string' ) {
187
187
/** if program assigns a string value, then format to date later */
188
188
if ( ! this . userModifyingValue ) {
189
- setTimeout ( ( ) => {
189
+ setTimeout ( ( ) => {
190
190
let dt = this . getDate ( date ) ;
191
191
dt . toString = ( ) => NguiDatetime . formatDate ( dt , this . dateFormat , this . dateOnly ) ;
192
192
this . ngModel = dt ;
193
- this . inputEl . value = '' + dt ;
193
+ this . inputEl . value = '' + dt ;
194
194
} )
195
+ } else {
196
+ let changeDate : any = new Date ( date ) ;
197
+ if ( changeDate . toString ( ) !== "Invalid Date" ) {
198
+ this . setInputElDateValue ( date ) ;
199
+ this . updateDatepicker ( ) ;
200
+ }
195
201
}
196
202
}
197
- }
203
+ }
198
204
this . userModifyingValue = false ;
199
205
}
200
206
201
207
updateDatepicker ( ) {
202
- if ( this . componentRef ) {
208
+ if ( this . componentRef ) {
203
209
let component = this . componentRef . instance ;
204
- component . defaultValue = < Date > this . el [ 'dateValue' ] ;
210
+ component . defaultValue = < Date > this . el [ 'dateValue' ] ;
205
211
}
206
212
}
207
213
@@ -214,13 +220,13 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
214
220
this . el [ 'dateValue' ] = null ;
215
221
}
216
222
217
- if ( this . ctrl ) {
223
+ if ( this . ctrl ) {
218
224
this . ctrl . markAsDirty ( ) ;
219
225
}
220
226
}
221
227
222
- ngOnDestroy ( ) :void {
223
- if ( this . sub ) {
228
+ ngOnDestroy ( ) : void {
229
+ if ( this . sub ) {
224
230
this . sub . unsubscribe ( ) ;
225
231
}
226
232
}
@@ -229,7 +235,7 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
229
235
inputElValueChanged = ( date : string | Date ) : void => {
230
236
this . setInputElDateValue ( date ) ;
231
237
this . el . value = date . toString ( ) ;
232
- if ( this . ctrl ) {
238
+ if ( this . ctrl ) {
233
239
this . ctrl . patchValue ( this . el . value ) ;
234
240
}
235
241
this . ngModel = this . el [ 'dateValue' ] ;
@@ -240,14 +246,14 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
240
246
} ;
241
247
242
248
//show datetimePicker element below the current element
243
- showDatetimePicker = ( event ?) : void => {
249
+ showDatetimePicker = ( event ?) : void => {
244
250
if ( this . componentRef ) { /* if already shown, do nothing */
245
251
return ;
246
252
}
247
253
248
254
let factory = this . resolver . resolveComponentFactory ( NguiDatetimePickerComponent ) ;
249
255
250
- this . componentRef = this . viewContainerRef . createComponent ( factory ) ;
256
+ this . componentRef = this . viewContainerRef . createComponent ( factory ) ;
251
257
this . nguiDatetimePickerEl = this . componentRef . location . nativeElement ;
252
258
this . nguiDatetimePickerEl . setAttribute ( 'tabindex' , '32767' ) ;
253
259
this . nguiDatetimePickerEl . setAttribute ( 'draggable' , String ( this . isDraggable ) ) ;
@@ -264,21 +270,21 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
264
270
this . nguiDatetimePickerEl . addEventListener ( 'blur' , ( event ) => {
265
271
this . hideDatetimePicker ( ) ;
266
272
} ) ;
267
- this . nguiDatetimePickerEl . addEventListener ( 'dragstart' , this . drag_start , false ) ;
268
- document . body . addEventListener ( 'dragover' , this . drag_over , false ) ;
269
- document . body . addEventListener ( 'drop' , this . drop , false ) ;
273
+ this . nguiDatetimePickerEl . addEventListener ( 'dragstart' , this . drag_start , false ) ;
274
+ document . body . addEventListener ( 'dragover' , this . drag_over , false ) ;
275
+ document . body . addEventListener ( 'drop' , this . drop , false ) ;
270
276
271
277
let component = this . componentRef . instance ;
272
- component . defaultValue = < Date > this . defaultValue || < Date > this . el [ 'dateValue' ] ;
273
- component . dateFormat = this . dateFormat ;
274
- component . dateOnly = this . dateOnly ;
275
- component . timeOnly = this . timeOnly ;
276
- component . minuteStep = this . minuteStep ;
277
- component . minDate = < Date > this . minDate ;
278
- component . maxDate = < Date > this . maxDate ;
279
- component . minHour = < number > this . minHour ;
280
- component . maxHour = < number > this . maxHour ;
281
- component . disabledDates = this . disabledDates ;
278
+ component . defaultValue = < Date > this . defaultValue || < Date > this . el [ 'dateValue' ] ;
279
+ component . dateFormat = this . dateFormat ;
280
+ component . dateOnly = this . dateOnly ;
281
+ component . timeOnly = this . timeOnly ;
282
+ component . minuteStep = this . minuteStep ;
283
+ component . minDate = < Date > this . minDate ;
284
+ component . maxDate = < Date > this . maxDate ;
285
+ component . minHour = < number > this . minHour ;
286
+ component . maxHour = < number > this . maxHour ;
287
+ component . disabledDates = this . disabledDates ;
282
288
component . showCloseButton = this . closeOnSelect === false ;
283
289
component . showCloseLayer = this . showCloseLayer ;
284
290
component . showTodayShortcut = this . showTodayShortcut ;
@@ -290,7 +296,7 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
290
296
component . closing$ . subscribe ( ( ) => {
291
297
this . hideDatetimePicker ( ) ;
292
298
} ) ;
293
-
299
+
294
300
//Hack not to fire tab keyup event
295
301
// this.justShown = true;
296
302
// setTimeout(() => this.justShown = false, 100);
@@ -321,26 +327,26 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
321
327
event && event . stopPropagation ( ) ;
322
328
} ;
323
329
324
- private elementIn ( el :Node , containerEl :Node ) :boolean {
330
+ private elementIn ( el : Node , containerEl : Node ) : boolean {
325
331
while ( el = el . parentNode ) {
326
332
if ( el === containerEl ) return true ;
327
333
}
328
334
return false ;
329
335
}
330
336
331
- private styleDatetimePicker ( ) {
337
+ private styleDatetimePicker ( ) {
332
338
// setting position, width, and height of auto complete dropdown
333
- let thisElBCR = this . el . getBoundingClientRect ( ) ;
339
+ let thisElBCR = this . el . getBoundingClientRect ( ) ;
334
340
// this.nguiDatetimePickerEl.style.minWidth = thisElBCR.width + 'px';
335
- this . nguiDatetimePickerEl . style . position = 'absolute' ;
336
- this . nguiDatetimePickerEl . style . zIndex = '1000' ;
337
- this . nguiDatetimePickerEl . style . left = '0' ;
341
+ this . nguiDatetimePickerEl . style . position = 'absolute' ;
342
+ this . nguiDatetimePickerEl . style . zIndex = '1000' ;
343
+ this . nguiDatetimePickerEl . style . left = '0' ;
338
344
this . nguiDatetimePickerEl . style . transition = 'height 0.3s ease-in' ;
339
345
340
346
this . nguiDatetimePickerEl . style . visibility = 'hidden' ;
341
347
342
348
setTimeout ( ( ) => {
343
- let thisElBcr = this . el . getBoundingClientRect ( ) ;
349
+ let thisElBcr = this . el . getBoundingClientRect ( ) ;
344
350
let nguiDatetimePickerElBcr = this . nguiDatetimePickerEl . getBoundingClientRect ( ) ;
345
351
346
352
if ( thisElBcr . bottom + nguiDatetimePickerElBcr . height > window . innerHeight ) {
@@ -355,38 +361,38 @@ export class NguiDatetimePickerDirective implements OnInit, OnChanges {
355
361
} ) ;
356
362
} ;
357
363
358
- private getDate = ( arg : any ) : Date => {
364
+ private getDate = ( arg : any ) : Date => {
359
365
let date : Date = < Date > arg ;
360
366
if ( typeof arg === 'string' ) {
361
- date = NguiDatetime . parseDate ( arg , this . parseFormat , this . dateFormat ) ;
367
+ date = NguiDatetime . parseDate ( arg , this . parseFormat , this . dateFormat ) ;
362
368
}
363
369
return date ;
364
370
}
365
371
366
372
private drag_start = ( event ) => {
367
- if ( document . activeElement . tagName == 'INPUT' ) {
373
+ if ( document . activeElement . tagName == 'INPUT' ) {
368
374
event . preventDefault ( ) ;
369
375
return false ; // block dragging
370
- }
376
+ }
371
377
var style = window . getComputedStyle ( event . target , null ) ;
372
378
event . dataTransfer . setData ( "text/plain" ,
373
- ( parseInt ( style . getPropertyValue ( "left" ) , 10 ) - event . clientX )
374
- + ','
375
- + ( parseInt ( style . getPropertyValue ( "top" ) , 10 ) - event . clientY )
379
+ ( parseInt ( style . getPropertyValue ( "left" ) , 10 ) - event . clientX )
380
+ + ','
381
+ + ( parseInt ( style . getPropertyValue ( "top" ) , 10 ) - event . clientY )
376
382
) ;
377
383
}
378
384
379
385
private drag_over ( event ) {
380
386
event . preventDefault ( ) ;
381
387
return false ;
382
- }
388
+ }
383
389
384
390
private drop = ( event ) => {
385
391
var offset = event . dataTransfer . getData ( "text/plain" ) . split ( ',' ) ;
386
- this . nguiDatetimePickerEl . style . left = ( event . clientX + parseInt ( offset [ 0 ] , 10 ) ) + 'px' ;
387
- this . nguiDatetimePickerEl . style . top = ( event . clientY + parseInt ( offset [ 1 ] , 10 ) ) + 'px' ;
392
+ this . nguiDatetimePickerEl . style . left = ( event . clientX + parseInt ( offset [ 0 ] , 10 ) ) + 'px' ;
393
+ this . nguiDatetimePickerEl . style . top = ( event . clientY + parseInt ( offset [ 1 ] , 10 ) ) + 'px' ;
388
394
this . nguiDatetimePickerEl . style . bottom = '' ;
389
395
event . preventDefault ( ) ;
390
396
return false ;
391
- }
397
+ }
392
398
}
0 commit comments