Send separate events for blurring or entering outside change event

Currently, entering in the date field triggers submission before a date
could be entered. We need to separate these events

https://community.openproject.org/wp/45076
pull/11730/head
Oliver Günther 2 years ago
parent 5f81d8a773
commit 54c774202a
No known key found for this signature in database
GPG Key ID: A3A8BDAD7C0C552C
  1. 18
      frontend/src/app/shared/components/fields/edit/field-types/date-edit-field/date-edit-field.component.ts
  2. 8
      frontend/src/app/shared/components/op-date-picker/date-picker.directive.ts
  3. 3
      frontend/src/app/shared/components/op-date-picker/op-single-date-picker/op-single-date-picker.component.html
  4. 28
      frontend/src/app/shared/components/op-date-picker/op-single-date-picker/op-single-date-picker.component.ts

@ -39,6 +39,8 @@ import { TimezoneService } from 'core-app/core/datetime/timezone.service';
tabindex="-1" tabindex="-1"
(changed)="onValueSelected($event)" (changed)="onValueSelected($event)"
(canceled)="onCancel()" (canceled)="onCancel()"
(blurred)="submit($event)"
(enterPressed)="submit($event)"
[initialDate]="formatter(value)" [initialDate]="formatter(value)"
[required]="required" [required]="required"
[disabled]="inFlight" [disabled]="inFlight"
@ -52,27 +54,31 @@ export class DateEditFieldComponent extends EditFieldComponent implements OnInit
@InjectField() opModalService:OpModalService; @InjectField() opModalService:OpModalService;
ngOnInit() { ngOnInit():void {
super.ngOnInit(); super.ngOnInit();
} }
public onValueSelected(data:string) { public onValueSelected(data:string):void {
this.value = this.parser(data); this.value = this.parser(data);
this.handler.handleUserSubmit();
} }
public onCancel() { public submit(data:string):void {
this.onValueSelected(data);
void this.handler.handleUserSubmit();
}
public onCancel():void {
this.handler.handleUserCancel(); this.handler.handleUserCancel();
} }
public parser(data:any) { public parser(data:string):string|null {
if (moment(data, 'YYYY-MM-DD', true).isValid()) { if (moment(data, 'YYYY-MM-DD', true).isValid()) {
return data; return data;
} }
return null; return null;
} }
public formatter(data:any) { public formatter(data:string):string|null {
if (moment(data, 'YYYY-MM-DD', true).isValid()) { if (moment(data, 'YYYY-MM-DD', true).isValid()) {
const d = this.timezoneService.parseDate(data); const d = this.timezoneService.parseDate(data);
return this.timezoneService.formattedISODate(d); return this.timezoneService.formattedISODate(d);

@ -97,12 +97,16 @@ export abstract class AbstractDatePickerDirective extends UntilDestroyedMixin im
} }
closeOnOutsideClick(event:MouseEvent):void { closeOnOutsideClick(event:MouseEvent):void {
if (!(event.relatedTarget if (this.isOutsideClick(event)) {
&& this.datePickerInstance.datepickerInstance.calendarContainer.contains(event.relatedTarget as HTMLElement))) {
this.close(); this.close();
} }
} }
isOutsideClick(event:MouseEvent):boolean {
return (!(event.relatedTarget
&& this.datePickerInstance.datepickerInstance.calendarContainer.contains(event.relatedTarget as HTMLElement)));
}
close():void { close():void {
this.datePickerInstance.hide(); this.datePickerInstance.hide();
} }

@ -8,8 +8,9 @@
[required]="required" [required]="required"
[disabled]="disabled" [disabled]="disabled"
(click)="openOnClick()" (click)="openOnClick()"
(keydown.enter)="enterPressed.emit(dateValue)"
(keydown.escape)="close()" (keydown.escape)="close()"
(blur)="closeOnOutsideClick($event)"
(input)="onInputChange()" (input)="onInputChange()"
(blur)="onBlurred($event)"
type="text" type="text"
> >

@ -26,7 +26,12 @@
// See COPYRIGHT and LICENSE files for more details. // See COPYRIGHT and LICENSE files for more details.
//++ //++
import { Component, Input, Output } from '@angular/core'; import {
Component,
EventEmitter,
Input,
Output,
} from '@angular/core';
import { Instance } from 'flatpickr/dist/types/instance'; import { Instance } from 'flatpickr/dist/types/instance';
import { KeyCodes } from 'core-app/shared/helpers/keyCodes.enum'; import { KeyCodes } from 'core-app/shared/helpers/keyCodes.enum';
import { DatePicker } from 'core-app/shared/components/op-date-picker/datepicker'; import { DatePicker } from 'core-app/shared/components/op-date-picker/datepicker';
@ -42,16 +47,33 @@ import { componentDestroyed } from '@w11k/ngx-componentdestroyed';
export class OpSingleDatePickerComponent extends AbstractDatePickerDirective { export class OpSingleDatePickerComponent extends AbstractDatePickerDirective {
@Output() public changed = new DebouncedEventEmitter<string>(componentDestroyed(this)); @Output() public changed = new DebouncedEventEmitter<string>(componentDestroyed(this));
@Output() public blurred = new EventEmitter<string>();
@Output() public enterPressed = new EventEmitter<string>();
@Input() public initialDate = ''; @Input() public initialDate = '';
onInputChange():void { onInputChange():void {
if (this.inputIsValidDate()) { if (this.inputIsValidDate()) {
this.changed.emit(this.currentValue); this.changed.emit(this.currentValue);
} else {
this.changed.emit('');
} }
} }
onBlurred(event:MouseEvent):void {
if (this.isOutsideClick(event)) {
this.close();
this.blurred.emit(this.currentValue);
}
}
get dateValue():string {
if (this.inputIsValidDate()) {
return this.currentValue;
}
return '';
}
protected inputIsValidDate():boolean { protected inputIsValidDate():boolean {
return (/\d{4}-\d{2}-\d{2}/.exec(this.currentValue)) !== null; return (/\d{4}-\d{2}-\d{2}/.exec(this.currentValue)) !== null;
} }

Loading…
Cancel
Save