Fix opened card Date Format to be used at dates popups.

Thanks to xet7 !

Related #5971
This commit is contained in:
Lauri Ojansivu 2025-10-23 01:00:11 +03:00
parent 49a865cdbf
commit 7ca81285b1
4 changed files with 103 additions and 24 deletions

View file

@ -4,7 +4,7 @@ template(name="datepicker")
.fields .fields
.left .left
label(for="date") {{_ 'date'}} label(for="date") {{_ 'date'}}
input.js-date-field#date(type="date" name="date" value=showDate autofocus) input.js-date-field#date(type="text" name="date" value=showDate autofocus placeholder=dateFormat)
.right .right
label(for="time") {{_ 'time'}} label(for="time") {{_ 'time'}}
input.js-time-field#time(type="time" name="time" value=showTime) input.js-time-field#time(type="time" name="time" value=showTime)

View file

@ -3,6 +3,7 @@ import { TAPi18n } from '/imports/i18n';
import { import {
formatDateTime, formatDateTime,
formatDate, formatDate,
formatDateByUserPreference,
formatTime, formatTime,
getISOWeek, getISOWeek,
isValidDate, isValidDate,
@ -50,25 +51,35 @@ export class DatePicker extends BlazeComponent {
} }
onRendered() { onRendered() {
// Set initial values for native HTML inputs // Set initial values for text and time inputs
if (isValidDate(this.date.get())) { if (isValidDate(this.date.get())) {
const dateInput = this.find('#date'); const dateInput = this.find('#date');
const timeInput = this.find('#time'); const timeInput = this.find('#time');
if (dateInput) { if (dateInput) {
dateInput.value = formatDate(this.date.get()); // Use user's preferred format for text input
const currentUser = ReactiveCache.getCurrentUser();
const userFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD';
dateInput.value = formatDateByUserPreference(this.date.get(), userFormat, false);
} }
if (timeInput && !timeInput.value && this.defaultTime) { if (timeInput) {
if (!timeInput.value && this.defaultTime) {
const defaultDate = new Date(this.defaultTime); const defaultDate = new Date(this.defaultTime);
timeInput.value = formatTime(defaultDate); timeInput.value = formatTime(defaultDate);
} else if (timeInput && isValidDate(this.date.get())) { } else if (isValidDate(this.date.get())) {
timeInput.value = formatTime(this.date.get()); timeInput.value = formatTime(this.date.get());
} }
} }
} }
}
showDate() { showDate() {
if (isValidDate(this.date.get())) return formatDate(this.date.get()); if (isValidDate(this.date.get())) {
// Use user's preferred format for display, but HTML date input needs YYYY-MM-DD
const currentUser = ReactiveCache.getCurrentUser();
const userFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD';
return formatDateByUserPreference(this.date.get(), userFormat, false);
}
return ''; return '';
} }
showTime() { showTime() {
@ -76,7 +87,18 @@ export class DatePicker extends BlazeComponent {
return ''; return '';
} }
dateFormat() { dateFormat() {
return 'L'; const currentUser = ReactiveCache.getCurrentUser();
const userFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD';
// Convert format to localized placeholder
switch (userFormat) {
case 'DD-MM-YYYY':
return TAPi18n.__('date-format-dd-mm-yyyy') || 'PP-KK-VVVV';
case 'MM-DD-YYYY':
return TAPi18n.__('date-format-mm-dd-yyyy') || 'KK-PP-VVVV';
case 'YYYY-MM-DD':
default:
return TAPi18n.__('date-format-yyyy-mm-dd') || 'VVVV-KK-PP';
}
} }
timeFormat() { timeFormat() {
return 'LT'; return 'LT';
@ -86,11 +108,35 @@ export class DatePicker extends BlazeComponent {
return [ return [
{ {
'change .js-date-field'() { 'change .js-date-field'() {
// Native HTML date input validation // Text input date validation
const dateValue = this.find('#date').value; const dateInput = this.find('#date');
if (!dateInput) return;
const dateValue = dateInput.value;
if (dateValue) { if (dateValue) {
const dateObj = new Date(dateValue); // Try to parse different date formats
if (isValidDate(dateObj)) { const formats = [
'YYYY-MM-DD',
'DD-MM-YYYY',
'MM-DD-YYYY',
'DD/MM/YYYY',
'MM/DD/YYYY',
'DD.MM.YYYY',
'MM.DD.YYYY'
];
let parsedDate = null;
for (const format of formats) {
parsedDate = parseDate(dateValue, [format], true);
if (parsedDate) break;
}
// Fallback to native Date parsing
if (!parsedDate) {
parsedDate = new Date(dateValue);
}
if (isValidDate(parsedDate)) {
this.error.set(''); this.error.set('');
} else { } else {
this.error.set('invalid-date'); this.error.set('invalid-date');
@ -99,7 +145,10 @@ export class DatePicker extends BlazeComponent {
}, },
'change .js-time-field'() { 'change .js-time-field'() {
// Native HTML time input validation // Native HTML time input validation
const timeValue = this.find('#time').value; const timeInput = this.find('#time');
if (!timeInput) return;
const timeValue = timeInput.value;
if (timeValue) { if (timeValue) {
const timeObj = new Date(`1970-01-01T${timeValue}`); const timeObj = new Date(`1970-01-01T${timeValue}`);
if (isValidDate(timeObj)) { if (isValidDate(timeObj)) {
@ -121,14 +170,44 @@ export class DatePicker extends BlazeComponent {
return; return;
} }
const newCompleteDate = new Date(`${dateValue}T${timeValue}`); // Try to parse different date formats
const formats = [
'YYYY-MM-DD',
'DD-MM-YYYY',
'MM-DD-YYYY',
'DD/MM/YYYY',
'MM/DD/YYYY',
'DD.MM.YYYY',
'MM.DD.YYYY'
];
if (!isValidDate(newCompleteDate)) { let parsedDate = null;
for (const format of formats) {
parsedDate = parseDate(dateValue, [format], true);
if (parsedDate) break;
}
// Fallback to native Date parsing
if (!parsedDate) {
parsedDate = new Date(dateValue);
}
if (!isValidDate(parsedDate)) {
this.error.set('invalid'); this.error.set('invalid');
return; return;
} }
this._storeDate(newCompleteDate); // Combine with time
const timeObj = new Date(`1970-01-01T${timeValue}`);
if (!isValidDate(timeObj)) {
this.error.set('invalid-time');
return;
}
// Set the time on the parsed date
parsedDate.setHours(timeObj.getHours(), timeObj.getMinutes(), 0, 0);
this._storeDate(parsedDate);
Popup.back(); Popup.back();
}, },
'click .js-delete-date'(evt) { 'click .js-delete-date'(evt) {

View file

@ -357,9 +357,9 @@
"custom-fields": "Custom Fields", "custom-fields": "Custom Fields",
"date": "Date", "date": "Date",
"date-format": "Date Format", "date-format": "Date Format",
"date-format-yyyy-mm-dd": "YYYY-MM-DD HH:MM", "date-format-yyyy-mm-dd": "YYYY-MM-DD",
"date-format-dd-mm-yyyy": "DD-MM-YYYY HH:MM", "date-format-dd-mm-yyyy": "DD-MM-YYYY",
"date-format-mm-dd-yyyy": "MM-DD-YYYY HH:MM", "date-format-mm-dd-yyyy": "MM-DD-YYYY",
"decline": "Decline", "decline": "Decline",
"default-avatar": "Default avatar", "default-avatar": "Default avatar",
"delete": "Delete", "delete": "Delete",

View file

@ -357,9 +357,9 @@
"custom-fields": "Mukautetut kentät", "custom-fields": "Mukautetut kentät",
"date": "Päivämäärä", "date": "Päivämäärä",
"date-format": "Päivämäärämuoto", "date-format": "Päivämäärämuoto",
"date-format-yyyy-mm-dd": "VVVV-KK-PP HH:MM", "date-format-yyyy-mm-dd": "VVVV-KK-PP",
"date-format-dd-mm-yyyy": "PP-KK-VVVV HH:MM", "date-format-dd-mm-yyyy": "PP-KK-VVVV",
"date-format-mm-dd-yyyy": "PP-KK-VVVV HH:MM", "date-format-mm-dd-yyyy": "PP-KK-VVVV",
"decline": "Kieltäydy", "decline": "Kieltäydy",
"default-avatar": "Oletusprofiilikuva", "default-avatar": "Oletusprofiilikuva",
"delete": "Poista", "delete": "Poista",