Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions com.woltlab.wcf/templates/shared_dateFormField.tpl
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<input {*
*}type="{if $field->supportsTime()}datetime{else}date{/if}" {*
*}type="{if $field->supportsTime()}datetime-local{else}date{/if}" {*
*}data-native-date-picker {*
*}id="{$field->getPrefixedId()}" {*
*}name="{$field->getPrefixedId()}" {*
*}value="{$field->getValue()}"{*
*}value="{$dateFormFieldValue}"{*
*}{if !$field->getFieldClasses()|empty} class="{implode from=$field->getFieldClasses() item='class' glue=' '}{$class}{/implode}"{/if}{*
*}{if $field->isAutofocused()} autofocus{/if}{*
*}{if $field->isRequired()} required{/if}{*
Expand Down
85 changes: 82 additions & 3 deletions ts/WoltLabSuite/Core/Date/Picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -634,20 +634,51 @@ function click(event: MouseEvent): void {
}

/**
* Validates given element or id if it represents an active date picker.
* Validates given element or id if it represents an active date picker
* or a native date input.
*/
function getElement(element: InputElementOrString): HTMLInputElement {
if (typeof element === "string") {
element = document.getElementById(element) as HTMLInputElement;
}

if (!(element instanceof HTMLInputElement) || !element.classList.contains("inputDatePicker") || !_data.has(element)) {
if (!(element instanceof HTMLInputElement)) {
throw new Error("Expected a valid date picker input element or id.");
}

if (isNativeInput(element)) {
return element;
}

if (!element.classList.contains("inputDatePicker") || !_data.has(element)) {
throw new Error("Expected a valid date picker input element or id.");
}

return element;
}

/**
* Returns true if the element is a native date input that is not
* enhanced by the date picker.
*/
function isNativeInput(element: HTMLInputElement): boolean {
return element.hasAttribute("data-native-date-picker");
}

/**
* Returns the value of the given date in the format of the native input.
*/
function formatNativeValue(element: HTMLInputElement, date: Date): string {
switch (element.type) {
case "datetime-local":
return DateUtil.format(date, "Y-m-d\\TH:i");
case "time":
return DateUtil.format(date, "H:i");
default:
return DateUtil.format(date, "Y-m-d");
}
}

const DatePicker = {
/**
* Initializes all date and datetime input fields.
Expand All @@ -661,7 +692,7 @@ const DatePicker = {
_firstDayOfWeek = parseInt(getPhrase("wcf.date.firstDayOfTheWeek"), 10);

wheneverSeen(
`input[type="date"]:not(.inputDatePicker), input[type="datetime"]:not(.inputDatePicker)`,
`input[type="date"]:not(.inputDatePicker, [data-native-date-picker]), input[type="datetime"]:not(.inputDatePicker, [data-native-date-picker])`,
(element: HTMLInputElement) => {
const now = new Date();
element.classList.add("inputDatePicker");
Expand Down Expand Up @@ -932,6 +963,23 @@ const DatePicker = {
getDate(element: InputElementOrString): Date | null {
element = getElement(element);

if (isNativeInput(element)) {
if (element.value === "") {
return null;
}

if (element.type === "time") {
const [hours, minutes] = element.value.split(":");
const date = new Date();
date.setHours(+hours, +minutes, 0, 0);

return date;
}

// Date-only strings are parsed as UTC, append the time to parse it as local time.
return new Date(element.type === "date" ? `${element.value}T00:00` : element.value);
}

const value = element.dataset.value || "";
if (value) {
return new Date(+value);
Expand All @@ -948,6 +996,13 @@ const DatePicker = {
*/
setDate(element: InputElementOrString, date: Date): void {
element = getElement(element);

if (isNativeInput(element)) {
element.value = formatNativeValue(element, date);

return;
}

const data = _data.get(element) as DatePickerData;

element.dataset.value = date.getTime().toString();
Expand Down Expand Up @@ -985,6 +1040,11 @@ const DatePicker = {
*/
getValue(element: InputElementOrString): string {
element = getElement(element);

if (isNativeInput(element)) {
return element.value;
}

const data = _data.get(element);

if (data) {
Expand All @@ -999,6 +1059,13 @@ const DatePicker = {
*/
clear(element: InputElementOrString): void {
element = getElement(element);

if (isNativeInput(element)) {
element.value = "";

return;
}

const data = _data.get(element) as DatePickerData;

element.removeAttribute("data-value");
Expand All @@ -1017,6 +1084,11 @@ const DatePicker = {
*/
destroy(element: InputElementOrString): void {
element = getElement(element);

if (isNativeInput(element)) {
return;
}

const data = _data.get(element) as DatePickerData;

const container = element.parentNode as HTMLElement;
Expand All @@ -1041,6 +1113,13 @@ const DatePicker = {
*/
setCloseCallback(element: InputElementOrString, callback: Callback): void {
element = getElement(element);

if (isNativeInput(element)) {
element.addEventListener("change", () => callback());

return;
}

_data.get(element)!.onClose = callback;
},
};
Expand Down
64 changes: 61 additions & 3 deletions wcfsetup/install/files/js/WoltLabSuite/Core/Date/Picker.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading