@Component({
selector: 'eg-date-select-native',
templateUrl: './date-select-native.component.html',
+ styleUrls: ['./date-select-native.component.css'],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DateSelectNativeComponent),
@Input() disabled = false; // Also works for readOnly
@Input() min = ''; // YYYY-MM-DD
@Input() max = ''; // YYYY-MM-DD
+ @Input() noFuture = false; // sets max to now
+ @Input() noPast = false; // sets min to now
@Input() domId = 'eg-date-select-native-' + DateSelectNativeComponent.domAutoId++;
// Emits YYYY-MM-DD on value change, null on empty.
- @Output() dateChange: EventEmitter<string> = new EventEmitter<string>();
+ @Output() valueChange: EventEmitter<string> = new EventEmitter<string>();
// Emits Date object
- @Output() dateChangeAsDate: EventEmitter<Date> = new EventEmitter<Date>();
+ @Output() valueChangeAsDate: EventEmitter<Date> = new EventEmitter<Date>();
// Emits ISO8601 date string
- @Output() dateChangeAsIso: EventEmitter<string> = new EventEmitter<string>();
+ @Output() valueChangeAsIso: EventEmitter<string> = new EventEmitter<string>();
// Stub functions required by ControlValueAccessor
propagateChange = (_: any) => {};
constructor() { }
- ngOnInit() { }
+ ngOnInit() {
+ if (this.noFuture) {
+ this.max = DateUtil.localYmdFromDate();
+ }
+
+ if (this.noPast) {
+ this.min = DateUtil.localYmdFromDate();
+ }
+ }
input(): HTMLInputElement {
return document.getElementById(this.domId) as HTMLInputElement;
}
+ invalid(): boolean {
+ if (!this.input()) { return false; }
+
+ let value = this.input().value;
+
+ if (this.required && !value) { return true; }
+
+ // <input type="date"/> will prevent selection of out-of-bounds
+ // dates, but it does not prevent the user from manually
+ // entering such a date.
+ const nowYmd = DateUtil.localYmdFromDate();
+
+ if (this.noFuture && value > nowYmd) { return true; }
+
+ if (this.noPast && value < nowYmd) { return true; }
+
+ return false;
+ }
+
inputChange(evt: Event) {
const value = this.input().value;
this.propagateChange(value);
if (!value) {
- this.dateChange.emit(null);
- this.dateChangeAsDate.emit(null);
- this.dateChangeAsIso.emit(null);
+
+ this.valueChange.emit(null);
+ this.valueChangeAsDate.emit(null);
+ this.valueChangeAsIso.emit(null);
} else {
let date = DateUtil.localDateFromYmd(value);
- this.dateChange.emit(value);
- this.dateChangeAsDate.emit(date);
- this.dateChangeAsIso.emit(date.toISOString());
+ this.valueChange.emit(value);
+ this.valueChangeAsDate.emit(date);
+ this.valueChangeAsIso.emit(date.toISOString());
}
}
* Required valid fields are left-border styled in green-ish.
* Invalid fields are left-border styled in red-ish.
*/
-.form-validated .ng-valid[required]:not(eg-combobox):not(eg-date-select),
+.form-validated .ng-valid[required]:not(eg-combobox):not(eg-date-select):not(eg-date-select-native),
.form-validated .ng-valid.required, input[formcontrolname].ng-valid {
border-left: 5px solid #78FA89;
}
-.form-validated .ng-invalid:not(form):not(eg-combobox):not(eg-date-select),
+.form-validated .ng-invalid:not(form):not(eg-combobox):not(eg-date-select):not(eg-date-select-native),
input[formcontrolname].ng-invalid {
border-left: 5px solid #FA787E;
}