LP1831390: Fixing implementation of registerOnTouch
[Evergreen.git] / Open-ILS / src / eg2 / src / app / share / date-select / date-select.component.ts
index 6256290..66d363a 100644 (file)
@@ -1,5 +1,6 @@
-import {Component, OnInit, Input, Output, ViewChild, EventEmitter} from '@angular/core';
+import {Component, OnInit, Input, Output, ViewChild, EventEmitter, forwardRef} from '@angular/core';
 import {NgbDateStruct} from '@ng-bootstrap/ng-bootstrap';
 import {NgbDateStruct} from '@ng-bootstrap/ng-bootstrap';
+import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
 
 /**
  * RE: displaying locale dates in the input field:
 
 /**
  * RE: displaying locale dates in the input field:
@@ -9,9 +10,15 @@ import {NgbDateStruct} from '@ng-bootstrap/ng-bootstrap';
 
 @Component({
   selector: 'eg-date-select',
 
 @Component({
   selector: 'eg-date-select',
-  templateUrl: './date-select.component.html'
+  templateUrl: './date-select.component.html',
+  styleUrls: ['date-select.component.css'],
+  providers: [ {
+      provide: NG_VALUE_ACCESSOR,
+      useExisting: forwardRef(() => DateSelectComponent),
+      multi: true
+  } ]
 })
 })
-export class DateSelectComponent implements OnInit {
+export class DateSelectComponent implements OnInit, ControlValueAccessor {
 
     @Input() initialIso: string; // ISO string
     @Input() initialYmd: string; // YYYY-MM-DD (uses local time zone)
 
     @Input() initialIso: string; // ISO string
     @Input() initialYmd: string; // YYYY-MM-DD (uses local time zone)
@@ -19,22 +26,47 @@ export class DateSelectComponent implements OnInit {
     @Input() required: boolean;
     @Input() fieldName: string;
     @Input() domId = '';
     @Input() required: boolean;
     @Input() fieldName: string;
     @Input() domId = '';
-
-    _disabled: boolean;
-    @Input() set disabled(d: boolean) {
-        this._disabled = d;
-    }
+    @Input() disabled: boolean;
+    @Input() readOnly: boolean;
 
     current: NgbDateStruct;
 
     @Output() onChangeAsDate: EventEmitter<Date>;
     @Output() onChangeAsIso: EventEmitter<string>;
     @Output() onChangeAsYmd: EventEmitter<string>;
 
     current: NgbDateStruct;
 
     @Output() onChangeAsDate: EventEmitter<Date>;
     @Output() onChangeAsIso: EventEmitter<string>;
     @Output() onChangeAsYmd: EventEmitter<string>;
+    @Output() onCleared: EventEmitter<string>;
+
+    // convenience methods to access current selected date
+    currentAsYmd(): string {
+        if (this.current == null) { return null; }
+        if (!this.isValidDate(this.current)) { return null; }
+        return `${this.current.year}-${String(this.current.month).padStart(2, '0')}-${String(this.current.day).padStart(2, '0')}`;
+    }
+    currentAsIso(): string {
+        if (this.current == null) { return null; }
+        if (!this.isValidDate(this.current)) { return null; }
+        const ymd = `${this.current.year}-${String(this.current.month).padStart(2, '0')}-${String(this.current.day).padStart(2, '0')}`;
+        const date = this.localDateFromYmd(ymd);
+        const iso = date.toISOString();
+        return iso;
+    }
+    currentAsDate(): Date {
+        if (this.current == null) { return null; }
+        if (!this.isValidDate(this.current)) { return null; }
+        const ymd = `${this.current.year}-${String(this.current.month).padStart(2, '0')}-${String(this.current.day).padStart(2, '0')}`;
+        const date = this.localDateFromYmd(ymd);
+        return date;
+    }
+
+    // Stub functions required by ControlValueAccessor
+    propagateChange = (_: any) => {};
+    propagateTouch = () => {};
 
     constructor() {
         this.onChangeAsDate = new EventEmitter<Date>();
         this.onChangeAsIso = new EventEmitter<string>();
         this.onChangeAsYmd = new EventEmitter<string>();
 
     constructor() {
         this.onChangeAsDate = new EventEmitter<Date>();
         this.onChangeAsIso = new EventEmitter<string>();
         this.onChangeAsYmd = new EventEmitter<string>();
+        this.onCleared = new EventEmitter<string>();
     }
 
     ngOnInit() {
     }
 
     ngOnInit() {
@@ -47,21 +79,31 @@ export class DateSelectComponent implements OnInit {
         }
 
         if (this.initialDate) {
         }
 
         if (this.initialDate) {
-            this.current = {
-                year: this.initialDate.getFullYear(),
-                month: this.initialDate.getMonth() + 1,
-                day: this.initialDate.getDate()
-            };
+            this.writeValue(this.initialDate);
+        }
+    }
+
+    isValidDate(dt: NgbDateStruct): dt is NgbDateStruct {
+        return (<NgbDateStruct>dt).year !== undefined;
+    }
+
+    onDateEnter() {
+        if (this.current === null) {
+            this.onCleared.emit('cleared');
+        } else if (this.isValidDate(this.current)) {
+            this.onDateSelect(this.current);
         }
         }
+        // ignoring invalid input for now
     }
 
     onDateSelect(evt) {
     }
 
     onDateSelect(evt) {
-        const ymd = `${evt.year}-${evt.month}-${evt.day}`;
+        const ymd = `${evt.year}-${String(evt.month).padStart(2, '0')}-${String(evt.day).padStart(2, '0')}`;
         const date = this.localDateFromYmd(ymd);
         const iso = date.toISOString();
         this.onChangeAsDate.emit(date);
         this.onChangeAsYmd.emit(ymd);
         this.onChangeAsIso.emit(iso);
         const date = this.localDateFromYmd(ymd);
         const iso = date.toISOString();
         this.onChangeAsDate.emit(date);
         this.onChangeAsYmd.emit(ymd);
         this.onChangeAsIso.emit(iso);
+        this.propagateChange(date);
     }
 
     // Create a date in the local time zone with selected YMD values.
     }
 
     // Create a date in the local time zone with selected YMD values.
@@ -71,6 +113,32 @@ export class DateSelectComponent implements OnInit {
         return new Date(
             Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]));
     }
         return new Date(
             Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]));
     }
+
+    reset() {
+        this.current = {
+            year: null,
+            month: null,
+            day: null
+        };
+    }
+
+    writeValue(value: Date) {
+        if (value) {
+            this.current = {
+                year: value.getFullYear(),
+                month: value.getMonth() + 1,
+                day: value.getDate()
+            };
+        }
+    }
+
+    registerOnChange(fn) {
+        this.propagateChange = fn;
+    }
+
+    registerOnTouched(fn) {
+        this.propagateTouch = fn;
+    }
 }
 
 
 }