add: dateSelector
This commit is contained in:
153
lib/ui/date.js
Normal file
153
lib/ui/date.js
Normal file
@ -0,0 +1,153 @@
|
||||
import { createElement } from "../functions";
|
||||
|
||||
export function createDateInput(min, max) {
|
||||
const date = createElement('input', 'ui-date-cell');
|
||||
date.required = true;
|
||||
date.type = 'date';
|
||||
if (min != null) {
|
||||
date.min = min;
|
||||
}
|
||||
if (max != null) {
|
||||
date.max = max;
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
function toDateValue(dt) {
|
||||
if (isNaN(dt)) {
|
||||
return '';
|
||||
}
|
||||
const month = String(dt.getMonth() + 1).padStart(2, '0');
|
||||
const date = String(dt.getDate()).padStart(2, '0');
|
||||
return `${dt.getFullYear()}-${month}-${date}`;
|
||||
}
|
||||
|
||||
function resolveDate(s) {
|
||||
if (s instanceof Date) {
|
||||
return s;
|
||||
}
|
||||
const ticks = Number(s);
|
||||
if (!isNaN(ticks) && ticks > 0) {
|
||||
return new Date((ticks - 621355968e9) / 1e4);
|
||||
}
|
||||
return new Date(s);
|
||||
}
|
||||
|
||||
export function formatDate(date) {
|
||||
date = resolveDate(date);
|
||||
if (date instanceof Date && !isNaN(date)) {
|
||||
return `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
export function setDateValue(element, val) {
|
||||
if (element.tagName === 'INPUT') {
|
||||
if (val === '') {
|
||||
element.value = '';
|
||||
} else if (isNaN(val)) {
|
||||
if (/^\d{4}-\d{2}-\d{2}$/.test(val)) {
|
||||
element.value = val;
|
||||
} else if (/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(val)) {
|
||||
element.value = toDateValue(new Date(val));
|
||||
} else {
|
||||
element.value = '';
|
||||
}
|
||||
} else {
|
||||
if (!(val instanceof Date)) {
|
||||
val = new Date((val - 621355968e9) / 1e4);
|
||||
}
|
||||
element.value = toDateValue(val);
|
||||
}
|
||||
} else {
|
||||
element.innerText = formatDate(val);
|
||||
}
|
||||
}
|
||||
|
||||
export function getDateValue(element, formatter) {
|
||||
const date = element?.valueAsDate;
|
||||
if (date instanceof Date && !isNaN(date)) {
|
||||
const year = date.getFullYear();
|
||||
if (year < 1900 || year > 9999) {
|
||||
return '';
|
||||
}
|
||||
if (typeof formatter === 'function') {
|
||||
return formatter(date);
|
||||
}
|
||||
return String(date.getTime() * 1e4 + 621355968e9);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
export class DateSelector {
|
||||
_var = {
|
||||
parent: null,
|
||||
options: null
|
||||
};
|
||||
|
||||
onDateChanged;
|
||||
|
||||
constructor(opts) {
|
||||
opts ??= {};
|
||||
if (typeof opts.parent === 'string') {
|
||||
opts.parent = document.querySelector(opts.parent);
|
||||
}
|
||||
if (!(opts.parent instanceof HTMLElement)) {
|
||||
throw new Error('no specified parent.');
|
||||
}
|
||||
this._var.options = opts;
|
||||
this._var.parent = opts.parent;
|
||||
|
||||
const el = createDateInput(opts.minDate, opts.maxDate);
|
||||
el.addEventListener('blur', e => {
|
||||
const date = this._getDate(e.target.valueAsDate);
|
||||
if (date == null) {
|
||||
e.target.value = '';
|
||||
}
|
||||
if (typeof this.onDateChanged === 'function') {
|
||||
this.onDateChanged(date);
|
||||
}
|
||||
});
|
||||
this._var.el = el;
|
||||
parent.appendChild(el);
|
||||
}
|
||||
|
||||
get enabled() { return !this._var.el.disabled }
|
||||
set enabled(flag) {
|
||||
this._var.el.disabled = flag === false;
|
||||
}
|
||||
|
||||
get value() { return this._getDate(this._var.el.valueAsDate) }
|
||||
set value(val) {
|
||||
setDateValue(this._var.el, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} date
|
||||
*/
|
||||
set minDate(date) {
|
||||
this._var.el.min = date;
|
||||
this._var.options.minDate = date;
|
||||
}
|
||||
/**
|
||||
* @param {string} date
|
||||
*/
|
||||
set maxDate(date) {
|
||||
this._var.el.max = date;
|
||||
this._var.options.maxDate = date;
|
||||
}
|
||||
|
||||
_getDate(date) {
|
||||
if (date instanceof Date && !isNaN(date)) {
|
||||
const year = date.getFullYear();
|
||||
if (year < 1900 || year > 9999) {
|
||||
return null;
|
||||
}
|
||||
if (typeof this._var.options.valueFormatter === 'function') {
|
||||
return this._var.options.valueFormatter(date);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user