1 import {Component, OnInit, Input, Output, ViewChild, EventEmitter} from '@angular/core';
2 import {NgbDateStruct} from '@ng-bootstrap/ng-bootstrap';
5 * RE: displaying locale dates in the input field:
6 * https://github.com/ng-bootstrap/ng-bootstrap/issues/754
7 * https://stackoverflow.com/questions/40664523/angular2-ngbdatepicker-how-to-format-date-in-inputfield
11 selector: 'eg-date-select',
12 templateUrl: './date-select.component.html',
13 styleUrls: ['date-select.component.css']
15 export class DateSelectComponent implements OnInit {
17 @Input() initialIso: string; // ISO string
18 @Input() initialYmd: string; // YYYY-MM-DD (uses local time zone)
19 @Input() initialDate: Date; // Date object
20 @Input() required: boolean;
21 @Input() fieldName: string;
23 @Input() disabled: boolean;
24 @Input() readOnly: boolean;
26 current: NgbDateStruct;
28 @Output() onChangeAsDate: EventEmitter<Date>;
29 @Output() onChangeAsIso: EventEmitter<string>;
30 @Output() onChangeAsYmd: EventEmitter<string>;
31 @Output() onCleared: EventEmitter<string>;
33 // convenience methods to access current selected date
34 currentAsYmd(): string {
35 if (this.current == null) { return null; }
36 if (!this.isValidDate(this.current)) { return null; }
37 return `${this.current.year}-${String(this.current.month).padStart(2, '0')}-${String(this.current.day).padStart(2, '0')}`;
39 currentAsIso(): string {
40 if (this.current == null) { return null; }
41 if (!this.isValidDate(this.current)) { return null; }
42 const ymd = `${this.current.year}-${String(this.current.month).padStart(2, '0')}-${String(this.current.day).padStart(2, '0')}`;
43 const date = this.localDateFromYmd(ymd);
44 const iso = date.toISOString();
47 currentAsDate(): Date {
48 if (this.current == null) { return null; }
49 if (!this.isValidDate(this.current)) { return null; }
50 const ymd = `${this.current.year}-${String(this.current.month).padStart(2, '0')}-${String(this.current.day).padStart(2, '0')}`;
51 const date = this.localDateFromYmd(ymd);
56 this.onChangeAsDate = new EventEmitter<Date>();
57 this.onChangeAsIso = new EventEmitter<string>();
58 this.onChangeAsYmd = new EventEmitter<string>();
59 this.onCleared = new EventEmitter<string>();
64 if (this.initialYmd) {
65 this.initialDate = this.localDateFromYmd(this.initialYmd);
67 } else if (this.initialIso) {
68 this.initialDate = new Date(this.initialIso);
71 if (this.initialDate) {
73 year: this.initialDate.getFullYear(),
74 month: this.initialDate.getMonth() + 1,
75 day: this.initialDate.getDate()
80 isValidDate(dt: NgbDateStruct): dt is NgbDateStruct {
81 return (<NgbDateStruct>dt).year !== undefined;
85 if (this.current === null) {
86 this.onCleared.emit('cleared');
87 } else if (this.isValidDate(this.current)) {
88 this.onDateSelect(this.current);
90 // ignoring invalid input for now
94 const ymd = `${evt.year}-${String(evt.month).padStart(2, '0')}-${String(evt.day).padStart(2, '0')}`;
95 const date = this.localDateFromYmd(ymd);
96 const iso = date.toISOString();
97 this.onChangeAsDate.emit(date);
98 this.onChangeAsYmd.emit(ymd);
99 this.onChangeAsIso.emit(iso);
102 // Create a date in the local time zone with selected YMD values.
103 // TODO: Consider moving this to a date service...
104 localDateFromYmd(ymd: string): Date {
105 const parts = ymd.split('-');
107 Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]));