This commit is contained in:
Juergen Kunz
2025-06-30 10:58:31 +00:00
parent 60a811fd18
commit 2c12c22666
3 changed files with 138 additions and 9 deletions

View File

@ -35,7 +35,7 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
public minuteIncrement: number = 1;
@property({ type: String })
public dateFormat: string = 'DD/MM/YYYY';
public dateFormat: string = 'YYYY-MM-DD';
@property({ type: String })
public minDate: string = '';
@ -50,7 +50,7 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
public weekStartsOn: 0 | 1 = 1; // Default to Monday
@property({ type: String })
public placeholder: string = 'Select date';
public placeholder: string = 'YYYY-MM-DD';
@state()
private isOpened: boolean = false;
@ -479,7 +479,8 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
?disabled=${this.disabled}
@click=${this.toggleCalendar}
@keydown=${this.handleKeydown}
readonly
@input=${this.handleManualInput}
@blur=${this.handleInputBlur}
style="padding-right: ${this.value ? '64px' : '40px'}"
/>
<div class="icon-container">
@ -641,10 +642,11 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const year = date.getFullYear().toString();
formatted = formatted.replace('DD', day);
formatted = formatted.replace('MM', month);
// Replace in correct order to avoid conflicts
formatted = formatted.replace('YYYY', year);
formatted = formatted.replace('YY', year.slice(-2));
formatted = formatted.replace('MM', month);
formatted = formatted.replace('DD', day);
// Time formatting if enabled
if (this.enableTime) {
@ -894,6 +896,117 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
this.changeSubject.next(this);
}
private handleManualInput(e: InputEvent): void {
const input = e.target as HTMLInputElement;
const inputValue = input.value.trim();
if (!inputValue) {
// Clear the value if input is empty
this.value = '';
this.selectedDate = null;
return;
}
const parsedDate = this.parseManualDate(inputValue);
if (parsedDate && !isNaN(parsedDate.getTime())) {
// Update internal state without triggering re-render of input
this.value = parsedDate.toISOString();
this.selectedDate = parsedDate;
this.viewDate = new Date(parsedDate);
this.selectedHour = parsedDate.getHours();
this.selectedMinute = parsedDate.getMinutes();
this.changeSubject.next(this);
}
}
private handleInputBlur(e: FocusEvent): void {
const input = e.target as HTMLInputElement;
const inputValue = input.value.trim();
if (!inputValue) {
this.value = '';
this.selectedDate = null;
this.changeSubject.next(this);
return;
}
const parsedDate = this.parseManualDate(inputValue);
if (parsedDate && !isNaN(parsedDate.getTime())) {
this.value = parsedDate.toISOString();
this.selectedDate = parsedDate;
this.viewDate = new Date(parsedDate);
this.selectedHour = parsedDate.getHours();
this.selectedMinute = parsedDate.getMinutes();
this.changeSubject.next(this);
// Update the input with formatted date
input.value = this.formatDate(this.value);
} else {
// Revert to previous valid value on blur if parsing failed
input.value = this.formatDate(this.value);
}
}
private parseManualDate(input: string): Date | null {
if (!input) return null;
// Split date and time parts if present
const parts = input.split(' ');
let datePart = parts[0];
let timePart = parts[1] || '';
let parsedDate: Date | null = null;
// Try different date formats
// Format 1: YYYY-MM-DD (ISO-like)
const isoMatch = datePart.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/);
if (isoMatch) {
const [_, year, month, day] = isoMatch;
parsedDate = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
}
// Format 2: DD.MM.YYYY (European)
if (!parsedDate) {
const euMatch = datePart.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/);
if (euMatch) {
const [_, day, month, year] = euMatch;
parsedDate = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
}
}
// Format 3: MM/DD/YYYY (US)
if (!parsedDate) {
const usMatch = datePart.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
if (usMatch) {
const [_, month, day, year] = usMatch;
parsedDate = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
}
}
// If no date was parsed, return null
if (!parsedDate || isNaN(parsedDate.getTime())) {
return null;
}
// Parse time if present (HH:MM format)
if (timePart) {
const timeMatch = timePart.match(/^(\d{1,2}):(\d{2})$/);
if (timeMatch) {
const [_, hours, minutes] = timeMatch;
parsedDate.setHours(parseInt(hours));
parsedDate.setMinutes(parseInt(minutes));
}
} else if (!this.enableTime) {
// If time is not enabled and not provided, use current time
const now = new Date();
parsedDate.setHours(now.getHours());
parsedDate.setMinutes(now.getMinutes());
parsedDate.setSeconds(0);
parsedDate.setMilliseconds(0);
}
return parsedDate;
}
public getValue(): string {
return this.value;
}