176 lines
4.8 KiB
JavaScript
176 lines
4.8 KiB
JavaScript
import { createElement } from "../functions";
|
|
|
|
export function createDateInput(min, max, element) {
|
|
let date;
|
|
if (element instanceof HTMLInputElement) {
|
|
date = element;
|
|
date.classList.add('ui-date-cell');
|
|
} else {
|
|
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 ??= {};
|
|
this._var.options = opts;
|
|
}
|
|
|
|
create(element) {
|
|
const opts = this._var.options;
|
|
const el = createDateInput(opts.minDate, opts.maxDate, element);
|
|
if (element == null) {
|
|
el.disabled = opts.enabled === false;
|
|
}
|
|
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;
|
|
return el;
|
|
}
|
|
|
|
get element() { return this._var.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);
|
|
}
|
|
|
|
get minDate() { return this._var.el.min }
|
|
set minDate(date) {
|
|
this._var.el.min = date;
|
|
this._var.options.minDate = date;
|
|
}
|
|
|
|
get maxDate() { return this._var.el.max }
|
|
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;
|
|
}
|
|
|
|
static resolve(dom = document.body, trigger) {
|
|
const dates = dom.querySelectorAll('input[data-type="date"]');
|
|
for (let dat of dates) {
|
|
const val = dat.value;
|
|
const dateSelector = new DateSelector({
|
|
minDate: dat.getAttribute('data-min'),
|
|
maxDate: dat.getAttribute('data-max')
|
|
});
|
|
if (typeof trigger === 'function') {
|
|
dateSelector.onDateChanged = date => trigger.call(dateSelector, date);
|
|
}
|
|
dat.removeAttribute('data-type');
|
|
dat.removeAttribute('data-min');
|
|
dat.removeAttribute('data-max');
|
|
dateSelector.create(dat);
|
|
dateSelector.value = val;
|
|
}
|
|
}
|
|
} |