mirror of https://github.com/Squidex/squidex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
5.8 KiB
219 lines
5.8 KiB
/*
|
|
* Squidex Headless CMS
|
|
*
|
|
* @license
|
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
|
|
*/
|
|
|
|
import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core';
|
|
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
import * as moment from 'moment';
|
|
|
|
import {
|
|
StatefulControlComponent,
|
|
Types,
|
|
UIOptions
|
|
} from '@app/framework/internal';
|
|
|
|
declare module 'pikaday/pikaday';
|
|
|
|
import * as Pikaday from 'pikaday/pikaday';
|
|
|
|
export const SQX_DATE_TIME_EDITOR_CONTROL_VALUE_ACCESSOR: any = {
|
|
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateTimeEditorComponent), multi: true
|
|
};
|
|
|
|
const NO_EMIT = { emitEvent: false };
|
|
|
|
@Component({
|
|
selector: 'sqx-date-time-editor',
|
|
styleUrls: ['./date-time-editor.component.scss'],
|
|
templateUrl: './date-time-editor.component.html',
|
|
providers: [SQX_DATE_TIME_EDITOR_CONTROL_VALUE_ACCESSOR],
|
|
changeDetection: ChangeDetectionStrategy.OnPush
|
|
})
|
|
export class DateTimeEditorComponent extends StatefulControlComponent<{}, string | null> implements OnInit, AfterViewInit {
|
|
private picker: any;
|
|
private timeValue: moment.Moment | null = null;
|
|
private dateValue: moment.Moment | null = null;
|
|
private suppressEvents = false;
|
|
|
|
@Input()
|
|
public mode: 'DateTime' | 'Date';
|
|
|
|
@Input()
|
|
public enforceTime: boolean;
|
|
|
|
@Input()
|
|
public hideClear: boolean;
|
|
|
|
@ViewChild('dateInput', { static: false })
|
|
public dateInput: ElementRef;
|
|
|
|
public timeControl = new FormControl();
|
|
public dateControl = new FormControl();
|
|
|
|
public hideDateButtons: boolean;
|
|
|
|
public get showTime() {
|
|
return this.mode === 'DateTime';
|
|
}
|
|
|
|
public get hasValue() {
|
|
return !!this.dateValue;
|
|
}
|
|
|
|
constructor(changeDetector: ChangeDetectorRef, uiOptions: UIOptions) {
|
|
super(changeDetector, {});
|
|
|
|
this.hideDateButtons = !!uiOptions.get('hideDateButtons');
|
|
}
|
|
|
|
public ngOnInit() {
|
|
this.own(
|
|
this.timeControl.valueChanges.subscribe(value => {
|
|
if (!value || value.length === 0) {
|
|
this.timeValue = null;
|
|
} else {
|
|
this.timeValue = moment.utc(value, 'HH:mm:ss');
|
|
}
|
|
|
|
this.callChangeFormatted();
|
|
}));
|
|
|
|
this.own(
|
|
this.dateControl.valueChanges.subscribe(value => {
|
|
if (!value || value.length === 0) {
|
|
this.dateValue = null;
|
|
} else {
|
|
this.dateValue = moment.utc(value, 'YYYY-MM-DD');
|
|
}
|
|
|
|
this.callChangeFormatted();
|
|
}));
|
|
}
|
|
|
|
public writeValue(obj: any) {
|
|
if (Types.isString(obj) && obj.length > 0) {
|
|
const parsed = moment.parseZone(obj);
|
|
|
|
this.dateValue = parsed;
|
|
|
|
if (this.showTime) {
|
|
this.timeValue = parsed;
|
|
}
|
|
} else {
|
|
this.timeValue = null;
|
|
this.dateValue = null;
|
|
}
|
|
|
|
this.updateControls();
|
|
}
|
|
|
|
public setDisabledState(isDisabled: boolean): void {
|
|
super.setDisabledState(isDisabled);
|
|
|
|
if (isDisabled) {
|
|
this.dateControl.disable(NO_EMIT);
|
|
this.timeControl.disable(NO_EMIT);
|
|
} else {
|
|
this.dateControl.enable(NO_EMIT);
|
|
this.timeControl.enable(NO_EMIT);
|
|
}
|
|
}
|
|
|
|
public registerOnChange(fn: any) {
|
|
this.callChange = fn;
|
|
}
|
|
|
|
public registerOnTouched(fn: any) {
|
|
this.callTouched = fn;
|
|
}
|
|
|
|
public ngAfterViewInit() {
|
|
this.picker = new Pikaday({ field: this.dateInput.nativeElement, format: 'YYYY-MM-DD',
|
|
onSelect: () => {
|
|
if (this.suppressEvents) {
|
|
return;
|
|
}
|
|
this.dateValue = this.picker.getMoment();
|
|
|
|
this.callChangeFormatted();
|
|
this.callTouched();
|
|
}
|
|
});
|
|
|
|
this.updateControls();
|
|
}
|
|
|
|
public writeNow() {
|
|
this.writeValue(new Date().toUTCString());
|
|
|
|
this.updateControls();
|
|
this.callChangeFormatted();
|
|
this.callTouched();
|
|
|
|
return false;
|
|
}
|
|
|
|
public reset() {
|
|
this.timeControl.setValue(null, NO_EMIT);
|
|
this.dateControl.setValue(null, NO_EMIT);
|
|
|
|
this.dateValue = null;
|
|
|
|
this.callChange(null);
|
|
this.callTouched();
|
|
|
|
return false;
|
|
}
|
|
|
|
private callChangeFormatted() {
|
|
this.callChange(this.getValue());
|
|
}
|
|
|
|
private getValue(): string | null {
|
|
if (!this.dateValue || !this.dateValue.isValid()) {
|
|
return null;
|
|
}
|
|
|
|
if (this.timeValue && !this.timeValue.isValid()) {
|
|
return null;
|
|
}
|
|
|
|
let result = this.dateValue.format('YYYY-MM-DD');
|
|
|
|
if (this.showTime && this.timeValue) {
|
|
result += 'T';
|
|
result += this.timeValue.format('HH:mm:ss');
|
|
result += 'Z';
|
|
} else if (this.enforceTime) {
|
|
result += 'T00:00:00Z';
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private updateControls() {
|
|
this.suppressEvents = true;
|
|
|
|
if (this.timeValue && this.timeValue.isValid()) {
|
|
this.timeControl.setValue(this.timeValue.format('HH:mm:ss'), NO_EMIT);
|
|
} else {
|
|
this.timeControl.setValue(null, NO_EMIT);
|
|
}
|
|
|
|
if (this.dateValue && this.dateValue.isValid() && this.picker) {
|
|
const dateString = this.dateValue.format('YYYY-MM-DD');
|
|
const dateLocal = moment(dateString);
|
|
|
|
this.dateControl.setValue(dateString, NO_EMIT);
|
|
|
|
this.picker.setMoment(dateLocal);
|
|
} else {
|
|
this.dateControl.setValue(null, NO_EMIT);
|
|
}
|
|
|
|
this.suppressEvents = false;
|
|
}
|
|
}
|